[gimp] app: allow locale lower and upper values in gimp_prop_spin_scale_new().



commit cafa912c988ffcb0f9a99ad5ff55f7348f062d23
Author: Jehan <jehan girinstud io>
Date:   Tue Jun 14 16:52:52 2016 +0200

    app: allow locale lower and upper values in gimp_prop_spin_scale_new().
    
    Currently a GimpSpinScale created with gimp_prop_spin_scale_new() will
    use the associated property's lower and upper values.
    Unfortunately these generic values may not be always relevant and we
    may want to construct a spin scale UI adapted to the current image.
    For instance, several symmetry painting have a x/y property which has
    to stay within the image's dimension, but changing the property's lower
    and upper values would affect the symmetry on the class level (i.e. for
    all similar symmetries on all images).
    Let's allow setting data on object with key "property-name:min|max" to
    provide locale min/max values specifically for this object.
    This is used only on the symmetry dock for now, but could be used as
    well on GEGL op UIs.

 app/core/gimpsymmetry-mandala.c |   56 ++++++++++++++++++-------------------
 app/core/gimpsymmetry-mirror.c  |   52 +++++++++++++++++++++++++++++++++++
 app/core/gimpsymmetry-tiling.c  |   58 ++++++++++++++++++++-------------------
 app/widgets/gimppropgui.c       |   27 ++++++++++++++++++
 app/widgets/gimppropwidgets.c   |   32 +++++++++++++++++++++
 5 files changed, 168 insertions(+), 57 deletions(-)
---
diff --git a/app/core/gimpsymmetry-mandala.c b/app/core/gimpsymmetry-mandala.c
index c612c03..b447bde 100644
--- a/app/core/gimpsymmetry-mandala.c
+++ b/app/core/gimpsymmetry-mandala.c
@@ -85,7 +85,7 @@ static GeglNode * gimp_mandala_get_operation      (GimpSymmetry *mandala,
                                                    gint          stroke,
                                                    gint          paint_width,
                                                    gint          paint_height);
-static void    gimp_mandala_image_size_changed_cb (GimpImage    *image ,
+static void    gimp_mandala_image_size_changed_cb (GimpImage    *image,
                                                    gint          previous_origin_x,
                                                    gint          previous_origin_y,
                                                    gint          previous_width,
@@ -118,7 +118,7 @@ gimp_mandala_class_init (GimpMandalaClass *klass)
                            "center-x",
                            _("Center abscisse"),
                            NULL,
-                           0.0, 10000.0, 0.0,
+                           0.0, G_MAXDOUBLE, 0.0,
                            GIMP_PARAM_STATIC_STRINGS |
                            GIMP_SYMMETRY_PARAM_GUI);
 
@@ -126,7 +126,7 @@ gimp_mandala_class_init (GimpMandalaClass *klass)
                            "center-y",
                            _("Center ordinate"),
                            NULL,
-                           0.0, 10000.0, 0.0,
+                           0.0, G_MAXDOUBLE, 0.0,
                            GIMP_PARAM_STATIC_STRINGS |
                            GIMP_SYMMETRY_PARAM_GUI);
 
@@ -155,19 +155,17 @@ gimp_mandala_init (GimpMandala *mandala)
 static void
 gimp_mandala_constructed (GObject *object)
 {
-  GimpSymmetry     *sym;
-  GParamSpecDouble *dspec;
+  GimpSymmetry *sym;
+  gdouble      *x_max = g_new (gdouble, 1);
+  gdouble      *y_max = g_new (gdouble, 1);
 
   sym = GIMP_SYMMETRY (object);
 
-  /* Update property values to actual image size. */
-  dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                                             "center-x"));
-  dspec->maximum = gimp_image_get_width (sym->image);
+  *x_max = gimp_image_get_width (sym->image);
+  *y_max = gimp_image_get_height (sym->image);
 
-  dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                                             "center-y"));
-  dspec->maximum = gimp_image_get_height (sym->image);
+  g_object_set_data_full (object, "center-x:max", x_max, g_free);
+  g_object_set_data_full (object, "center-y:max", y_max, g_free);
 
   g_signal_connect (sym->image, "size-changed-detailed",
                     G_CALLBACK (gimp_mandala_image_size_changed_cb),
@@ -177,8 +175,12 @@ gimp_mandala_constructed (GObject *object)
 static void
 gimp_mandala_finalize (GObject *object)
 {
-  GimpMandala *mandala = GIMP_MANDALA (object);
+  GimpSymmetry *sym     = GIMP_SYMMETRY (object);
+  GimpMandala  *mandala = GIMP_MANDALA (object);
 
+  g_signal_handlers_disconnect_by_func (sym->image,
+                                        gimp_mandala_image_size_changed_cb,
+                                        object);
   if (mandala->horizontal_guide)
     g_object_unref (mandala->horizontal_guide);
   mandala->horizontal_guide = NULL;
@@ -547,22 +549,18 @@ gimp_mandala_image_size_changed_cb (GimpImage    *image,
                                     gint          previous_height,
                                     GimpSymmetry *sym)
 {
-  GParamSpecDouble *dspec;
-
-  if (previous_width != gimp_image_get_width (image))
-    {
-      dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                                                 "center-x"));
-      dspec->maximum = gimp_image_get_width (sym->image);
-    }
-  if (previous_height != gimp_image_get_height (image))
-    {
-      dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                                                 "center-y"));
-      dspec->maximum = gimp_image_get_height (sym->image);
-    }
-
   if (previous_width != gimp_image_get_width (image) ||
       previous_height != gimp_image_get_height (image))
-    g_signal_emit_by_name (sym, "update-ui", sym->image);
+    {
+      gdouble *x_max = g_new (gdouble, 1);
+      gdouble *y_max = g_new (gdouble, 1);
+
+      *x_max = gimp_image_get_width (image);
+      *y_max = gimp_image_get_height (image);
+
+      g_object_set_data_full (G_OBJECT (sym), "center-x:max", x_max, g_free);
+      g_object_set_data_full (G_OBJECT (sym), "center-y:max", y_max, g_free);
+
+      g_signal_emit_by_name (sym, "update-ui", sym->image);
+    }
 }
diff --git a/app/core/gimpsymmetry-mirror.c b/app/core/gimpsymmetry-mirror.c
index 94ed719..c36e975 100644
--- a/app/core/gimpsymmetry-mirror.c
+++ b/app/core/gimpsymmetry-mirror.c
@@ -57,6 +57,7 @@ enum
 
 /* Local function prototypes */
 
+static void       gimp_mirror_constructed             (GObject             *object);
 static void       gimp_mirror_finalize                (GObject             *object);
 static void       gimp_mirror_set_property            (GObject             *object,
                                                        guint                property_id,
@@ -95,6 +96,12 @@ static void       gimp_mirror_set_vertical_symmetry   (GimpMirror          *mirr
 static void       gimp_mirror_set_point_symmetry      (GimpMirror          *mirror,
                                                        gboolean             active);
 
+static void       gimp_mirror_image_size_changed_cb   (GimpImage           *image,
+                                                       gint                 previous_origin_x,
+                                                       gint                 previous_origin_y,
+                                                       gint                 previous_width,
+                                                       gint                 previous_height,
+                                                       GimpSymmetry        *sym);
 
 G_DEFINE_TYPE (GimpMirror, gimp_mirror, GIMP_TYPE_SYMMETRY)
 
@@ -107,6 +114,7 @@ gimp_mirror_class_init (GimpMirrorClass *klass)
   GObjectClass      *object_class   = G_OBJECT_CLASS (klass);
   GimpSymmetryClass *symmetry_class = GIMP_SYMMETRY_CLASS (klass);
 
+  object_class->constructed         = gimp_mirror_constructed;
   object_class->finalize            = gimp_mirror_finalize;
   object_class->set_property        = gimp_mirror_set_property;
   object_class->get_property        = gimp_mirror_get_property;
@@ -171,6 +179,26 @@ gimp_mirror_init (GimpMirror *mirror)
 }
 
 static void
+gimp_mirror_constructed (GObject *object)
+{
+  GimpSymmetry *sym;
+  gdouble      *x_max = g_new (gdouble, 1);
+  gdouble      *y_max = g_new (gdouble, 1);
+
+  sym = GIMP_SYMMETRY (object);
+
+  *x_max = gimp_image_get_width (sym->image);
+  *y_max = gimp_image_get_height (sym->image);
+
+  g_object_set_data_full (object, "horizontal-position:max", y_max, g_free);
+  g_object_set_data_full (object, "vertical-position:max", x_max, g_free);
+
+  g_signal_connect (sym->image, "size-changed-detailed",
+                    G_CALLBACK (gimp_mirror_image_size_changed_cb),
+                    sym);
+}
+
+static void
 gimp_mirror_finalize (GObject *object)
 {
   GimpMirror *mirror = GIMP_MIRROR (object);
@@ -707,3 +735,27 @@ gimp_mirror_set_point_symmetry (GimpMirror *mirror,
 
   gimp_mirror_reset (mirror);
 }
+
+static void
+gimp_mirror_image_size_changed_cb (GimpImage    *image,
+                                   gint          previous_origin_x,
+                                   gint          previous_origin_y,
+                                   gint          previous_width,
+                                   gint          previous_height,
+                                   GimpSymmetry *sym)
+{
+  if (previous_width != gimp_image_get_width (image) ||
+      previous_height != gimp_image_get_height (image))
+    {
+      gdouble *x_max = g_new (gdouble, 1);
+      gdouble *y_max = g_new (gdouble, 1);
+
+      *x_max = gimp_image_get_width (image);
+      *y_max = gimp_image_get_height (image);
+
+      g_object_set_data_full (G_OBJECT (sym), "vertical-position:max", x_max, g_free);
+      g_object_set_data_full (G_OBJECT (sym), "horizontal-position:max", y_max, g_free);
+
+      g_signal_emit_by_name (sym, "update-ui", sym->image);
+    }
+}
diff --git a/app/core/gimpsymmetry-tiling.c b/app/core/gimpsymmetry-tiling.c
index 3c6a4d6..a5328a7 100644
--- a/app/core/gimpsymmetry-tiling.c
+++ b/app/core/gimpsymmetry-tiling.c
@@ -105,7 +105,7 @@ gimp_tiling_class_init (GimpTilingClass *klass)
                            "x-interval",
                            _("Interval X"),
                            _("Interval on the X axis (pixels)"),
-                           0.0, 10000.0, 0.0,
+                           0.0, G_MAXDOUBLE, 0.0,
                            GIMP_PARAM_STATIC_STRINGS |
                            GIMP_SYMMETRY_PARAM_GUI);
 
@@ -113,7 +113,7 @@ gimp_tiling_class_init (GimpTilingClass *klass)
                            "y-interval",
                            _("Interval Y"),
                            _("Interval on the Y axis (pixels)"),
-                           0.0, 10000.0, 0.0,
+                           0.0, G_MAXDOUBLE, 0.0,
                            GIMP_PARAM_STATIC_STRINGS |
                            GIMP_SYMMETRY_PARAM_GUI);
 
@@ -121,7 +121,7 @@ gimp_tiling_class_init (GimpTilingClass *klass)
                            "shift",
                            _("Shift"),
                            _("X-shift between lines (pixels)"),
-                           0.0, 10000.0, 0.0,
+                           0.0, G_MAXDOUBLE, 0.0,
                            GIMP_PARAM_STATIC_STRINGS |
                            GIMP_SYMMETRY_PARAM_GUI);
 
@@ -150,22 +150,20 @@ gimp_tiling_init (GimpTiling *tiling)
 static void
 gimp_tiling_constructed (GObject *object)
 {
-  GimpSymmetry     *sym    = GIMP_SYMMETRY (object);
-  GimpTiling       *tiling = GIMP_TILING (object);
-  GParamSpecDouble *dspec;
+  GimpSymmetry *sym       = GIMP_SYMMETRY (object);
+  GimpTiling   *tiling    = GIMP_TILING (object);
+  gdouble      *x_max     = g_new (gdouble, 1);
+  gdouble      *y_max     = g_new (gdouble, 1);
+  gdouble      *shift_max = g_new (gdouble, 1);
 
-  /* Update property values to actual image size. */
-  dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                                             "x-interval"));
-  dspec->maximum = gimp_image_get_width (sym->image);
+  /* Set property values to actual image size. */
+  *x_max     = gimp_image_get_width (sym->image);
+  *y_max     = gimp_image_get_height (sym->image);
+  *shift_max = *x_max;
 
-  dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                                             "shift"));
-  dspec->maximum = gimp_image_get_width (sym->image);
-
-  dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                                             "y-interval"));
-  dspec->maximum = gimp_image_get_height (sym->image);
+  g_object_set_data_full (object, "x-interval:max", x_max, g_free);
+  g_object_set_data_full (object, "y-interval:max", y_max, g_free);
+  g_object_set_data_full (object, "shift:max", shift_max, g_free);
 
   g_signal_connect (sym->image, "size-changed-detailed",
                     G_CALLBACK (gimp_tiling_image_size_changed_cb),
@@ -375,23 +373,27 @@ gimp_tiling_image_size_changed_cb (GimpImage    *image,
                                    gint          previous_height,
                                    GimpSymmetry *sym)
 {
-  GParamSpecDouble *dspec;
-
   if (previous_width != gimp_image_get_width (image))
     {
-      dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                                                 "x-interval"));
-      dspec->maximum = gimp_image_get_width (sym->image);
+      gdouble *x_max     = g_new (gdouble, 1);
+      gdouble *shift_max = g_new (gdouble, 1);
+
+      *x_max     = gimp_image_get_width (sym->image);
+      *shift_max = *x_max;
 
-      dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                                                 "shift"));
-      dspec->maximum = gimp_image_get_width (sym->image);
+      g_object_set_data_full (G_OBJECT (sym), "x-interval:max",
+                              x_max, g_free);
+      g_object_set_data_full (G_OBJECT (sym), "shift:max",
+                              shift_max, g_free);
     }
   if (previous_height != gimp_image_get_height (image))
     {
-      dspec = G_PARAM_SPEC_DOUBLE (g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                                                 "y-interval"));
-      dspec->maximum = gimp_image_get_height (sym->image);
+      gdouble *y_max     = g_new (gdouble, 1);
+
+      *y_max = gimp_image_get_height (sym->image);
+
+      g_object_set_data_full (G_OBJECT (sym), "y-interval:max",
+                              y_max, g_free);
     }
 
   if (previous_width != gimp_image_get_width (image) ||
diff --git a/app/widgets/gimppropgui.c b/app/widgets/gimppropgui.c
index e2c109b..426dc1f 100644
--- a/app/widgets/gimppropgui.c
+++ b/app/widgets/gimppropgui.c
@@ -160,11 +160,37 @@ gimp_prop_widget_new_from_pspec (GObject               *config,
       else
         {
           gdouble value;
+          gdouble *config_value;
+          gchar   *config_key;
 
+          /* Get the min and max for the given property. */
           _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                  &value, &lower, &upper,
                                                  G_STRFUNC);
 
+          /* A given config object may have locale min/max. */
+          config_key = g_strconcat (pspec->name, ":min", NULL);
+          config_value = g_object_get_data (G_OBJECT (config),
+                                            config_key);
+          if (config_value &&
+              *config_value > lower &&
+              *config_value < upper)
+            {
+              lower = *config_value;
+            }
+          g_free (config_key);
+
+          config_key = g_strconcat (pspec->name, ":max", NULL);
+          config_value = g_object_get_data (G_OBJECT (config),
+                                            config_key);
+          if (config_value &&
+              *config_value > lower &&
+              *config_value < upper)
+            {
+              upper = *config_value;
+            }
+          g_free (config_key);
+
           if ((upper - lower <= 1.0) &&
               (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                G_IS_PARAM_SPEC_DOUBLE (pspec)))
@@ -344,6 +370,7 @@ static const struct
   const gchar        *config_type;
   GimpPropGuiNewFunc  gui_new_func;
 }
+
 gui_new_funcs[] =
 {
   { "GimpGegl-gegl-color-rotate-config",
diff --git a/app/widgets/gimppropwidgets.c b/app/widgets/gimppropwidgets.c
index 2da934f..99c4051 100644
--- a/app/widgets/gimppropwidgets.c
+++ b/app/widgets/gimppropwidgets.c
@@ -492,6 +492,10 @@ static void   gimp_prop_adjustment_notify   (GObject       *config,
  * gdouble property in a very space-efficient way.
  * If @label is #NULL, the @property_name's nick will be used as label
  * of the returned widget.
+ * The property's lower and upper values will be used as min/max of the
+ * #GimpSpinScale, unless the object carries locale data superseding
+ * the property's setting, with the respective keys "@property_name:min"
+ * and "@property_name:max".
  *
  * Return value:  A new #GimpSpinScale widget.
  *
@@ -508,6 +512,8 @@ gimp_prop_spin_scale_new (GObject     *config,
   GParamSpec    *param_spec;
   GtkAdjustment *adjustment;
   GtkWidget     *scale;
+  gdouble       *config_value;
+  gchar         *config_key;
   gdouble        value;
   gdouble        lower;
   gdouble        upper;
@@ -516,14 +522,40 @@ gimp_prop_spin_scale_new (GObject     *config,
   if (! param_spec)
     return NULL;
 
+  /* The generic min and max for the property. */
   if (! _gimp_prop_widgets_get_numeric_values (config, param_spec,
                                                &value, &lower, &upper,
                                                G_STRFUNC))
     return NULL;
 
+  /* Check if locale min/max for this specific config object exist. */
+  config_key = g_strconcat (param_spec->name, ":min", NULL);
+  config_value = g_object_get_data (G_OBJECT (config),
+                                    config_key);
+  if (config_value &&
+      *config_value > lower &&
+      *config_value < upper)
+    {
+      lower = *config_value;
+    }
+  g_free (config_key);
+
+  config_key = g_strconcat (param_spec->name, ":max", NULL);
+  config_value = g_object_get_data (G_OBJECT (config),
+                                    config_key);
+  if (config_value &&
+      *config_value > lower &&
+      *config_value < upper)
+    {
+      upper = *config_value;
+    }
+  g_free (config_key);
+
+  /* Get label. */
   if (! label)
     label = g_param_spec_get_nick (param_spec);
 
+  /* Also usable on int properties. */
   if (! G_IS_PARAM_SPEC_DOUBLE (param_spec))
     digits = 0;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]