1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crossterm::event::{KeyCode, KeyEvent};
use tty_interface::{pos, Interface, Position};
use tty_text::Key;
use crate::{
dependency::{DependencyId, DependencyState, Evaluation},
style::drawer_style,
text::{DrawerContents, Segment, Text},
Form,
};
use super::{InputResult, Step};
pub struct KeyValueStep {
prompt: String,
pairs: Vec<(tty_text::Text, tty_text::Text)>,
active_pair: usize,
active_field: usize,
evaluation: Option<(DependencyId, Evaluation)>,
}
impl KeyValueStep {
pub fn new(prompt: &str) -> Self {
Self {
prompt: prompt.to_string(),
pairs: vec![(tty_text::Text::new(false), tty_text::Text::new(false))],
active_pair: 0,
active_field: 0,
evaluation: None,
}
}
pub fn set_evaluation(&mut self, evaluation: Evaluation) -> DependencyId {
let id = DependencyId::new();
self.evaluation = Some((id, evaluation));
id
}
}
impl Step for KeyValueStep {
fn initialize(&mut self, _dependency_state: &mut DependencyState, _index: usize) {}
fn render(
&self,
interface: &mut Interface,
_dependency_state: &DependencyState,
mut position: Position,
_is_focused: bool,
) -> u16 {
for (pair_index, (key, value)) in self.pairs.iter().enumerate() {
interface.set(position, &format!("{}: {}", key.value(), value.value()));
if pair_index == self.active_pair {
interface.set_cursor(Some(position));
}
position = pos!(position.x(), position.y() + 1);
}
self.pairs.len() as u16
}
fn update(
&mut self,
_dependency_state: &mut DependencyState,
input: KeyEvent,
) -> Option<InputResult> {
let text = if self.active_field == 0 {
&mut self.pairs[self.active_pair].0
} else {
&mut self.pairs[self.active_pair].1
};
match input.code {
KeyCode::Char(ch) => text.handle_input(Key::Char(ch)),
KeyCode::Backspace => text.handle_input(Key::Backspace),
KeyCode::Left => text.handle_input(Key::Left),
KeyCode::Right => text.handle_input(Key::Right),
_ => {}
};
None
}
fn help(&self) -> Segment {
Text::new_styled(self.prompt.to_string(), drawer_style()).as_segment()
}
fn drawer(&self) -> Option<DrawerContents> {
None
}
fn result(&self, _dependency_state: &DependencyState) -> String {
String::new() }
fn add_to(self, form: &mut Form) {
form.add_step(Box::new(self));
}
}