@@ -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; |