3 days ago
allow autoscale + useradjustable in imageviewer (GTK)
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 | |
ui/gtk/widget.c | file | annotate | diff | comparison | revisions | |
ui/ui/image.h | file | annotate | diff | comparison | revisions | |
ui/ui/widget.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Sun Mar 30 10:14:27 2025 +0200 +++ b/application/main.c Sun Mar 30 10:37:35 2025 +0200 @@ -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, .useradjustable = TRUE); + ui_imageviewer(obj, .varname = "image", .style_class = "imageviewer", .contextmenu = menubuilder, .scrollarea = TRUE, .useradjustable = TRUE, .autoscale = TRUE); } ui_tab(obj, "Tab 6") {
--- a/ui/gtk/image.c Sun Mar 30 10:14:27 2025 +0200 +++ b/ui/gtk/image.c Sun Mar 30 10:37:35 2025 +0200 @@ -81,7 +81,7 @@ if(args.scrollarea) { toplevel = SCROLLEDWINDOW_NEW(); SCROLLEDWINDOW_SET_CHILD(toplevel, widget); - args.adjustsize = TRUE; + args.adjustwidgetsize = TRUE; } else { toplevel = widget; } @@ -99,7 +99,7 @@ imgviewer->padding_top = args.image_padding_top; imgviewer->padding_bottom = args.image_padding_bottom; } - imgviewer->adjustsize = args.adjustsize; + imgviewer->adjustwidgetsize = args.adjustwidgetsize; imgviewer->autoscale = args.autoscale; imgviewer->useradjustable = args.useradjustable; imgviewer->zoom_scale = 20; @@ -182,6 +182,44 @@ return toplevel; } +static void imageviewer_reset(UiImageViewer *imgviewer) { + imgviewer->zoom = 0; + imgviewer->isautoscaled = FALSE; + imgviewer->transx = 0; + imgviewer->transy; + imgviewer->begin_transx = 0; + imgviewer->begin_transy = 0; + imgviewer->scale = 1; +} + +UIWIDGET ui_imageviewer_reset(UIWIDGET w) { + UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer"); + if(imgviewer) { + imageviewer_reset(imgviewer); + gtk_widget_queue_draw(w); + } +} + +UIWIDGET ui_imageviewer_set_autoscale(UIWIDGET w, UiBool set) { + UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer"); + if(imgviewer) { + imgviewer->autoscale = set; + } +} + +UIWIDGET ui_imageviewer_set_adjustwidgetsize(UIWIDGET w, UiBool set) { + UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer"); + if(imgviewer) { + imgviewer->adjustwidgetsize = set; + } +} + +UIWIDGET ui_imageviewer_set_useradjustable(UIWIDGET w, UiBool set) { + UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer"); + if(imgviewer) { + imgviewer->useradjustable = set; + } +} void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height) { if(!imgviewer->pixbuf) { @@ -195,12 +233,25 @@ double dwidth = width; double dheight = height; double scale = 1; - if(imgviewer->autoscale) { - scale = dwidth / dpixwidth; - if(dpixheight * scale > dheight) { - scale = dheight / dpixheight; + // if autoscale is enabled, scale the image to fill available space + // if useradjustable is also enabled, the autoscaling is only done once + if(imgviewer->autoscale && imgviewer->scale != 0) { + if(!imgviewer->isautoscaled) { + scale = dwidth / dpixwidth; + if(dpixheight * scale > dheight) { + scale = dheight / dpixheight; + } + + if(imgviewer->useradjustable) { + imgviewer->isautoscaled = TRUE; + } + + imgviewer->scale = scale; + } else { + scale = imgviewer->scale; } } else { + // user-adjusted scaling scale = 1 + ((double)imgviewer->zoom / (double)imgviewer->zoom_scale); } @@ -217,8 +268,6 @@ gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); - - imgviewer->prev_scale = scale; } void* ui_imageviewer_get(UiGeneric *g) { @@ -241,12 +290,14 @@ UiImageViewer *imgviewer = g->obj; g->value = pixbuf; + imageviewer_reset(imgviewer); + if(imgviewer->pixbuf) { g_object_unref(imgviewer->pixbuf); } imgviewer->pixbuf = pixbuf; - if(imgviewer->adjustsize) { + if(imgviewer->adjustwidgetsize && !imgviewer->autoscale) { int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); gtk_widget_set_size_request(imgviewer->widget, width, height); @@ -288,6 +339,7 @@ if(imgviewer->zoom < -imgviewer->zoom_scale) { imgviewer->zoom = -imgviewer->zoom_scale; } + imgviewer->scale = 0; // disable autoscale gtk_widget_queue_draw(imgviewer->widget); return TRUE; }
--- a/ui/gtk/image.h Sun Mar 30 10:14:27 2025 +0200 +++ b/ui/gtk/image.h Sun Mar 30 10:37:35 2025 +0200 @@ -44,7 +44,7 @@ int padding_top; int padding_bottom; UiBool autoscale; - UiBool adjustsize; + UiBool adjustwidgetsize; UiBool useradjustable; GdkPixbuf *pixbuf; @@ -54,7 +54,8 @@ int begin_transx; int begin_transy; int zoom; - double prev_scale; + UiBool isautoscaled; + double scale; } UiImageViewer; void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height);
--- a/ui/gtk/widget.c Sun Mar 30 10:14:27 2025 +0200 +++ b/ui/gtk/widget.c Sun Mar 30 10:37:35 2025 +0200 @@ -54,3 +54,7 @@ void ui_widget_set_size(UIWIDGET w, int width, int height) { gtk_widget_set_size_request(w, width, height); } + +void ui_widget_redraw(UIWIDGET w) { + gtk_widget_queue_draw(w); +}
--- a/ui/ui/image.h Sun Mar 30 10:14:27 2025 +0200 +++ b/ui/ui/image.h Sun Mar 30 10:37:35 2025 +0200 @@ -51,7 +51,7 @@ UiBool scrollarea; UiBool autoscale; - UiBool adjustsize; + UiBool adjustwidgetsize; UiBool useradjustable; int image_padding; int image_padding_left; @@ -67,6 +67,11 @@ UIEXPORT UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args); +UIEXPORT UIWIDGET ui_imageviewer_reset(UIWIDGET w); +UIEXPORT UIWIDGET ui_imageviewer_set_autoscale(UIWIDGET w, UiBool set); +UIEXPORT UIWIDGET ui_imageviewer_set_adjustwidgetsize(UIWIDGET w, UiBool set); +UIEXPORT UIWIDGET ui_imageviewer_set_useradjustable(UIWIDGET w, UiBool set); + UIEXPORT int ui_image_load_file(UiGeneric *obj, const char *path); #ifdef __cplusplus
--- a/ui/ui/widget.h Sun Mar 30 10:14:27 2025 +0200 +++ b/ui/ui/widget.h Sun Mar 30 10:37:35 2025 +0200 @@ -70,6 +70,7 @@ #define ui_separator(obj, ...) ui_separator_create(obj, &(UiWidgetArgs){ __VA_ARGS__ } ) UIEXPORT void ui_widget_set_size(UIWIDGET w, int width, int height); +UIEXPORT void ui_widget_redraw(UIWIDGET w); #ifdef __cplusplus