rust_kanban/ui/rendering/popup/
edit_specific_keybinding.rs

1use crate::{
2    app::{
3        state::{AppStatus, Focus, KeyBindingEnum},
4        App,
5    },
6    ui::{
7        rendering::{
8            common::{render_blank_styled_canvas, render_close_button, render_logs},
9            popup::EditSpecificKeybinding,
10            utils::{
11                centered_rect_with_percentage, check_if_active_and_get_style,
12                check_if_mouse_is_in_area,
13            },
14        },
15        Renderable,
16    },
17};
18use ratatui::{
19    layout::{Alignment, Constraint, Direction, Layout},
20    text::{Line, Span},
21    widgets::{Block, BorderType, Borders, Paragraph},
22    Frame,
23};
24
25impl Renderable for EditSpecificKeybinding {
26    fn render(rect: &mut Frame, app: &mut App, is_active: bool) {
27        let area = centered_rect_with_percentage(70, 70, rect.area());
28
29        let chunks = if app.config.enable_mouse_support {
30            Layout::default()
31                .direction(Direction::Vertical)
32                .constraints(
33                    [
34                        Constraint::Length(6),
35                        Constraint::Fill(1),
36                        Constraint::Length(4),
37                        Constraint::Length(3),
38                    ]
39                    .as_ref(),
40                )
41                .split(area)
42        } else {
43            Layout::default()
44                .direction(Direction::Vertical)
45                .constraints(
46                    [
47                        Constraint::Length(6),
48                        Constraint::Fill(1),
49                        Constraint::Length(4),
50                    ]
51                    .as_ref(),
52                )
53                .split(area)
54        };
55
56        let general_style = check_if_active_and_get_style(
57            is_active,
58            app.current_theme.inactive_text_style,
59            app.current_theme.general_style,
60        );
61        let keyboard_focus_style = check_if_active_and_get_style(
62            is_active,
63            app.current_theme.inactive_text_style,
64            app.current_theme.keyboard_focus_style,
65        );
66        let mouse_focus_style = check_if_active_and_get_style(
67            is_active,
68            app.current_theme.inactive_text_style,
69            app.current_theme.mouse_focus_style,
70        );
71        let help_text_style = check_if_active_and_get_style(
72            is_active,
73            app.current_theme.inactive_text_style,
74            app.current_theme.help_text_style,
75        );
76        let help_key_style = check_if_active_and_get_style(
77            is_active,
78            app.current_theme.inactive_text_style,
79            app.current_theme.help_key_style,
80        );
81
82        let edit_box_style =
83            if check_if_mouse_is_in_area(&app.state.current_mouse_coordinates, &chunks[1]) {
84                app.state.mouse_focus = Some(Focus::EditSpecificKeyBindingPopup);
85                app.state.set_focus(Focus::EditSpecificKeyBindingPopup);
86                mouse_focus_style
87            } else if app.state.app_status == AppStatus::KeyBindMode {
88                keyboard_focus_style
89            } else {
90                general_style
91            };
92
93        let key_id = app
94            .state
95            .app_table_states
96            .edit_keybindings
97            .selected()
98            .unwrap_or(0);
99        let current_bindings = app.config.keybindings.clone();
100        let mut key_list = vec![];
101
102        for (k, v) in current_bindings.iter() {
103            key_list.push((k, v));
104        }
105
106        if key_id > key_list.len() {
107            return;
108        }
109
110        key_list.sort_by(|a, b| a.0.to_string().cmp(&b.0.to_string()));
111
112        let paragraph_title = current_bindings
113            .keybinding_enum_to_action(key_list[key_id].0)
114            .to_string();
115        let value = key_list[key_id].1;
116        let mut key_value = String::new();
117        for v in value.iter() {
118            key_value.push_str(v.to_string().as_str());
119            if value.iter().last().unwrap() != v {
120                key_value.push_str(", ");
121            }
122        }
123        let user_input_key = app
124            .get_first_keybinding(KeyBindingEnum::TakeUserInput)
125            .unwrap_or("".to_string());
126        let accept_key = app
127            .get_first_keybinding(KeyBindingEnum::Accept)
128            .unwrap_or("".to_string());
129        let cancel_key = app
130            .get_first_keybinding(KeyBindingEnum::GoToPreviousViewOrCancel)
131            .unwrap_or("".to_string());
132        let stop_editing_key = app
133            .get_first_keybinding(KeyBindingEnum::StopUserInput)
134            .unwrap_or("".to_string());
135
136        let paragraph_text = vec![
137            Line::from(vec![
138                Span::styled("Current Value is '", help_text_style),
139                Span::styled(key_value, help_key_style),
140                Span::styled("'", help_text_style),
141            ]),
142            Line::from(String::from("")),
143            Line::from(vec![
144                Span::styled("Press ", help_text_style),
145                Span::styled(user_input_key, help_key_style),
146                Span::styled(" to edit, ", help_text_style),
147                Span::styled(cancel_key, help_key_style),
148                Span::styled(" to cancel, ", help_text_style),
149                Span::styled(stop_editing_key, help_key_style),
150                Span::styled(" to stop editing and ", help_text_style),
151                Span::styled(accept_key, help_key_style),
152                Span::styled(" to save when stopped editing", help_text_style),
153            ]),
154        ];
155        let config_item = Paragraph::new(paragraph_text)
156            .block(
157                Block::default()
158                    .title(paragraph_title)
159                    .borders(Borders::ALL)
160                    .border_type(BorderType::Rounded),
161            )
162            .wrap(ratatui::widgets::Wrap { trim: true });
163        let current_edited_keybinding = app.state.edited_keybinding.clone();
164        let mut current_edited_keybinding_string = String::new();
165        if let Some(current_edited_keybinding) = current_edited_keybinding {
166            for key in current_edited_keybinding {
167                current_edited_keybinding_string.push_str(&key.to_string());
168                current_edited_keybinding_string.push(' ');
169            }
170        }
171        let edit_item = Paragraph::new(current_edited_keybinding_string.clone())
172            .block(
173                Block::default()
174                    .title("Edit")
175                    .borders(Borders::ALL)
176                    .border_style(edit_box_style)
177                    .border_type(BorderType::Rounded),
178            )
179            .wrap(ratatui::widgets::Wrap { trim: true });
180
181        let clear_area = centered_rect_with_percentage(80, 80, rect.area());
182        let clear_area_border = Block::default()
183            .title("Edit Keybindings")
184            .borders(Borders::ALL)
185            .border_style(keyboard_focus_style)
186            .border_type(BorderType::Rounded);
187
188        render_blank_styled_canvas(rect, &app.current_theme, clear_area, is_active);
189        rect.render_widget(clear_area_border, clear_area);
190        rect.render_widget(config_item, chunks[0]);
191        rect.render_widget(edit_item, chunks[1]);
192        render_logs(app, false, chunks[2], rect, is_active);
193        if app.config.enable_mouse_support {
194            let submit_button_style =
195                if check_if_mouse_is_in_area(&app.state.current_mouse_coordinates, &chunks[3]) {
196                    app.state.mouse_focus = Some(Focus::SubmitButton);
197                    app.state.set_focus(Focus::SubmitButton);
198                    mouse_focus_style
199                } else if app.state.app_status == AppStatus::KeyBindMode {
200                    keyboard_focus_style
201                } else {
202                    general_style
203                };
204            let submit_button = Paragraph::new("Submit")
205                .block(
206                    Block::default()
207                        .borders(Borders::ALL)
208                        .border_style(submit_button_style)
209                        .border_type(BorderType::Rounded),
210                )
211                .alignment(Alignment::Center);
212            rect.render_widget(submit_button, chunks[3]);
213            render_close_button(rect, app, is_active);
214        }
215    }
216}