datui_lib/widgets/
chart_export_modal.rs1use crate::chart_export::ChartExportFormat;
4use crate::chart_export_modal::{ChartExportFocus, ChartExportModal};
5use crate::widgets::radio_block::RadioBlock;
6use ratatui::layout::{Constraint, Direction, Layout, Rect};
7use ratatui::style::Style;
8use ratatui::widgets::{Block, BorderType, Borders, Clear, Paragraph, Widget};
9
10pub fn render_chart_export_modal(
11 area: Rect,
12 buf: &mut ratatui::buffer::Buffer,
13 modal: &mut ChartExportModal,
14 border_color: ratatui::style::Color,
15 active_color: ratatui::style::Color,
16) {
17 Clear.render(area, buf);
18 let block = Block::default()
19 .borders(Borders::ALL)
20 .border_type(BorderType::Rounded)
21 .border_style(Style::default().fg(border_color))
22 .title(" Export Chart ");
23 let inner = block.inner(area);
24 block.render(area, buf);
25
26 let horz = Layout::default()
28 .direction(Direction::Horizontal)
29 .constraints([Constraint::Length(12), Constraint::Min(40)])
30 .split(inner);
31
32 let format_list_area = horz[0];
33 let format_selected = ChartExportFormat::ALL
34 .iter()
35 .position(|&f| f == modal.selected_format)
36 .unwrap_or(0);
37 let is_format_focused = modal.focus == ChartExportFocus::FormatSelector;
38 let format_labels: Vec<&str> = ChartExportFormat::ALL.iter().map(|f| f.as_str()).collect();
39 RadioBlock::new(
40 " Format ",
41 &format_labels,
42 format_selected,
43 is_format_focused,
44 1,
45 border_color,
46 active_color,
47 )
48 .render(format_list_area, buf);
49
50 let right = horz[1];
51 let right_chunks = Layout::default()
52 .direction(Direction::Vertical)
53 .constraints([
54 Constraint::Length(3), Constraint::Length(3), Constraint::Length(3), Constraint::Length(1), Constraint::Length(3), ])
60 .split(right);
61
62 let path_area = right_chunks[0];
64 let is_path_focused = modal.focus == ChartExportFocus::PathInput;
65 let path_block = Block::default()
66 .borders(Borders::ALL)
67 .border_type(BorderType::Rounded)
68 .border_style(Style::default().fg(if is_path_focused {
69 active_color
70 } else {
71 border_color
72 }))
73 .title(" File Path ");
74 let path_inner = path_block.inner(path_area);
75 path_block.render(path_area, buf);
76 modal.path_input.set_focused(is_path_focused);
77 (&modal.path_input).render(path_inner, buf);
78
79 let title_area = right_chunks[1];
81 let is_title_focused = modal.focus == ChartExportFocus::TitleInput;
82 let title_block = Block::default()
83 .borders(Borders::ALL)
84 .border_type(BorderType::Rounded)
85 .border_style(Style::default().fg(if is_title_focused {
86 active_color
87 } else {
88 border_color
89 }))
90 .title(" Chart Title ");
91 let title_inner = title_block.inner(title_area);
92 title_block.render(title_area, buf);
93 modal.title_input.set_focused(is_title_focused);
94 (&modal.title_input).render(title_inner, buf);
95
96 let size_area = right_chunks[2];
98 let size_row = Layout::default()
99 .direction(Direction::Horizontal)
100 .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
101 .split(size_area);
102 let is_width_focused = modal.focus == ChartExportFocus::WidthInput;
103 let is_height_focused = modal.focus == ChartExportFocus::HeightInput;
104 let width_block = Block::default()
105 .borders(Borders::ALL)
106 .border_type(BorderType::Rounded)
107 .border_style(Style::default().fg(if is_width_focused {
108 active_color
109 } else {
110 border_color
111 }))
112 .title(" Width ");
113 let width_inner = width_block.inner(size_row[0]);
114 width_block.render(size_row[0], buf);
115 modal.width_input.set_focused(is_width_focused);
116 (&modal.width_input).render(width_inner, buf);
117 let height_block = Block::default()
118 .borders(Borders::ALL)
119 .border_type(BorderType::Rounded)
120 .border_style(Style::default().fg(if is_height_focused {
121 active_color
122 } else {
123 border_color
124 }))
125 .title(" Height ");
126 let height_inner = height_block.inner(size_row[1]);
127 height_block.render(size_row[1], buf);
128 modal.height_input.set_focused(is_height_focused);
129 (&modal.height_input).render(height_inner, buf);
130
131 let btn_area = right_chunks[4];
133 let btn_chunks = Layout::default()
134 .direction(Direction::Horizontal)
135 .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
136 .split(btn_area);
137
138 let is_export_focused = modal.focus == ChartExportFocus::ExportButton;
139 Paragraph::new("Export")
140 .style(if is_export_focused {
141 Style::default().fg(active_color)
142 } else {
143 Style::default().fg(border_color)
144 })
145 .block(
146 Block::default()
147 .borders(Borders::ALL)
148 .border_type(BorderType::Rounded)
149 .border_style(if is_export_focused {
150 Style::default().fg(active_color)
151 } else {
152 Style::default().fg(border_color)
153 }),
154 )
155 .centered()
156 .render(btn_chunks[0], buf);
157
158 let is_cancel_focused = modal.focus == ChartExportFocus::CancelButton;
159 Paragraph::new("Cancel")
160 .style(if is_cancel_focused {
161 Style::default().fg(active_color)
162 } else {
163 Style::default().fg(border_color)
164 })
165 .block(
166 Block::default()
167 .borders(Borders::ALL)
168 .border_type(BorderType::Rounded)
169 .border_style(if is_cancel_focused {
170 Style::default().fg(active_color)
171 } else {
172 Style::default().fg(border_color)
173 }),
174 )
175 .centered()
176 .render(btn_chunks[1], buf);
177}