gardesk/garfield / 63af87c

Browse files

grid: add icon size toolbar buttons and Ctrl++/- shortcuts

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
63af87c98c6045ee43936e5eb531199981ea49bc
Parents
281c04e
Tree
5150e8f

4 changed files

StatusFile+-
M garfield/src/ui/grid_view.rs 21 2
M garfield/src/ui/mod.rs 1 1
M garfield/src/ui/tab.rs 21 1
M garfield/src/ui/toolbar.rs 92 0
garfield/src/ui/grid_view.rsmodified
@@ -48,12 +48,21 @@ impl IconSize {
48
         }
48
         }
49
     }
49
     }
50
 
50
 
51
-    /// Cycle to the next size.
51
+    /// Cycle to the next (larger) size.
52
     pub fn next(&self) -> Self {
52
     pub fn next(&self) -> Self {
53
         match self {
53
         match self {
54
             IconSize::Small => IconSize::Medium,
54
             IconSize::Small => IconSize::Medium,
55
             IconSize::Medium => IconSize::Large,
55
             IconSize::Medium => IconSize::Large,
56
-            IconSize::Large => IconSize::Small,
56
+            IconSize::Large => IconSize::Large, // Already at max
57
+        }
58
+    }
59
+
60
+    /// Cycle to the previous (smaller) size.
61
+    pub fn prev(&self) -> Self {
62
+        match self {
63
+            IconSize::Small => IconSize::Small, // Already at min
64
+            IconSize::Medium => IconSize::Small,
65
+            IconSize::Large => IconSize::Medium,
57
         }
66
         }
58
     }
67
     }
59
 
68
 
@@ -168,6 +177,16 @@ impl GridView {
168
         self.set_icon_size(self.icon_size.next());
177
         self.set_icon_size(self.icon_size.next());
169
     }
178
     }
170
 
179
 
180
+    /// Increase icon size (to next larger).
181
+    pub fn increase_icon_size(&mut self) {
182
+        self.set_icon_size(self.icon_size.next());
183
+    }
184
+
185
+    /// Decrease icon size (to next smaller).
186
+    pub fn decrease_icon_size(&mut self) {
187
+        self.set_icon_size(self.icon_size.prev());
188
+    }
189
+
171
     /// Set the entries to display.
190
     /// Set the entries to display.
172
     pub fn set_entries(&mut self, entries: Vec<FileEntry>) {
191
     pub fn set_entries(&mut self, entries: Vec<FileEntry>) {
173
         self.entries = entries;
192
         self.entries = entries;
garfield/src/ui/mod.rsmodified
@@ -22,7 +22,7 @@ pub use context_menu::{ContextMenu, ContextMenuAction, ContextType};
22
 pub use dialog::{ConfirmDialog, ConflictAction, ConflictDialog, DialogResult, InputDialog, InputResult, ProgressDialog, ProgressInfo};
22
 pub use dialog::{ConfirmDialog, ConflictAction, ConflictDialog, DialogResult, InputDialog, InputResult, ProgressDialog, ProgressInfo};
23
 pub use breadcrumb::Breadcrumb;
23
 pub use breadcrumb::Breadcrumb;
24
 pub use column_view::{ColumnClickResult, ColumnView};
24
 pub use column_view::{ColumnClickResult, ColumnView};
25
-pub use grid_view::GridView;
25
+pub use grid_view::{GridView, IconSize};
26
 pub use help_modal::HelpModal;
26
 pub use help_modal::HelpModal;
27
 pub use list_view::ListView;
27
 pub use list_view::ListView;
28
 pub use pane::Pane;
28
 pub use pane::Pane;
garfield/src/ui/tab.rsmodified
@@ -1,7 +1,7 @@
1
 //! Tab state for a single directory view.
1
 //! Tab state for a single directory view.
2
 
2
 
3
 use crate::core::{read_directory, rename_path, sort_entries, FileEntry, History, SortDirection, SortOrder};
3
 use crate::core::{read_directory, rename_path, sort_entries, FileEntry, History, SortDirection, SortOrder};
4
-use crate::ui::{ColumnClickResult, ColumnView, GridView, ListView};
4
+use crate::ui::{ColumnClickResult, ColumnView, GridView, IconSize, ListView};
5
 use gartk_core::{Key, Modifiers, Point, Rect};
5
 use gartk_core::{Key, Modifiers, Point, Rect};
6
 use gartk_render::Renderer;
6
 use gartk_render::Renderer;
7
 use std::path::PathBuf;
7
 use std::path::PathBuf;
@@ -126,6 +126,26 @@ impl Tab {
126
         self.grid_view.cycle_icon_size();
126
         self.grid_view.cycle_icon_size();
127
     }
127
     }
128
 
128
 
129
+    /// Get the current icon size for grid view.
130
+    pub fn icon_size(&self) -> IconSize {
131
+        self.grid_view.icon_size()
132
+    }
133
+
134
+    /// Set the icon size for grid view.
135
+    pub fn set_icon_size(&mut self, size: IconSize) {
136
+        self.grid_view.set_icon_size(size);
137
+    }
138
+
139
+    /// Increase icon size in grid view.
140
+    pub fn increase_icon_size(&mut self) {
141
+        self.grid_view.increase_icon_size();
142
+    }
143
+
144
+    /// Decrease icon size in grid view.
145
+    pub fn decrease_icon_size(&mut self) {
146
+        self.grid_view.decrease_icon_size();
147
+    }
148
+
129
     /// Get history reference.
149
     /// Get history reference.
130
     pub fn history(&self) -> &History {
150
     pub fn history(&self) -> &History {
131
         &self.history
151
         &self.history
garfield/src/ui/toolbar.rsmodified
@@ -49,6 +49,12 @@ pub enum ToolbarAction {
49
     Trash,
49
     Trash,
50
     /// Create new folder.
50
     /// Create new folder.
51
     NewFolder,
51
     NewFolder,
52
+    /// Small icon size (grid view).
53
+    IconSizeSmall,
54
+    /// Medium icon size (grid view).
55
+    IconSizeMedium,
56
+    /// Large icon size (grid view).
57
+    IconSizeLarge,
52
 }
58
 }
53
 
59
 
54
 /// A toolbar button.
60
 /// A toolbar button.
@@ -65,6 +71,7 @@ pub struct Toolbar {
65
     buttons: Vec<ToolbarButton>,
71
     buttons: Vec<ToolbarButton>,
66
     hovered: Option<usize>,
72
     hovered: Option<usize>,
67
     active_view: ToolbarAction,
73
     active_view: ToolbarAction,
74
+    active_icon_size: ToolbarAction,
68
     can_go_back: bool,
75
     can_go_back: bool,
69
     can_go_forward: bool,
76
     can_go_forward: bool,
70
     has_selection: bool,
77
     has_selection: bool,
@@ -79,6 +86,7 @@ impl Toolbar {
79
             buttons: Vec::new(),
86
             buttons: Vec::new(),
80
             hovered: None,
87
             hovered: None,
81
             active_view: ToolbarAction::ViewList,
88
             active_view: ToolbarAction::ViewList,
89
+            active_icon_size: ToolbarAction::IconSizeMedium,
82
             can_go_back: false,
90
             can_go_back: false,
83
             can_go_forward: false,
91
             can_go_forward: false,
84
             has_selection: false,
92
             has_selection: false,
@@ -99,6 +107,11 @@ impl Toolbar {
99
         self.active_view = action;
107
         self.active_view = action;
100
     }
108
     }
101
 
109
 
110
+    /// Set active icon size.
111
+    pub fn set_active_icon_size(&mut self, action: ToolbarAction) {
112
+        self.active_icon_size = action;
113
+    }
114
+
102
     /// Set navigation state.
115
     /// Set navigation state.
103
     pub fn set_nav_state(&mut self, can_back: bool, can_forward: bool) {
116
     pub fn set_nav_state(&mut self, can_back: bool, can_forward: bool) {
104
         self.can_go_back = can_back;
117
         self.can_go_back = can_back;
@@ -154,6 +167,24 @@ impl Toolbar {
154
 
167
 
155
         x += GROUP_SEPARATOR as i32;
168
         x += GROUP_SEPARATOR as i32;
156
 
169
 
170
+        // Icon size buttons (for grid view)
171
+        let size_buttons = [
172
+            (ToolbarAction::IconSizeSmall, "Small Icons (Ctrl+-)"),
173
+            (ToolbarAction::IconSizeMedium, "Medium Icons"),
174
+            (ToolbarAction::IconSizeLarge, "Large Icons (Ctrl++)"),
175
+        ];
176
+
177
+        for (action, tooltip) in size_buttons {
178
+            self.buttons.push(ToolbarButton {
179
+                action,
180
+                bounds: Rect::new(x, y, BUTTON_SIZE, BUTTON_SIZE),
181
+                tooltip,
182
+            });
183
+            x += BUTTON_SIZE as i32 + BUTTON_PADDING as i32;
184
+        }
185
+
186
+        x += GROUP_SEPARATOR as i32;
187
+
157
         // Tab/pane buttons
188
         // Tab/pane buttons
158
         let pane_buttons = [
189
         let pane_buttons = [
159
             (ToolbarAction::NewTab, "New Tab (Ctrl+T)"),
190
             (ToolbarAction::NewTab, "New Tab (Ctrl+T)"),
@@ -323,6 +354,9 @@ impl Toolbar {
323
             ToolbarAction::ViewList | ToolbarAction::ViewGrid | ToolbarAction::ViewColumns => {
354
             ToolbarAction::ViewList | ToolbarAction::ViewGrid | ToolbarAction::ViewColumns => {
324
                 button.action == self.active_view
355
                 button.action == self.active_view
325
             }
356
             }
357
+            ToolbarAction::IconSizeSmall | ToolbarAction::IconSizeMedium | ToolbarAction::IconSizeLarge => {
358
+                button.action == self.active_icon_size
359
+            }
326
             _ => false,
360
             _ => false,
327
         };
361
         };
328
         let is_disabled = match button.action {
362
         let is_disabled = match button.action {
@@ -330,6 +364,10 @@ impl Toolbar {
330
             ToolbarAction::GoForward => !self.can_go_forward,
364
             ToolbarAction::GoForward => !self.can_go_forward,
331
             ToolbarAction::Copy | ToolbarAction::Cut | ToolbarAction::Trash => !self.has_selection,
365
             ToolbarAction::Copy | ToolbarAction::Cut | ToolbarAction::Trash => !self.has_selection,
332
             ToolbarAction::Paste => !self.has_clipboard,
366
             ToolbarAction::Paste => !self.has_clipboard,
367
+            // Icon size buttons disabled when not in grid view
368
+            ToolbarAction::IconSizeSmall | ToolbarAction::IconSizeMedium | ToolbarAction::IconSizeLarge => {
369
+                self.active_view != ToolbarAction::ViewGrid
370
+            }
333
             _ => false,
371
             _ => false,
334
         };
372
         };
335
 
373
 
@@ -364,6 +402,9 @@ impl Toolbar {
364
             ToolbarAction::ViewList => self.draw_list_icon(renderer, cx, cy, icon_color)?,
402
             ToolbarAction::ViewList => self.draw_list_icon(renderer, cx, cy, icon_color)?,
365
             ToolbarAction::ViewGrid => self.draw_grid_icon(renderer, cx, cy, icon_color)?,
403
             ToolbarAction::ViewGrid => self.draw_grid_icon(renderer, cx, cy, icon_color)?,
366
             ToolbarAction::ViewColumns => self.draw_columns_icon(renderer, cx, cy, icon_color)?,
404
             ToolbarAction::ViewColumns => self.draw_columns_icon(renderer, cx, cy, icon_color)?,
405
+            ToolbarAction::IconSizeSmall => self.draw_size_small_icon(renderer, cx, cy, icon_color)?,
406
+            ToolbarAction::IconSizeMedium => self.draw_size_medium_icon(renderer, cx, cy, icon_color)?,
407
+            ToolbarAction::IconSizeLarge => self.draw_size_large_icon(renderer, cx, cy, icon_color)?,
367
             ToolbarAction::NewTab => self.draw_new_tab_icon(renderer, cx, cy, icon_color)?,
408
             ToolbarAction::NewTab => self.draw_new_tab_icon(renderer, cx, cy, icon_color)?,
368
             ToolbarAction::SplitHorizontal => self.draw_split_h_icon(renderer, cx, cy, icon_color)?,
409
             ToolbarAction::SplitHorizontal => self.draw_split_h_icon(renderer, cx, cy, icon_color)?,
369
             ToolbarAction::SplitVertical => self.draw_split_v_icon(renderer, cx, cy, icon_color)?,
410
             ToolbarAction::SplitVertical => self.draw_split_v_icon(renderer, cx, cy, icon_color)?,
@@ -444,6 +485,57 @@ impl Toolbar {
444
         Ok(())
485
         Ok(())
445
     }
486
     }
446
 
487
 
488
+    fn draw_size_small_icon(&self, renderer: &Renderer, cx: f64, cy: f64, color: gartk_core::Color) -> Result<()> {
489
+        // Small grid of tiny squares (4x4)
490
+        let size = 2.0;
491
+        let gap = 1.5;
492
+        let total = 4.0 * size + 3.0 * gap;
493
+        let start = -total / 2.0;
494
+        for row in 0..4 {
495
+            for col in 0..4 {
496
+                let x = cx + start + (col as f64) * (size + gap);
497
+                let y = cy + start + (row as f64) * (size + gap);
498
+                let rect = Rect::new(x as i32, y as i32, size as u32, size as u32);
499
+                renderer.fill_rect(rect, color)?;
500
+            }
501
+        }
502
+        Ok(())
503
+    }
504
+
505
+    fn draw_size_medium_icon(&self, renderer: &Renderer, cx: f64, cy: f64, color: gartk_core::Color) -> Result<()> {
506
+        // Medium grid of squares (3x3)
507
+        let size = 3.0;
508
+        let gap = 2.0;
509
+        let total = 3.0 * size + 2.0 * gap;
510
+        let start = -total / 2.0;
511
+        for row in 0..3 {
512
+            for col in 0..3 {
513
+                let x = cx + start + (col as f64) * (size + gap);
514
+                let y = cy + start + (row as f64) * (size + gap);
515
+                let rect = Rect::new(x as i32, y as i32, size as u32, size as u32);
516
+                renderer.fill_rect(rect, color)?;
517
+            }
518
+        }
519
+        Ok(())
520
+    }
521
+
522
+    fn draw_size_large_icon(&self, renderer: &Renderer, cx: f64, cy: f64, color: gartk_core::Color) -> Result<()> {
523
+        // Large grid of squares (2x2)
524
+        let size = 5.0;
525
+        let gap = 2.0;
526
+        let total = 2.0 * size + gap;
527
+        let start = -total / 2.0;
528
+        for row in 0..2 {
529
+            for col in 0..2 {
530
+                let x = cx + start + (col as f64) * (size + gap);
531
+                let y = cy + start + (row as f64) * (size + gap);
532
+                let rect = Rect::new(x as i32, y as i32, size as u32, size as u32);
533
+                renderer.fill_rect(rect, color)?;
534
+            }
535
+        }
536
+        Ok(())
537
+    }
538
+
447
     fn draw_new_tab_icon(&self, renderer: &Renderer, cx: f64, cy: f64, color: gartk_core::Color) -> Result<()> {
539
     fn draw_new_tab_icon(&self, renderer: &Renderer, cx: f64, cy: f64, color: gartk_core::Color) -> Result<()> {
448
         // Plus sign
540
         // Plus sign
449
         let size = 8.0;
541
         let size = 8.0;