]> uap-core.de Git - mizunara.git/commitdiff
add motion handler to MzFilesView and highlight items on mouseover
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 26 Jan 2025 14:53:23 +0000 (15:53 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 26 Jan 2025 14:53:23 +0000 (15:53 +0100)
mizunara/gtk-filesview.c
mizunara/gtk-filesview.h

index cf13919ececd7040699728f940f4e375ca453690..fa7e8202de562b85705087bf313fa38ae4513779 100644 (file)
@@ -51,6 +51,11 @@ static void drag_update_cb(
         gdouble y,
         gpointer user_data);
 
+static void motion_cb(
+        GtkEventControllerMotion* self,
+        gdouble x,
+        gdouble y,
+        gpointer user_data);
 
 static void mz_files_view_class_init(MzFilesViewClass *klass) {
     printf("mz_files_view_class_init\n");
@@ -69,12 +74,20 @@ static void mz_files_view_init(MzFilesView *self) {
     
     self->current_width = 0;
     
+    self->highlight = FALSE;
+    self->highlight_col = -1;
+    self->highlight_row = -1;
+    
     // event handler
     GtkGesture *drag = gtk_gesture_drag_new();
     g_signal_connect(drag, "drag-begin", G_CALLBACK(drag_begin_cb), self);
     g_signal_connect(drag, "drag-end", G_CALLBACK(drag_end_cb), self);
     g_signal_connect(drag, "drag-update", G_CALLBACK(drag_update_cb), self);
     gtk_widget_add_controller(GTK_WIDGET(self), GTK_EVENT_CONTROLLER(drag));
+    
+    GtkEventController *motion = gtk_event_controller_motion_new();
+    g_signal_connect(motion, "motion", G_CALLBACK(motion_cb), self);
+    gtk_widget_add_controller(GTK_WIDGET(self), motion);
 }
 
 void mz_files_view_dispose(GObject *object) {
@@ -95,6 +108,46 @@ MzFilesView* mz_files_view_new(void) {
 #define MZ_GRID_VIEW_SELECTION_WIDTH 165
 #define MZ_GRID_VIEW_SELECTION_HEIGHT 165
 
+static int point2item(MzFilesView *view, int x, int y, int *out_col, int *out_row) {
+    int width = view->current_width;
+    width -= MZ_GRID_VIEW_PADDING_LEFT + MZ_GRID_VIEW_PADDING_RIGHT;
+    
+    int item_width = 180;
+    int item_height = 170;
+    
+    int highlight_width =  MZ_GRID_VIEW_SELECTION_WIDTH; 
+    int highlight_height = MZ_GRID_VIEW_SELECTION_HEIGHT;
+    int highlight_rect_offset_x = (item_width - highlight_width) / 2;
+    int highlight_rect_offset_y = (item_height - highlight_height) / 2;
+    
+    int col;
+    if(x <= MZ_GRID_VIEW_PADDING_LEFT) {
+        col = -1;
+    } else {
+        col = (x - MZ_GRID_VIEW_PADDING_LEFT) / item_width;
+    }
+    
+    if(col >= 0) {
+        int col_start_pos = MZ_GRID_VIEW_PADDING_LEFT + col*item_width + highlight_rect_offset_x;
+        if(x < col_start_pos || x > col_start_pos + highlight_width) {
+            col = -1;
+        }
+    }
+
+    int row = y / item_height;
+    int row_start_pos = MZ_GRID_VIEW_PADDING_TOP + row*item_height + highlight_rect_offset_y;
+    if(y < row_start_pos || y > row_start_pos + highlight_height) {
+        row = -1;
+    }
+    
+    if(col >= 0 && row >= 0) {
+        *out_col = col;
+        *out_row = row;
+        return 1;
+    }
+    return 0;
+}
+
 void mz_files_view_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) {
     MzFilesView *view = (MzFilesView*)widget;
     //printf("MzFilesView snapshot\n");
@@ -159,7 +212,7 @@ void mz_files_view_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) {
         highlight_clip.corner[i].height = 16;
     }
     
-    int handle_selection = view->drag || view->update_selection;
+    int handle_selection = view->drag || view->update_selection || view->highlight;
     
     if(highlight_col_start >= 0) {
         // check minimum pos
@@ -211,8 +264,9 @@ void mz_files_view_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) {
         for(size_t i=0;i<view->numitems;i++) {
             int base_x = x * item_width + MZ_GRID_VIEW_PADDING_LEFT;
             int base_y = y * item_height + MZ_GRID_VIEW_PADDING_TOP;
-            if(handle_selection && x >= highlight_col_start && x <= highlight_col_end && y >= highlight_row_start && y <= highlight_row_end) {
-                if(view->drag) {
+            int highlight_item = x == view->highlight_col && y == view->highlight_row;
+            if(handle_selection && (highlight_item || (x >= highlight_col_start && x <= highlight_col_end && y >= highlight_row_start && y <= highlight_row_end))) {
+                if(view->drag || (highlight_item && !view->update_selection)) {
                     highlight_rect.origin.x = base_x + highlight_rect_offset_x;
                     highlight_rect.origin.y = base_y + highlight_rect_offset_y;
 
@@ -445,6 +499,38 @@ static void drag_update_cb(
 }
 
 
+static void motion_cb(
+        GtkEventControllerMotion* self,
+        gdouble x,
+        gdouble y,
+        gpointer user_data)
+{
+    MzFilesView *view = user_data;
+    int col, row;
+    int update = FALSE;
+    if(point2item(view, x, y, &col, &row)) {
+        if(view->highlight_col != col || view->highlight_row != row) {
+            update = TRUE;
+            view->highlight = TRUE;
+            view->highlight_col = col;
+            view->highlight_row = row;
+        }
+    } else {
+        if(view->highlight) {
+            view->highlight = FALSE;
+            view->highlight_col = -1;
+            view->highlight_row = -1;
+            update = TRUE;
+        }
+        view->highlight_col = -1;
+        view->highlight_row = -1;
+    }
+    if(update) {
+        gtk_widget_queue_draw(GTK_WIDGET(view));
+    }
+}
+
+
 /* -------------------------- public -------------------------- */
 
 void mz_update_files_view(MzFilesView *view, FilesSection *sections, size_t numsections) {
index 391fb27cd3ad2fc08b279e11addeddee579d79fd..d5a6ee4ed222b807be496eacb24bedddfb2b0470 100644 (file)
@@ -63,6 +63,9 @@ typedef struct MzFilesView {
     MzViewSection *sections;
     size_t numsections;
     
+    int highlight_col;
+    int highlight_row;
+    
     int drag_start_x;
     int drag_start_y;
     int drag_width;
@@ -72,6 +75,7 @@ typedef struct MzFilesView {
     int drag_col;
     int drag_row;
     bool drag;
+    bool highlight;
     
     int update_selection; // 0: no update, 1: set selection, 2: add selection
 } MzFilesView;