gardesk/garfield / cdb4a3a

Browse files

app: bookmark selection, double-click to enter

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
cdb4a3a94c382a8ff2d23ccff30ff98daacbc39e
Parents
d931fc0
Tree
a8a7b23

1 changed file

StatusFile+-
M garfield/src/app.rs 45 8
garfield/src/app.rsmodified
@@ -7,6 +7,7 @@ use gartk_core::{InputEvent, Key, Point, Rect, Theme};
7
 use gartk_render::{Renderer, Surface};
7
 use gartk_render::{Renderer, Surface};
8
 use gartk_x11::{Connection, EventLoop, EventLoopConfig, Window, WindowConfig};
8
 use gartk_x11::{Connection, EventLoop, EventLoopConfig, Window, WindowConfig};
9
 use std::path::PathBuf;
9
 use std::path::PathBuf;
10
+use std::time::Instant;
10
 use x11rb::protocol::xproto::{ConnectionExt, ImageFormat};
11
 use x11rb::protocol::xproto::{ConnectionExt, ImageFormat};
11
 
12
 
12
 /// Height of the breadcrumb bar.
13
 /// Height of the breadcrumb bar.
@@ -50,6 +51,10 @@ pub struct App {
50
     should_quit: bool,
51
     should_quit: bool,
51
     /// Pane divider resize in progress (split pane pointer path).
52
     /// Pane divider resize in progress (split pane pointer path).
52
     pane_resize_path: Option<Vec<bool>>,
53
     pane_resize_path: Option<Vec<bool>>,
54
+    /// Last click time for double-click detection.
55
+    last_click_time: Option<Instant>,
56
+    /// Last click position for double-click detection.
57
+    last_click_pos: Option<Point>,
53
 }
58
 }
54
 
59
 
55
 impl App {
60
 impl App {
@@ -175,6 +180,8 @@ impl App {
175
             help_modal,
180
             help_modal,
176
             should_quit: false,
181
             should_quit: false,
177
             pane_resize_path: None,
182
             pane_resize_path: None,
183
+            last_click_time: None,
184
+            last_click_pos: None,
178
         };
185
         };
179
 
186
 
180
         app.update_status_bar();
187
         app.update_status_bar();
@@ -329,9 +336,32 @@ impl App {
329
             }
336
             }
330
         }
337
         }
331
 
338
 
332
-        if let Some(pane) = self.focused_pane_mut() {
339
+        // Check for double-click to enter directory
333
-            if let Some(tab) = pane.active_tab_mut() {
340
+        let now = Instant::now();
334
-                tab.on_click(pos, modifiers);
341
+        let is_double_click = if let (Some(last_time), Some(last_pos)) = (self.last_click_time, self.last_click_pos) {
342
+            let elapsed = now.duration_since(last_time);
343
+            let distance = ((pos.x - last_pos.x).pow(2) + (pos.y - last_pos.y).pow(2)) as f64;
344
+            elapsed.as_millis() < 400 && distance.sqrt() < 5.0
345
+        } else {
346
+            false
347
+        };
348
+
349
+        // Update click tracking
350
+        self.last_click_time = Some(now);
351
+        self.last_click_pos = Some(pos);
352
+
353
+        if is_double_click {
354
+            // Double-click: enter the selected item
355
+            self.enter_selected();
356
+            // Clear click tracking to prevent triple-click
357
+            self.last_click_time = None;
358
+            self.last_click_pos = None;
359
+        } else {
360
+            // Single click: handle selection
361
+            if let Some(pane) = self.focused_pane_mut() {
362
+                if let Some(tab) = pane.active_tab_mut() {
363
+                    tab.on_click(pos, modifiers);
364
+                }
335
             }
365
             }
336
         }
366
         }
337
     }
367
     }
@@ -506,11 +536,15 @@ impl App {
506
                     return;
536
                     return;
507
                 }
537
                 }
508
                 Key::Char('d') | Key::Char('D') => {
538
                 Key::Char('d') | Key::Char('D') => {
509
-                    if let Some(pane) = self.focused_pane() {
539
+                    // Bookmark the selected item (must be a directory)
510
-                        if let Some(tab) = pane.active_tab() {
540
+                    let bookmark_path = self.focused_pane()
511
-                            let current = tab.current_path().clone();
541
+                        .and_then(|pane| pane.active_tab())
512
-                            self.sidebar.toggle_bookmark(&current);
542
+                        .and_then(|tab| tab.selected_entry())
513
-                        }
543
+                        .filter(|e| e.is_dir())
544
+                        .map(|e| e.path.clone());
545
+
546
+                    if let Some(path) = bookmark_path {
547
+                        self.sidebar.toggle_bookmark(&path);
514
                     }
548
                     }
515
                     return;
549
                     return;
516
                 }
550
                 }
@@ -1060,6 +1094,9 @@ impl App {
1060
         // Draw status bar
1094
         // Draw status bar
1061
         self.status_bar.render(&self.renderer)?;
1095
         self.status_bar.render(&self.renderer)?;
1062
 
1096
 
1097
+        // Draw toolbar tooltip overlay (on top of other UI)
1098
+        self.toolbar.render_tooltip_overlay(&self.renderer)?;
1099
+
1063
         // Draw help modal overlay (on top of everything)
1100
         // Draw help modal overlay (on top of everything)
1064
         self.help_modal.render(&self.renderer)?;
1101
         self.help_modal.render(&self.renderer)?;
1065
 
1102