fresh/view/controls/toggle/
render.rs1use ratatui::layout::Rect;
4use ratatui::style::Style;
5use ratatui::text::{Line, Span};
6use ratatui::widgets::Paragraph;
7use ratatui::Frame;
8
9use super::{FocusState, ToggleColors, ToggleLayout, ToggleState};
10
11pub fn render_toggle(
22 frame: &mut Frame,
23 area: Rect,
24 state: &ToggleState,
25 colors: &ToggleColors,
26) -> ToggleLayout {
27 render_toggle_aligned(frame, area, state, colors, None)
28}
29
30pub fn render_toggle_aligned(
42 frame: &mut Frame,
43 area: Rect,
44 state: &ToggleState,
45 colors: &ToggleColors,
46 label_width: Option<u16>,
47) -> ToggleLayout {
48 if area.height == 0 || area.width < 4 {
49 return ToggleLayout {
50 checkbox_area: Rect::default(),
51 full_area: area,
52 };
53 }
54
55 let (bracket_color, check_color, label_color) = match state.focus {
61 FocusState::Normal => (colors.bracket, colors.checkmark, colors.label),
62 FocusState::Focused => (colors.focused_fg, colors.focused_fg, colors.focused_fg),
63 FocusState::Hovered => (colors.focused_fg, colors.focused_fg, colors.focused_fg),
64 FocusState::Disabled => (colors.disabled, colors.disabled, colors.disabled),
65 };
66
67 let actual_label_width = label_width.unwrap_or(state.label.len() as u16);
69 let padded_label = format!(
70 "{:width$}",
71 state.label,
72 width = actual_label_width as usize
73 );
74
75 const CHIP_WIDTH: u16 = 3;
82
83 let line = if state.inherited {
84 Line::from(vec![
88 Span::styled(padded_label, Style::default().fg(label_color)),
89 Span::styled(": ", Style::default().fg(label_color)),
90 Span::styled("[", Style::default().fg(bracket_color)),
91 Span::styled("-", Style::default().fg(bracket_color)),
92 Span::styled("]", Style::default().fg(bracket_color)),
93 ])
94 } else if state.checked {
95 Line::from(vec![
96 Span::styled(padded_label, Style::default().fg(label_color)),
97 Span::styled(": ", Style::default().fg(label_color)),
98 Span::styled("[", Style::default().fg(bracket_color)),
99 Span::styled(
100 "v",
101 Style::default()
102 .fg(check_color)
103 .add_modifier(ratatui::style::Modifier::BOLD),
104 ),
105 Span::styled("]", Style::default().fg(bracket_color)),
106 ])
107 } else {
108 Line::from(vec![
109 Span::styled(padded_label, Style::default().fg(label_color)),
110 Span::styled(": ", Style::default().fg(label_color)),
111 Span::styled("[", Style::default().fg(bracket_color)),
112 Span::styled(" ", Style::default().fg(bracket_color)),
113 Span::styled("]", Style::default().fg(bracket_color)),
114 ])
115 };
116
117 let paragraph = Paragraph::new(line);
118 frame.render_widget(paragraph, area);
119
120 let label_overhead = actual_label_width.saturating_add(2);
122 let checkbox_start = area.x.saturating_add(label_overhead);
123 let chip_avail = area.width.saturating_sub(label_overhead.min(area.width));
124 let checkbox_area = Rect::new(checkbox_start, area.y, CHIP_WIDTH.min(chip_avail), 1);
125
126 let full_width = (actual_label_width + 2 + CHIP_WIDTH).min(area.width);
128 let full_area = Rect::new(area.x, area.y, full_width, 1);
129
130 ToggleLayout {
131 checkbox_area,
132 full_area,
133 }
134}