diff --git a/Cargo.lock b/Cargo.lock index d74ca30..c088c03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -511,41 +511,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "deranged" version = "0.3.11" @@ -555,29 +520,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive-getters" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "derive_setters" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "diff" version = "0.1.13" @@ -595,15 +537,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "document-features" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" -dependencies = [ - "litrs", -] - [[package]] name = "either" version = "1.13.0" @@ -846,12 +779,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "indexmap" version = "2.6.0" @@ -986,12 +913,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - [[package]] name = "lock_api" version = "0.4.12" @@ -1594,7 +1515,6 @@ dependencies = [ "slice-utils", "thiserror", "tui-markdown", - "tui-popup", "tui-prompts", "tui-textarea", ] @@ -1855,18 +1775,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tui-popup" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ee3d08800c83ba0a2efaec44d225bcc3f885f30e2b520a17e2cd962b7da6ab" -dependencies = [ - "derive-getters", - "derive_setters", - "document-features", - "ratatui", -] - [[package]] name = "tui-prompts" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 155056b..fb9fea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ thiserror = "1.0.65" tui-textarea = "0.7.0" tui-prompts = "0.5.0" slice-utils = { git = "https://dev.zaphar.net/zaphar/slice-cursor-rs.git" } -tui-popup = "0.6.0" serde_json = "1.0.133" colorsys = "0.6.7" tui-markdown = { version = "0.3.1", features = [] } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index b4e0cff..7409750 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -77,6 +77,7 @@ pub struct AppState<'ws> { pub numeric_prefix: Vec, pub char_queue: Vec, pub range_select: RangeSelection, + pub dialog_scroll: u16, dirty: bool, popup: Text<'ws>, clipboard: Option, @@ -91,6 +92,7 @@ impl<'ws> Default for AppState<'ws> { numeric_prefix: Default::default(), char_queue: Default::default(), range_select: Default::default(), + dialog_scroll: 0, dirty: Default::default(), popup: Default::default(), clipboard: Default::default(), @@ -332,6 +334,12 @@ impl<'ws> Workspace<'ws> { KeyCode::Char('h') if key.modifiers == KeyModifiers::ALT => { self.exit_dialog_mode()? } + KeyCode::Char('j') | KeyCode::Down => { + self.state.dialog_scroll = self.state.dialog_scroll.saturating_add(1); + } + KeyCode::Char('k') | KeyCode::Up => { + self.state.dialog_scroll = self.state.dialog_scroll.saturating_sub(1); + } _ => { // NOOP } diff --git a/src/ui/render/dialog.rs b/src/ui/render/dialog.rs new file mode 100644 index 0000000..2dd1248 --- /dev/null +++ b/src/ui/render/dialog.rs @@ -0,0 +1,56 @@ +use ratatui::{ + self, + layout::{Constraint, Layout, Rect}, + style::{Color, Style, Stylize}, + text::Text, + widgets::{Block, Paragraph, Widget, Wrap}, +}; + +pub struct Dialog<'w> { + content: Text<'w>, + title: &'w str, + scroll: (u16, u16), +} + +impl<'w> Dialog<'w> { + pub fn new(content: Text<'w>, title: &'w str) -> Self { + Self { + content, + title, + scroll: (0, 0), + } + } + + pub fn scroll(mut self, line: u16) -> Self { + self.scroll.0 = line; + self + } +} + +impl<'w> Widget for Dialog<'w> { + fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized, + { + // First find the center of the area. + let content_width = self.content.width(); + let sidebar_width = (area.width - (content_width as u16) + 2) / 2; + let [_, dialog_area, _] = Layout::horizontal(vec![ + Constraint::Length(sidebar_width), + Constraint::Fill(1), + Constraint::Length(sidebar_width), + ]) + .areas(area); + + let dialog_block = Block::bordered() + .title_top(self.title) + .title_bottom("j,k or up,down to scroll") + .style(Style::default().on_black()); + let dialog = Paragraph::new(self.content.clone()) + .wrap(Wrap::default()) + .scroll(self.scroll.clone()) + .block(dialog_block) + .style(Style::default()); + dialog.render(dialog_area, buf); + } +} diff --git a/src/ui/render/mod.rs b/src/ui/render/mod.rs index 6afba12..e2b79af 100644 --- a/src/ui/render/mod.rs +++ b/src/ui/render/mod.rs @@ -5,12 +5,12 @@ use ratatui::{ widgets::{Block, Paragraph, Tabs, Widget}, Frame, }; -use tui_popup::Popup; use super::*; pub mod viewport; pub use viewport::Viewport; +pub mod dialog; #[cfg(test)] mod test; @@ -98,38 +98,40 @@ impl<'widget, 'ws: 'widget> Widget for &'widget mut Workspace<'ws> { where Self: Sized, { - let outer_block = Block::bordered() - .title(Line::from( - self.name - .file_name() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_else(|| String::from("Unknown")), - )) - .title_bottom(match self.state.modality() { - Modality::Navigate => "navigate", - Modality::CellEdit => "edit", - Modality::Command => "command", - Modality::Dialog => "", - Modality::RangeSelect => "range-copy", - }) - .title_bottom( - Line::from(format!( - "{},{}", - self.book.location.row, self.book.location.col - )) - .right_aligned(), - ); - - for (rect, f) in self.get_render_parts(area.clone()) { - f(rect, buf, self); - } - - outer_block.render(area, buf); - if self.state.modality() == &Modality::Dialog { + // Use a popup here. let lines = Text::from_iter(self.state.popup.iter().cloned()); - let popup = Popup::new(lines); + let popup = dialog::Dialog::new(lines, "Help").scroll(self.state.dialog_scroll); + //let popup = Paragraph::new(lines); popup.render(area, buf); + } else { + let outer_block = Block::bordered() + .title(Line::from( + self.name + .file_name() + .map(|p| p.to_string_lossy().to_string()) + .unwrap_or_else(|| String::from("Unknown")), + )) + .title_bottom(match self.state.modality() { + Modality::Navigate => "navigate", + Modality::CellEdit => "edit", + Modality::Command => "command", + Modality::Dialog => "", + Modality::RangeSelect => "range-copy", + }) + .title_bottom( + Line::from(format!( + "{},{}", + self.book.location.row, self.book.location.col + )) + .right_aligned(), + ); + + for (rect, f) in self.get_render_parts(area.clone()) { + f(rect, buf, self); + } + + outer_block.render(area, buf); } } }