From: Olaf Wintermann Date: Sun, 26 Jan 2025 14:53:23 +0000 (+0100) Subject: add motion handler to MzFilesView and highlight items on mouseover X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=8ab9c9e2bd917970171fd21223519230730f8857;p=mizunara.git add motion handler to MzFilesView and highlight items on mouseover --- diff --git a/mizunara/gtk-filesview.c b/mizunara/gtk-filesview.c index cf13919..fa7e820 100644 --- a/mizunara/gtk-filesview.c +++ b/mizunara/gtk-filesview.c @@ -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;inumitems;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) { diff --git a/mizunara/gtk-filesview.h b/mizunara/gtk-filesview.h index 391fb27..d5a6ee4 100644 --- a/mizunara/gtk-filesview.h +++ b/mizunara/gtk-filesview.h @@ -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;