diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs index d2de52cc..9e4e3d0b 100644 --- a/src/components/revision_files.rs +++ b/src/components/revision_files.rs @@ -31,6 +31,11 @@ const FOLDER_ICON_COLLAPSED: &str = "\u{25b8}"; //▸ const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾ const EMPTY_STR: &str = ""; +enum Focus { + Tree, + File, +} + pub struct RevisionFilesComponent { queue: Queue, title: String, @@ -43,6 +48,7 @@ pub struct RevisionFilesComponent { scroll_top: Cell, revision: Option, visible: bool, + focus: Focus, key_config: SharedKeyConfig, } @@ -67,6 +73,7 @@ impl RevisionFilesComponent { files: Vec::new(), revision: None, visible: false, + focus: Focus::Tree, key_config, } } @@ -276,18 +283,26 @@ impl Component for RevisionFilesComponent { ) -> Result { if self.is_visible() { if let Event::Key(key) = event { + let is_tree_focused = + matches!(self.focus, Focus::Tree); if key == self.key_config.exit_popup { self.hide(); + } else if is_tree_focused + && tree_nav(&mut self.tree, &self.key_config, key) + { + self.selection_changed(); } else if key == self.key_config.blame { if self.blame() { self.hide(); } - } else if tree_nav( - &mut self.tree, - &self.key_config, - key, - ) { - self.selection_changed(); + } else if key == self.key_config.move_right { + if is_tree_focused { + self.focus = Focus::File; + } else { + self.focus = Focus::Tree; + } + } else if !is_tree_focused { + self.current_file.event(event)?; } } diff --git a/src/components/syntax_text.rs b/src/components/syntax_text.rs index 421314bc..fb0fdb3d 100644 --- a/src/components/syntax_text.rs +++ b/src/components/syntax_text.rs @@ -13,8 +13,9 @@ use asyncgit::{ AsyncNotification, CWD, }; use crossbeam_channel::Sender; +use crossterm::event::Event; use itertools::Either; -use std::{convert::From, path::Path}; +use std::{cell::Cell, convert::From, path::Path}; use tui::{ backend::Backend, layout::Rect, @@ -27,7 +28,8 @@ pub struct SyntaxTextComponent { current_file: Option<(String, Either)>, async_highlighting: AsyncSingleJob, - _key_config: SharedKeyConfig, + key_config: SharedKeyConfig, + scroll_top: Cell, } impl SyntaxTextComponent { @@ -42,7 +44,8 @@ impl SyntaxTextComponent { AsyncNotification::SyntaxHighlighting, ), current_file: None, - _key_config: key_config, + scroll_top: Cell::new(0), + key_config, } } @@ -115,14 +118,16 @@ impl DrawableComponent for SyntaxTextComponent { f: &mut Frame, area: Rect, ) -> Result<()> { - let content = - Paragraph::new(self.current_file.as_ref().map_or_else( - || Text::from(""), - |(_, content)| match content { - Either::Left(syn) => syn.into(), - Either::Right(s) => Text::from(s.as_str()), - }, - )) + let text = self.current_file.as_ref().map_or_else( + || Text::from(""), + |(_, content)| match content { + Either::Left(syn) => syn.into(), + Either::Right(s) => Text::from(s.as_str()), + }, + ); + + let content = Paragraph::new(text) + .scroll((self.scroll_top.get(), 0)) .wrap(Wrap { trim: false }); f.render_widget(content, area); @@ -142,9 +147,18 @@ impl Component for SyntaxTextComponent { fn event( &mut self, - _event: crossterm::event::Event, + event: crossterm::event::Event, ) -> Result { - //TODO: scrolling + if let Event::Key(key) = event { + if key == self.key_config.move_down { + self.scroll_top + .set(self.scroll_top.get().saturating_add(1)); + } else if key == self.key_config.move_up { + self.scroll_top + .set(self.scroll_top.get().saturating_sub(1)); + } + } + Ok(EventState::NotConsumed) } }