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");
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) {
#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");
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
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;
}
+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) {