rust_kanban/ui/rendering/view/
main_menu_view.rs1use crate::{
2 app::App,
3 constants::LIST_SELECTED_SYMBOL,
4 ui::{
5 rendering::{
6 common::{draw_help, draw_title, render_close_button, render_logs},
7 utils::{
8 check_if_active_and_get_style,
9 get_mouse_focusable_field_style_with_vertical_list_selection,
10 },
11 view::MainMenuView,
12 },
13 Renderable,
14 },
15};
16use ratatui::{
17 layout::{Alignment, Constraint, Direction, Layout, Rect},
18 style::Modifier,
19 widgets::{Block, BorderType, Borders, List, ListItem, Paragraph},
20 Frame,
21};
22
23impl Renderable for MainMenuView {
24 fn render(rect: &mut Frame, app: &mut App, is_active: bool) {
25 let chunks = Layout::default()
26 .direction(Direction::Vertical)
27 .constraints(
28 [
29 Constraint::Length(3),
30 Constraint::Length(10),
31 Constraint::Fill(1),
32 Constraint::Fill(2),
33 ]
34 .as_ref(),
35 )
36 .split(rect.area());
37
38 let help_chunks = Layout::default()
39 .direction(Direction::Horizontal)
40 .constraints(
41 [
42 Constraint::Fill(1),
43 Constraint::Length(1),
44 Constraint::Fill(1),
45 ]
46 .as_ref(),
47 )
48 .margin(1)
49 .split(chunks[2]);
50
51 let general_style = check_if_active_and_get_style(
52 is_active,
53 app.current_theme.inactive_text_style,
54 app.current_theme.general_style,
55 );
56 let rapid_blink_general_style = if is_active {
57 general_style.add_modifier(Modifier::RAPID_BLINK)
58 } else {
59 general_style
60 };
61
62 let main_menu_help = draw_help(app, chunks[2], is_active);
63 let help_separator = Block::default()
64 .borders(Borders::LEFT)
65 .border_style(general_style);
66
67 rect.render_widget(draw_title(app, chunks[0], is_active), chunks[0]);
68
69 if let Some(email_id) = &app.state.user_login_data.email_id {
70 let email_id = email_id.to_string();
71 let email_id_len = email_id.len() as u16 + 4;
72 let sub_main_menu_chunks = Layout::default()
73 .direction(Direction::Horizontal)
74 .constraints(
75 [
76 Constraint::Length(chunks[1].width - email_id_len),
77 Constraint::Length(email_id_len),
78 ]
79 .as_ref(),
80 )
81 .split(chunks[1]);
82
83 let border_block = Block::default()
84 .borders(Borders::ALL)
85 .border_style(rapid_blink_general_style)
86 .border_type(BorderType::Rounded);
87
88 let email_chunks = Layout::default()
89 .direction(Direction::Vertical)
90 .constraints(
91 [
92 Constraint::Length((sub_main_menu_chunks[1].height - 4) / 2),
93 Constraint::Length(1),
94 Constraint::Length(1),
95 Constraint::Length(1),
96 Constraint::Length((sub_main_menu_chunks[1].height - 4) / 2),
97 ]
98 .as_ref(),
99 )
100 .split(sub_main_menu_chunks[1]);
101
102 let heading_text = Paragraph::new("Logged in as:")
103 .block(Block::default().style(rapid_blink_general_style))
104 .alignment(Alignment::Center)
105 .wrap(ratatui::widgets::Wrap { trim: true });
106
107 let email_id_text = Paragraph::new(email_id)
108 .block(Block::default().style(rapid_blink_general_style))
109 .alignment(Alignment::Center)
110 .wrap(ratatui::widgets::Wrap { trim: true });
111
112 draw_main_menu(app, sub_main_menu_chunks[0], rect, is_active);
113 rect.render_widget(border_block, sub_main_menu_chunks[1]);
114 rect.render_widget(heading_text, email_chunks[1]);
115 rect.render_widget(email_id_text, email_chunks[3]);
116 } else {
117 draw_main_menu(app, chunks[1], rect, is_active);
118 }
119
120 rect.render_widget(main_menu_help.0, chunks[2]);
121 rect.render_stateful_widget(
122 main_menu_help.1,
123 help_chunks[0],
124 &mut app.state.app_table_states.help,
125 );
126 rect.render_widget(help_separator, help_chunks[1]);
127 rect.render_stateful_widget(
128 main_menu_help.2,
129 help_chunks[2],
130 &mut app.state.app_table_states.help,
131 );
132 render_logs(app, true, chunks[3], rect, is_active);
133 if app.config.enable_mouse_support {
134 render_close_button(rect, app, is_active);
135 }
136 }
137}
138
139fn draw_main_menu(app: &mut App, render_area: Rect, rect: &mut Frame, is_active: bool) {
140 let main_menu_items = app.main_menu.all();
141 let menu_style = get_mouse_focusable_field_style_with_vertical_list_selection(
142 app,
143 &main_menu_items,
144 render_area,
145 is_active,
146 );
147 let default_style = check_if_active_and_get_style(
148 is_active,
149 app.current_theme.inactive_text_style,
150 app.current_theme.general_style,
151 );
152 let highlight_style = check_if_active_and_get_style(
153 is_active,
154 app.current_theme.inactive_text_style,
155 app.current_theme.list_select_style,
156 );
157 let list_items = main_menu_items
158 .iter()
159 .map(|i| ListItem::new(i.to_string()))
160 .collect::<Vec<ListItem>>();
161 let main_menu = List::new(list_items)
162 .block(
163 Block::default()
164 .title("Main menu")
165 .style(default_style)
166 .borders(Borders::ALL)
167 .border_style(menu_style)
168 .border_type(BorderType::Rounded),
169 )
170 .highlight_style(highlight_style)
171 .highlight_symbol(LIST_SELECTED_SYMBOL);
172
173 rect.render_stateful_widget(
174 main_menu,
175 render_area,
176 &mut app.state.app_list_states.main_menu,
177 );
178}