diff --git a/src/app/mod.rs b/src/app/mod.rs index 46afe04..697bbd0 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -15,6 +15,7 @@ pub struct App<'a> { tabs: &'a [Tab], pub state: TableState, pub torrents: Torrents, + pub show_popup: bool, } impl<'a> App<'a> { @@ -27,6 +28,7 @@ impl<'a> App<'a> { index: 0, state: TableState::default(), torrents: Torrents::new(), + show_popup: false, } } @@ -96,4 +98,8 @@ impl<'a> App<'a> { pub fn tabs(&self) -> &[Tab] { self.tabs } + + pub fn toggle_popup(&mut self) { + self.show_popup = !self.show_popup; + } } diff --git a/src/handler.rs b/src/handler.rs index 51f10e9..f5c2b20 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -28,6 +28,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> Result<()> { KeyCode::Char('2') => app.switch_tab(1), KeyCode::Char('3') => app.switch_tab(2), KeyCode::Char('4') => app.switch_tab(3), + KeyCode::Char('t') => app.toggle_popup(), // Other handlers you could add here. _ => {} } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 849b3da..2c5e6ab 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -3,51 +3,15 @@ use ratatui::{ prelude::{Constraint, Direction, Layout}, style::{Color, Style}, text::Line, - widgets::{Block, BorderType, Borders, Row, Table, Tabs}, + widgets::{Block, BorderType, Borders, Clear, Tabs}, Frame, }; +mod popup; +mod table; -use crate::app::{utils::Wrapper, App, Tab}; +use crate::app::{App, Tab}; -fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> { - let fields = tab.fields(); - let torrents = app.torrents.set_fields(None).torrents(); - - let rows: Vec> = torrents - .iter() - .map(|torrent| { - Row::new( - fields - .iter() - .map(|&field| field.value(torrent.clone())) - .collect::>(), - ) - }) - .collect(); - - let widths = fields - .iter() - .map(|&field| Constraint::Length(field.width())) - .collect::>(); - - let header = Row::new( - fields - .iter() - .map(|&field| field.title()) - .collect::>(), - ) - .style(Style::default().fg(Color::Yellow)); - Table::new(rows, widths) - .block( - Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Rounded), - ) - .header(header) - .highlight_style(Style::default().fg(Color::Red)) - .highlight_symbol(">> ") - .column_spacing(1) -} +use self::{popup::render_popup, table::render_table}; /// Renders the user interface widgets. pub fn render(app: &mut App, frame: &mut Frame) { @@ -88,5 +52,12 @@ pub fn render(app: &mut App, frame: &mut Frame) { 2 => render_table(app, Tab::Downloading), _ => unreachable!(), }; - frame.render_stateful_widget(table, chunks[1], &mut app.state) // renders table + frame.render_stateful_widget(table, chunks[1], &mut app.state); // renders table + + if app.show_popup { + let block = Block::default().title("Popup").borders(Borders::ALL); + let size = render_popup(60, 20, size); + frame.render_widget(Clear, size); + frame.render_widget(block, size); + } } diff --git a/src/ui/popup.rs b/src/ui/popup.rs new file mode 100644 index 0000000..2be27a0 --- /dev/null +++ b/src/ui/popup.rs @@ -0,0 +1,21 @@ +use ratatui::layout::{Constraint, Direction, Layout, Rect}; + +pub fn render_popup(percent_x: u16, percent_y: u16, r: Rect) -> Rect { + let popup_layput = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage((100 - percent_y) / 2), + Constraint::Percentage(percent_y), + Constraint::Percentage((100 - percent_y) / 2), + ]) + .split(r); + + Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage((100 - percent_y) / 2), + Constraint::Percentage(percent_y), + Constraint::Percentage((100 - percent_y) / 2), + ]) + .split(popup_layput[1])[1] +} diff --git a/src/ui/table.rs b/src/ui/table.rs new file mode 100644 index 0000000..26d0cb3 --- /dev/null +++ b/src/ui/table.rs @@ -0,0 +1,47 @@ +use ratatui::{ + layout::Constraint, + style::{Color, Style}, + widgets::{Block, BorderType, Borders, Row, Table}, +}; + +use crate::app::{utils::Wrapper, App, Tab}; + +pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> { + let fields = tab.fields(); + let torrents = app.torrents.set_fields(None).torrents(); + + let rows: Vec> = torrents + .iter() + .map(|torrent| { + Row::new( + fields + .iter() + .map(|&field| field.value(torrent.clone())) + .collect::>(), + ) + }) + .collect(); + + let widths = fields + .iter() + .map(|&field| Constraint::Length(field.width())) + .collect::>(); + + let header = Row::new( + fields + .iter() + .map(|&field| field.title()) + .collect::>(), + ) + .style(Style::default().fg(Color::Yellow)); + Table::new(rows, widths) + .block( + Block::default() + .borders(Borders::ALL) + .border_type(BorderType::Rounded), + ) + .header(header) + .highlight_style(Style::default().fg(Color::Red)) + .highlight_symbol(">> ") + .column_spacing(1) +}