From 4db4ffad994bd614763641716013fa7ad41e1eb9 Mon Sep 17 00:00:00 2001 From: Turgay Bulut Date: Mon, 1 Jun 2026 04:15:26 +0300 Subject: feat: add expanded sidebar collapse control (#291) * feat: add expanded sidebar collapse control refs #278 * fix: place sidebar collapse control inside content refs #278 --------- Co-authored-by: Can Celik --- src/app/input/mouse.rs | 10 ++++----- src/app/input/sidebar.rs | 56 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 10 deletions(-) (limited to 'src/app/input') diff --git a/src/app/input/mouse.rs b/src/app/input/mouse.rs index cc03c8f6..b991828a 100644 --- a/src/app/input/mouse.rs +++ b/src/app/input/mouse.rs @@ -449,12 +449,12 @@ impl AppState { } if in_sidebar { - if self.sidebar_collapsed { - if self.on_collapsed_sidebar_toggle(mouse.column, mouse.row) { - self.sidebar_collapsed = false; - return None; - } + if self.on_sidebar_toggle(mouse.column, mouse.row) { + self.sidebar_collapsed = !self.sidebar_collapsed; + return None; + } + if self.sidebar_collapsed { if let Some(idx) = self.collapsed_workspace_at_row(mouse.row) { self.switch_workspace(idx); self.mode = Mode::Terminal; diff --git a/src/app/input/sidebar.rs b/src/app/input/sidebar.rs index 8ba12bc6..43093a82 100644 --- a/src/app/input/sidebar.rs +++ b/src/app/input/sidebar.rs @@ -238,17 +238,25 @@ impl AppState { return false; } let sidebar = self.view.sidebar_rect; + let toggle = crate::ui::expanded_sidebar_toggle_rect(sidebar); + let on_toggle = toggle.width > 0 + && col >= toggle.x + && col < toggle.x + toggle.width + && row >= toggle.y + && row < toggle.y + toggle.height; sidebar.width > 0 + && !on_toggle && col == sidebar.x + sidebar.width.saturating_sub(1) && row >= sidebar.y && row < sidebar.y + sidebar.height } - pub(super) fn on_collapsed_sidebar_toggle(&self, col: u16, row: u16) -> bool { - if !self.sidebar_collapsed { - return false; - } - let rect = crate::ui::collapsed_sidebar_toggle_rect(self.view.sidebar_rect); + pub(super) fn on_sidebar_toggle(&self, col: u16, row: u16) -> bool { + let rect = if self.sidebar_collapsed { + crate::ui::collapsed_sidebar_toggle_rect(self.view.sidebar_rect) + } else { + crate::ui::expanded_sidebar_toggle_rect(self.view.sidebar_rect) + }; rect.width > 0 && col >= rect.x && col < rect.x + rect.width @@ -969,6 +977,24 @@ mod tests { assert!(!app.state.sidebar_collapsed); } + #[test] + fn clicking_expanded_sidebar_toggle_collapses_sidebar() { + let mut app = app_for_mouse_test(); + app.state.sidebar_collapsed = false; + app.state.view.sidebar_rect = Rect::new(0, 0, 26, 20); + app.state.view.terminal_area = Rect::new(26, 0, 80, 20); + + let toggle = crate::ui::expanded_sidebar_toggle_rect(app.state.view.sidebar_rect); + app.handle_mouse(mouse( + MouseEventKind::Down(MouseButton::Left), + toggle.x, + toggle.y, + )); + + assert!(app.state.sidebar_collapsed); + assert!(app.state.drag.is_none()); + } + #[test] fn clicking_workspace_switches_on_mouse_up() { let mut app = app_for_mouse_test(); @@ -1454,6 +1480,26 @@ mod tests { assert_eq!(snapshot.sidebar_width, Some(31)); } + #[test] + fn dragging_sidebar_bottom_divider_still_sets_manual_width() { + let mut app = app_for_mouse_test(); + let divider_col = app.state.view.sidebar_rect.x + app.state.view.sidebar_rect.width - 1; + let bottom_row = app.state.view.sidebar_rect.y + app.state.view.sidebar_rect.height - 1; + + app.handle_mouse(mouse( + MouseEventKind::Down(MouseButton::Left), + divider_col, + bottom_row, + )); + app.handle_mouse(mouse( + MouseEventKind::Drag(MouseButton::Left), + divider_col + 5, + bottom_row, + )); + + assert_eq!(app.state.sidebar_width, 31); + } + #[test] fn dragging_past_max_clamps_to_configured_max() { let mut app = app_for_mouse_test(); -- cgit v1.2.3