3 days ago
implement imageviewer useradjustable setting in gtk4 implementation
application/main.c | file | annotate | diff | comparison | revisions | |
ui/gtk/image.c | file | annotate | diff | comparison | revisions | |
ui/gtk/image.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Sat Mar 29 18:17:01 2025 +0100 +++ b/application/main.c Sat Mar 29 20:03:25 2025 +0100 @@ -480,7 +480,7 @@ } ui_tab(obj, "Tab 5") { ui_button(obj, .label = "Test Button", .icon = "application-x-generic", .onclick = action_button); - ui_imageviewer(obj, .varname = "image", .style_class = "imageviewer", .contextmenu = menubuilder, .scrollarea = TRUE); + ui_imageviewer(obj, .varname = "image", .style_class = "imageviewer", .contextmenu = menubuilder, .scrollarea = TRUE, .useradjustable = TRUE); } ui_tab(obj, "Tab 6") {
--- a/ui/gtk/image.c Sat Mar 29 18:17:01 2025 +0100 +++ b/ui/gtk/image.c Sat Mar 29 20:03:25 2025 +0100 @@ -69,7 +69,7 @@ GtkWidget *drawingarea = gtk_drawing_area_new(); GtkWidget *toplevel; GtkWidget *widget = drawingarea; - + gtk_widget_set_size_request(drawingarea, 100, 100); #if GTK_MAJOR_VERSION < 4 @@ -102,6 +102,7 @@ imgviewer->adjustsize = args.adjustsize; imgviewer->autoscale = args.autoscale; imgviewer->useradjustable = args.useradjustable; + imgviewer->zoom_scale = 20; g_object_set_data_full(G_OBJECT(drawingarea), "uiimageviewer", imgviewer, (GDestroyNotify)imageviewer_destroy); @@ -128,12 +129,45 @@ imageviewer_draw, imgviewer, NULL); + + if(args.useradjustable) { + gtk_widget_set_focusable(drawingarea, TRUE); + } + + GtkEventController *scrollcontroller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_VERTICAL); + g_signal_connect(scrollcontroller, "scroll", G_CALLBACK(ui_imageviewer_scroll), imgviewer); + gtk_widget_add_controller(GTK_WIDGET(drawingarea), GTK_EVENT_CONTROLLER(scrollcontroller)); + + GtkGesture *drag = gtk_gesture_drag_new(); + g_signal_connect(drag, "drag-begin", G_CALLBACK(ui_imageviewer_drag_begin_cb), imgviewer); + g_signal_connect(drag, "drag-end", G_CALLBACK(ui_imageviewer_drag_end_cb), imgviewer); + g_signal_connect(drag, "drag-update", G_CALLBACK(ui_imageviewer_drag_update_cb), imgviewer); + gtk_widget_add_controller(GTK_WIDGET(drawingarea), GTK_EVENT_CONTROLLER(drag)); + #elif GTK_MAJOR_VERSION == 3 g_signal_connect( drawingarea, "draw", G_CALLBACK(imageviewer_draw), imgviewer); + + gtk_widget_add_events(eventbox, GDK_SCROLL_MASK); + + g_signal_connect( + eventbox, + "scroll-event", + G_CALLBACK(ui_imageviewer_scroll_event), + imgviewer); + g_signal_connect( + eventbox, + "button-press-event", + G_CALLBACK(ui_imageviewer_button_press_event), + imgviewer); + g_signal_connect( + eventbox, + "button-release-event", + G_CALLBACK(ui_imageviewer_button_release_event), + imgviewer); #endif @@ -141,7 +175,7 @@ UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, widget); ui_widget_set_contextmenu(widget, menu); } - + UI_APPLY_LAYOUT1(current, args); current->container->add(current->container, toplevel, TRUE); @@ -160,32 +194,31 @@ double dwidth = width; double dheight = height; + double scale = 1; if(imgviewer->autoscale) { - double scale = dwidth / dpixwidth; + scale = dwidth / dpixwidth; if(dpixheight * scale > dheight) { scale = dheight / dpixheight; } - - dpixwidth *= scale; - dpixheight *= scale; - double x = (dwidth - dpixwidth) / 2; - double y = (dheight - dpixheight) / 2; - cairo_translate(cr, x, y); - cairo_scale(cr, scale, scale); } else { - double x = (dwidth - dpixwidth) / 2; - double y = (dheight - dpixheight) / 2; - if(x < 0) { - x = 0; - } - if(y < 0) { - y = 0; - } - cairo_translate(cr, (int)x, (int)y); + scale = 1 + ((double)imgviewer->zoom / (double)imgviewer->zoom_scale); } + + dpixwidth *= scale; + dpixheight *= scale; + double x = (dwidth - dpixwidth) / 2; + double y = (dheight - dpixheight) / 2; + + x += imgviewer->transx; + y += imgviewer->transy; + + cairo_translate(cr, x, y); + cairo_scale(cr, scale, scale); gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); + + imgviewer->prev_scale = scale; } void* ui_imageviewer_get(UiGeneric *g) { @@ -240,3 +273,86 @@ return 0; } + +#if GTK_MAJOR_VERSION >= 4 + +gboolean ui_imageviewer_scroll( + GtkEventControllerScroll *widget, + gdouble dx, + gdouble dy, + gpointer userdata) +{ + UiImageViewer *imgviewer = userdata; + if(imgviewer->useradjustable) { + imgviewer->zoom -= dy; + if(imgviewer->zoom < -imgviewer->zoom_scale) { + imgviewer->zoom = -imgviewer->zoom_scale; + } + gtk_widget_queue_draw(imgviewer->widget); + return TRUE; + } + return FALSE; +} + +void ui_imageviewer_drag_begin_cb( + GtkGestureDrag* self, + gdouble start_x, + gdouble start_y, + gpointer userdata) +{ + UiImageViewer *imgviewer = userdata; + imgviewer->begin_transx = imgviewer->transx; + imgviewer->begin_transy = imgviewer->transy; +} + +void ui_imageviewer_drag_end_cb( + GtkGestureDrag* self, + gdouble x, + gdouble y, + gpointer userdata) +{ + +} + +void ui_imageviewer_drag_update_cb( + GtkGestureDrag* self, + gdouble x, + gdouble y, + gpointer userdata) +{ + UiImageViewer *imgviewer = userdata; + if(imgviewer->useradjustable) { + imgviewer->transx = imgviewer->begin_transx + x; + imgviewer->transy = imgviewer->begin_transy + y; + gtk_widget_queue_draw(imgviewer->widget); + } +} + +#else + +gboolean ui_imageviewer_scroll_event( + GtkWidget *widget, + GdkEventScroll event, + gpointer userdata) +{ + printf("scroll event\n"); + return FALSE; +} + +gboolean ui_imageviewer_button_press_event( + GtkWidget *widget, + GdkEventButton event, + gpointer userdata) +{ + printf("button pressed\n"); +} + +gboolean ui_imageviewer_button_release_event( + GtkWidget *widget, + GdkEventButton event, + gpointer userdata) +{ + printf("button released\n"); +} + +#endif
--- a/ui/gtk/image.h Sat Mar 29 18:17:01 2025 +0100 +++ b/ui/gtk/image.h Sat Mar 29 20:03:25 2025 +0100 @@ -47,6 +47,14 @@ UiBool adjustsize; UiBool useradjustable; GdkPixbuf *pixbuf; + + int zoom_scale; + int transx; + int transy; + int begin_transx; + int begin_transy; + int zoom; + double prev_scale; } UiImageViewer; void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height); @@ -55,6 +63,51 @@ const char* ui_imageviewer_get_type(UiGeneric *g); int ui_imageviewer_set(UiGeneric *g, void *value, const char *type); +#if GTK_MAJOR_VERSION >= 4 + +gboolean ui_imageviewer_scroll( + GtkEventControllerScroll *widget, + gdouble dx, + gdouble dy, + gpointer userdata); + +void ui_imageviewer_drag_begin_cb( + GtkGestureDrag* self, + gdouble start_x, + gdouble start_y, + gpointer userdata); + +void ui_imageviewer_drag_end_cb( + GtkGestureDrag* self, + gdouble x, + gdouble y, + gpointer userdata); + +void ui_imageviewer_drag_update_cb( + GtkGestureDrag* self, + gdouble x, + gdouble y, + gpointer userdata); + +#else + +gboolean ui_imageviewer_scroll_event( + GtkWidget *widget, + GdkEventScroll event, + gpointer userdata); + +gboolean ui_imageviewer_button_press_event( + GtkWidget *widget, + GdkEventButton event, + gpointer userdata); + +gboolean ui_imageviewer_button_release_event( + GtkWidget *widget, + GdkEventButton event, + gpointer userdata); + +#endif + #ifdef __cplusplus } #endif