cli_prompts/prompts/options/
multioption_prompt.rs1use crate::{engine::CommandBuffer, prompts::options::Options, style::LabelStyle};
2
3pub trait MultiOptionPrompt<T> {
6
7 fn max_options_count(&self) -> u16;
9
10 fn options(&self) -> &Options<T>;
12
13 fn currently_selected_index(&self) -> usize;
15
16 fn draw_option(
18 &self,
19 option_index: usize,
20 option_label: &str,
21 is_selected: bool,
22 cmd_buffer: &mut impl CommandBuffer,
23 );
24
25 fn draw_header(&self, cmd_buffer: &mut impl CommandBuffer, is_submitted: bool);
27
28 fn draw_multioption(
31 &self,
32 label: &str,
33 is_submitted: bool,
34 label_style: &LabelStyle,
35 cmd_buffer: &mut impl CommandBuffer,
36 ) {
37 label_style.print(label, cmd_buffer);
38 self.draw_header(cmd_buffer, is_submitted);
39
40 if is_submitted {
41 return;
42 }
43
44 cmd_buffer.new_line();
45 let max_options_count: usize = self.max_options_count().into();
46 let mut start_from = self
47 .currently_selected_index()
48 .checked_sub(max_options_count / 2)
49 .unwrap_or(0);
50 start_from = start_from.min(
51 self.options()
52 .filtered_options()
53 .len()
54 .checked_sub(max_options_count)
55 .unwrap_or(0),
56 );
57
58 let displayed_option_indices = self
59 .options()
60 .filtered_options()
61 .iter()
62 .enumerate()
63 .skip(start_from)
64 .take(self.max_options_count().into());
65
66 for (selection_index, option_index) in displayed_option_indices {
67 let is_selected = selection_index == self.currently_selected_index();
68 let option_label = &self.options().transformed_options()[*option_index];
69
70 self.draw_option(*option_index, option_label, is_selected, cmd_buffer);
71 cmd_buffer.new_line();
72 }
73 }
74}