allow autoscale + useradjustable in imageviewer (GTK)

3 days ago

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 30 Mar 2025 10:37:35 +0200 (3 days ago)
changeset 532
80a6d8923d75
parent 531
9068a5c7caf6
child 533
951b92ce3708

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

mercurial