Skip to main content

datui_lib/widgets/
chart_export_modal.rs

1//! Chart export modal rendering: format (PNG/EPS), optional title, and path.
2
3use 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 chunks = Layout::default()
27        .direction(Direction::Vertical)
28        .constraints([
29            Constraint::Length(3), // Format row
30            Constraint::Length(3), // Chart title (optional)
31            Constraint::Length(3), // Path row
32            Constraint::Length(3), // Buttons
33        ])
34        .split(inner);
35
36    // Format: radio block (PNG / EPS)
37    let format_area = chunks[0];
38    let is_format_focused = modal.focus == ChartExportFocus::FormatSelector;
39    let format_labels: Vec<&str> = ChartExportFormat::ALL.iter().map(|f| f.as_str()).collect();
40    let format_selected = ChartExportFormat::ALL
41        .iter()
42        .position(|&f| f == modal.selected_format)
43        .unwrap_or(0);
44    RadioBlock::new(
45        " Format ",
46        &format_labels,
47        format_selected,
48        is_format_focused,
49        2,
50        border_color,
51        active_color,
52    )
53    .render(format_area, buf);
54
55    // Chart title (optional; blank = no title on export)
56    let title_area = chunks[1];
57    let is_title_focused = modal.focus == ChartExportFocus::TitleInput;
58    let title_block = Block::default()
59        .borders(Borders::ALL)
60        .border_type(BorderType::Rounded)
61        .border_style(Style::default().fg(if is_title_focused {
62            active_color
63        } else {
64            border_color
65        }))
66        .title(" Chart Title ");
67    let title_inner = title_block.inner(title_area);
68    title_block.render(title_area, buf);
69    modal.title_input.set_focused(is_title_focused);
70    (&modal.title_input).render(title_inner, buf);
71
72    // Path input
73    let path_area = chunks[2];
74    let is_path_focused = modal.focus == ChartExportFocus::PathInput;
75    let path_block = Block::default()
76        .borders(Borders::ALL)
77        .border_type(BorderType::Rounded)
78        .border_style(Style::default().fg(if is_path_focused {
79            active_color
80        } else {
81            border_color
82        }))
83        .title(" File Path ");
84    let path_inner = path_block.inner(path_area);
85    path_block.render(path_area, buf);
86    modal.path_input.set_focused(is_path_focused);
87    (&modal.path_input).render(path_inner, buf);
88
89    // Buttons
90    let btn_area = chunks[3];
91    let btn_chunks = Layout::default()
92        .direction(Direction::Horizontal)
93        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
94        .split(btn_area);
95
96    let is_export_focused = modal.focus == ChartExportFocus::ExportButton;
97    Paragraph::new("Export")
98        .style(if is_export_focused {
99            Style::default().fg(active_color)
100        } else {
101            Style::default().fg(border_color)
102        })
103        .block(
104            Block::default()
105                .borders(Borders::ALL)
106                .border_type(BorderType::Rounded)
107                .border_style(if is_export_focused {
108                    Style::default().fg(active_color)
109                } else {
110                    Style::default().fg(border_color)
111                }),
112        )
113        .centered()
114        .render(btn_chunks[0], buf);
115
116    let is_cancel_focused = modal.focus == ChartExportFocus::CancelButton;
117    Paragraph::new("Cancel")
118        .style(if is_cancel_focused {
119            Style::default().fg(active_color)
120        } else {
121            Style::default().fg(border_color)
122        })
123        .block(
124            Block::default()
125                .borders(Borders::ALL)
126                .border_type(BorderType::Rounded)
127                .border_style(if is_cancel_focused {
128                    Style::default().fg(active_color)
129                } else {
130                    Style::default().fg(border_color)
131                }),
132        )
133        .centered()
134        .render(btn_chunks[1], buf);
135}