gtk4-demo: Polish the image scaling demo
authorMatthias Clasen <mclasen@redhat.com>
Mon, 13 Mar 2023 12:10:52 +0000 (13:10 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 14 Mar 2023 04:36:08 +0000 (05:36 +0100)
Make the scale binding bidirectional again, fix up
the ranges and the sensitivity of the actions, and
add a mark for the unscaled position.

demos/gtk-demo/demo3widget.c
demos/gtk-demo/menu.c

index 9cab3bc2ae72daaf4128f538de762f7c5cbf893e..4eedc949f0f3cfafe6e4b1d9cabadf9f55729713 100644 (file)
@@ -135,6 +135,8 @@ demo3_widget_size_allocate (GtkWidget *widget,
   gtk_popover_present (GTK_POPOVER (self->menu));
 }
 
+static void update_actions (Demo3Widget *self);
+
 static void
 demo3_widget_set_property (GObject      *object,
                            guint         prop_id,
@@ -153,6 +155,7 @@ demo3_widget_set_property (GObject      *object,
 
     case PROP_SCALE:
       self->scale = g_value_get_float (value);
+      update_actions (self);
       gtk_widget_queue_resize (GTK_WIDGET (object));
       break;
 
@@ -219,6 +222,14 @@ pressed_cb (GtkGestureClick *gesture,
   gtk_popover_popup (GTK_POPOVER (self->menu));
 }
 
+static void
+update_actions (Demo3Widget *self)
+{
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
+}
+
 static void
 zoom_cb (GtkWidget  *widget,
          const char *action_name,
@@ -228,15 +239,13 @@ zoom_cb (GtkWidget  *widget,
   float scale;
 
   if (g_str_equal (action_name, "zoom.in"))
-    scale = MIN (10, self->scale * M_SQRT2);
+    scale = MIN (1024., self->scale * M_SQRT2);
   else if (g_str_equal (action_name, "zoom.out"))
-    scale = MAX (0.01, self->scale / M_SQRT2);
-  else
+    scale = MAX (1./1024., self->scale / M_SQRT2);
+  else if (g_str_equal (action_name, "zoom.reset"))
     scale = 1.0;
-
-  gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
-  gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
-  gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
+  else
+    g_assert_not_reached ();
 
   g_object_set (widget, "scale", scale, NULL);
 }
@@ -275,7 +284,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
 
   g_object_class_install_property (object_class, PROP_SCALE,
       g_param_spec_float ("scale", NULL, NULL,
-                          0.0, 1024.0, 1.0,
+                          1./1024., 1024., 1.0,
                           G_PARAM_READWRITE));
 
   g_object_class_install_property (object_class, PROP_ANGLE,
index 2b057b25c1f56280428fa4002def710d566bd8be..d8ddac01df81825cbd9d3bcab48ce7ac1b31c029 100644 (file)
@@ -84,14 +84,36 @@ rotate (GtkWidget *button,
   g_object_set (demo, "angle", angle, NULL);
 }
 
-static void
-scale_changed (GtkRange  *range,
-               GtkWidget *widget)
+static gboolean
+transform_to (GBinding     *binding,
+              const GValue *src,
+              GValue       *dest,
+              gpointer      user_data)
 {
-  float scale;
+  double from;
+  float to;
+
+  from = g_value_get_double (src);
+  to = (float) pow (2., from);
+  g_value_set_float (dest, to);
+
+  return TRUE;
+}
+
+static gboolean
+transform_from (GBinding     *binding,
+                const GValue *src,
+                GValue       *dest,
+                gpointer      user_data)
+{
+  float to;
+  double from;
+
+  to = g_value_get_float (src);
+  from = log2 (to);
+  g_value_set_double (dest, from);
 
-  scale = (float) pow (2., gtk_range_get_value (range));
-  g_object_set (widget, "scale", scale, NULL);
+  return TRUE;
 }
 
 GtkWidget *
@@ -139,9 +161,10 @@ do_menu (GtkWidget *do_widget)
       g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
       gtk_box_append (GTK_BOX (box2), button);
 
-      scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10, 10.0, 0.1);
+      scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
+      gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
       gtk_widget_set_tooltip_text (scale, "Zoom");
-      gtk_range_set_value (GTK_RANGE (scale), 1.0);
+      gtk_range_set_value (GTK_RANGE (scale), 0.);
       gtk_widget_set_hexpand (scale, TRUE);
       gtk_box_append (GTK_BOX (box2), scale);
 
@@ -151,7 +174,12 @@ do_menu (GtkWidget *do_widget)
 
       g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
 
-      g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), widget);
+      g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
+                                   widget, "scale",
+                                   G_BINDING_BIDIRECTIONAL,
+                                   transform_to,
+                                   transform_from,
+                                   NULL, NULL);
     }
 
   if (!gtk_widget_get_visible (window))