rust_kanban/ui/rendering/view/
create_theme.rs

1use crate::{
2    app::{state::Focus, App},
3    constants::LIST_SELECTED_SYMBOL,
4    ui::{
5        rendering::{
6            common::{render_blank_styled_canvas, render_close_button},
7            utils::{check_if_mouse_is_in_area, get_button_style, get_mouse_focusable_field_style},
8            view::CreateTheme,
9        },
10        Renderable,
11    },
12};
13use ratatui::{
14    layout::{Alignment, Constraint, Direction, Layout},
15    text::Line,
16    widgets::{Block, BorderType, Borders, Paragraph, Table},
17    Frame,
18};
19
20impl Renderable for CreateTheme {
21    fn render(rect: &mut Frame, app: &mut App, is_active: bool) {
22        // TODO: add a help section
23        let render_area = rect.area();
24        let main_chunks = Layout::default()
25            .direction(Direction::Vertical)
26            .constraints([Constraint::Fill(1), Constraint::Length(3)].as_ref())
27            .split(render_area);
28        let chunks = Layout::default()
29            .direction(Direction::Horizontal)
30            .constraints([Constraint::Fill(1), Constraint::Fill(1)].as_ref())
31            .margin(1)
32            .split(main_chunks[0]);
33        let button_chunks = Layout::default()
34            .direction(Direction::Horizontal)
35            .constraints([Constraint::Fill(1), Constraint::Fill(1)].as_ref())
36            .split(main_chunks[1]);
37
38        let submit_button_style = get_mouse_focusable_field_style(
39            app,
40            Focus::SubmitButton,
41            &button_chunks[0],
42            is_active,
43            false,
44        );
45        let reset_button_style = get_mouse_focusable_field_style(
46            app,
47            Focus::ExtraFocus,
48            &button_chunks[1],
49            is_active,
50            false,
51        );
52
53        let theme_being_edited = app.state.get_theme_being_edited();
54        let theme_table_rows = theme_being_edited.to_rows(app, is_active);
55        // Exception to not using get_button_style as we have to manage other state
56        let list_highlight_style = if !is_active {
57            app.current_theme.inactive_text_style
58        } else if check_if_mouse_is_in_area(&app.state.current_mouse_coordinates, &main_chunks[0]) {
59            app.state.mouse_focus = Some(Focus::ThemeEditor);
60            app.state.set_focus(Focus::ThemeEditor);
61            let top_of_list = main_chunks[0].y + 1;
62            let mut bottom_of_list = main_chunks[0].y + theme_table_rows.0.len() as u16;
63            if bottom_of_list > main_chunks[0].bottom() {
64                bottom_of_list = main_chunks[0].bottom();
65            }
66            let mouse_y = app.state.current_mouse_coordinates.1;
67            if mouse_y >= top_of_list && mouse_y <= bottom_of_list {
68                app.state
69                    .app_table_states
70                    .theme_editor
71                    .select(Some((mouse_y - top_of_list) as usize));
72            } else {
73                app.state.app_table_states.theme_editor.select(None);
74            }
75            app.current_theme.list_select_style
76        } else if app.state.app_table_states.theme_editor.selected().is_some() {
77            app.current_theme.list_select_style
78        } else {
79            app.current_theme.general_style
80        };
81        let theme_block_style = get_button_style(app, Focus::ThemeEditor, None, is_active, false);
82        let theme_title_list = Table::new(theme_table_rows.0, [Constraint::Fill(1)])
83            .block(Block::default().style(theme_block_style))
84            .row_highlight_style(list_highlight_style)
85            .highlight_symbol(LIST_SELECTED_SYMBOL);
86        let theme_element_list = Table::new(theme_table_rows.1, [Constraint::Fill(1)])
87            .block(Block::default().style(theme_block_style));
88        let submit_button = Paragraph::new(vec![Line::from("Create Theme")])
89            .block(
90                Block::default()
91                    .borders(Borders::ALL)
92                    .border_type(BorderType::Rounded)
93                    .style(submit_button_style),
94            )
95            .alignment(Alignment::Center);
96
97        let reset_button = Paragraph::new(vec![Line::from("Reset")])
98            .block(
99                Block::default()
100                    .borders(Borders::ALL)
101                    .border_type(BorderType::Rounded)
102                    .style(reset_button_style),
103            )
104            .alignment(Alignment::Center);
105
106        let border_block = Block::default()
107            .title("Create a new Theme")
108            .borders(Borders::ALL)
109            .border_type(BorderType::Rounded)
110            .border_style(theme_block_style);
111
112        render_blank_styled_canvas(rect, &app.current_theme, render_area, is_active);
113        rect.render_stateful_widget(
114            theme_title_list,
115            chunks[0],
116            &mut app.state.app_table_states.theme_editor,
117        );
118        rect.render_stateful_widget(
119            theme_element_list,
120            chunks[1],
121            &mut app.state.app_table_states.theme_editor,
122        );
123        rect.render_widget(submit_button, button_chunks[0]);
124        rect.render_widget(reset_button, button_chunks[1]);
125        rect.render_widget(border_block, main_chunks[0]);
126        if app.config.enable_mouse_support {
127            render_close_button(rect, app, is_active)
128        }
129    }
130}