leetcode_tui_rs/widgets/
popup.rs1use crate::ctx::Ctx;
2use leetcode_tui_config::CONFIG;
3use leetcode_tui_shared::layout::GetWindowStats;
4use ratatui::prelude::*;
5use ratatui::widgets::{
6 Block, Borders, Clear, List, ListItem, Paragraph, Scrollbar, StatefulWidget, Widget, Wrap,
7};
8
9pub struct SelectPopup<'a> {
10 ctx: &'a mut Ctx,
11}
12
13impl<'a> SelectPopup<'a> {
14 pub fn new(ctx: &'a mut Ctx) -> Self {
15 Self { ctx }
16 }
17}
18
19impl<'a> Widget for SelectPopup<'a> {
20 fn render(self, _area: Rect, buf: &mut Buffer) {
21 let c_def = &CONFIG.as_ref().theme.defaults;
22 let mut block: Block<'_> = Block::default();
23 if let Some(title) = self.ctx.select_popup.get_title() {
24 block = Block::default().title(title);
25 }
26 let block = block
27 .borders(Borders::ALL)
28 .border_style(Style::default().fg(c_def.info.into()));
29 Clear.render(self.get_window().root.popup.outer, buf);
30 block.render(self.get_window().root.popup.outer, buf);
31 let chunks = Layout::default()
32 .direction(Direction::Horizontal)
33 .constraints(vec![Constraint::Percentage(100), Constraint::Min(1)])
34 .split(self.get_window().root.popup.inner);
35 let content_area = chunks[0];
36 let lines = self.ctx.select_popup.get_lines().clone();
37
38 let list = List::new(
39 lines
40 .iter()
41 .map(|l| ListItem::new(vec![Line::from(l.as_ref())]).fg(c_def.fg_dark))
42 .collect::<Vec<_>>(),
43 )
44 .highlight_style(
45 Style::default()
46 .bg(c_def.bg_highlight.into())
47 .fg(c_def.fg.into())
48 .add_modifier(Modifier::BOLD),
49 );
50 StatefulWidget::render(list, content_area, buf, &mut self.ctx.select_popup.state);
51 }
57}
58
59pub struct Popup<'a> {
60 ctx: &'a mut Ctx,
61}
62
63impl<'a> Popup<'a> {
64 pub fn new(ctx: &'a mut Ctx) -> Self {
65 Self { ctx }
66 }
67}
68
69impl<'a> Widget for Popup<'a> {
70 fn render(self, _area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) {
71 let c_def = &CONFIG.as_ref().theme.defaults;
72 let mut block: Block<'_> = Block::default();
73 if let Some(title) = self.ctx.popup.get_title() {
74 block = Block::default().title(title);
75 }
76 let block = block
77 .borders(Borders::ALL)
78 .border_style(Style::default().fg(c_def.info.into()));
79 Clear.render(self.get_window().root.popup.outer, buf);
80 block.render(self.get_window().root.popup.outer, buf);
81 let chunks = Layout::default()
82 .direction(Direction::Horizontal)
83 .constraints(vec![Constraint::Percentage(100), Constraint::Min(1)])
84 .split(self.get_window().root.popup.inner);
85 let content_area = chunks[0];
86 let scrollbar_area = chunks[1];
87
88 let content = self.ctx.popup.get_lines().join("\n");
89 let text = tui_markdown::from_str(content.as_str());
90
91 Paragraph::new(text)
92 .scroll((self.ctx.popup.v_scroll as u16, 0))
93 .wrap(Wrap { trim: true })
94 .style(Style::default().fg(CONFIG.as_ref().theme.defaults.fg.into()))
95 .render(content_area, buf);
96
97 Scrollbar::default()
98 .orientation(ratatui::widgets::ScrollbarOrientation::VerticalRight)
99 .begin_symbol(Some("↑"))
100 .end_symbol(Some("↓"))
101 .render(scrollbar_area, buf, &mut self.ctx.popup.v_scroll_state)
102 }
103}