[gnome-builder] libide/tweaks: allow bindings to create adjustments



commit c35b68a4cd42af0d9656322aba358ebd300e5280
Author: Christian Hergert <chergert redhat com>
Date:   Fri Aug 26 12:35:43 2022 -0700

    libide/tweaks: allow bindings to create adjustments

 src/libide/tweaks/ide-tweaks-binding.c  | 20 ++++++++
 src/libide/tweaks/ide-tweaks-binding.h  | 61 +++++++++++-----------
 src/libide/tweaks/ide-tweaks-property.c | 85 +++++++++++++++++++++++++++++++
 src/libide/tweaks/ide-tweaks-setting.c  | 90 +++++++++++++++++++++++++++++++++
 4 files changed, 227 insertions(+), 29 deletions(-)
---
diff --git a/src/libide/tweaks/ide-tweaks-binding.c b/src/libide/tweaks/ide-tweaks-binding.c
index 9c2586846..87f04677c 100644
--- a/src/libide/tweaks/ide-tweaks-binding.c
+++ b/src/libide/tweaks/ide-tweaks-binding.c
@@ -451,3 +451,23 @@ ide_tweaks_binding_set_string (IdeTweaksBinding *self,
   g_value_set_static_string (&value, string);
   ide_tweaks_binding_set_value (self, &value);
 }
+
+/**
+ * ide_tweaks_binding_create_adjustment:
+ * @self: a #IdeTweaksBinding
+ *
+ * Creates a new adjustment for the setting.
+ *
+ * Returns: (transfer full) (nullable): A #GtkAdjustment, or %NULL if
+ *   an adjustment is not supported for the binding.
+ */
+GtkAdjustment *
+ide_tweaks_binding_create_adjustment (IdeTweaksBinding *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_BINDING (self), NULL);
+
+  if (IDE_TWEAKS_BINDING_GET_CLASS (self)->create_adjustment)
+    return IDE_TWEAKS_BINDING_GET_CLASS (self)->create_adjustment (self);
+
+  return NULL;
+}
diff --git a/src/libide/tweaks/ide-tweaks-binding.h b/src/libide/tweaks/ide-tweaks-binding.h
index 5942a225d..96b288bb4 100644
--- a/src/libide/tweaks/ide-tweaks-binding.h
+++ b/src/libide/tweaks/ide-tweaks-binding.h
@@ -41,46 +41,49 @@ struct _IdeTweaksBindingClass
 {
   IdeTweaksItemClass parent_class;
 
-  void     (*changed)           (IdeTweaksBinding *self);
-  gboolean (*get_value)         (IdeTweaksBinding *self,
-                                 GValue           *value);
-  void     (*set_value)         (IdeTweaksBinding *self,
-                                 const GValue     *value);
-  GType    (*get_expected_type) (IdeTweaksBinding *self);
+  void           (*changed)           (IdeTweaksBinding *self);
+  gboolean       (*get_value)         (IdeTweaksBinding *self,
+                                       GValue           *value);
+  void           (*set_value)         (IdeTweaksBinding *self,
+                                       const GValue     *value);
+  GType          (*get_expected_type) (IdeTweaksBinding *self);
+  GtkAdjustment *(*create_adjustment) (IdeTweaksBinding *self);
 };
 
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_changed             (IdeTweaksBinding          *self);
+void           ide_tweaks_binding_changed             (IdeTweaksBinding          *self);
 IDE_AVAILABLE_IN_ALL
-gboolean ide_tweaks_binding_get_value           (IdeTweaksBinding          *self,
-                                                 GValue                    *value);
+gboolean       ide_tweaks_binding_get_value           (IdeTweaksBinding          *self,
+                                                       GValue                    *value);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_set_value           (IdeTweaksBinding          *self,
-                                                 const GValue              *value);
+void           ide_tweaks_binding_set_value           (IdeTweaksBinding          *self,
+                                                       const GValue              *value);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_set_variant         (IdeTweaksBinding          *self,
-                                                 GVariant                  *variant);
+void           ide_tweaks_binding_set_variant         (IdeTweaksBinding          *self,
+                                                       GVariant                  *variant);
 IDE_AVAILABLE_IN_ALL
-char    *ide_tweaks_binding_dup_string          (IdeTweaksBinding          *self);
+char          *ide_tweaks_binding_dup_string          (IdeTweaksBinding          *self);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_set_string          (IdeTweaksBinding          *self,
-                                                 const char                *string);
+void           ide_tweaks_binding_set_string          (IdeTweaksBinding          *self,
+                                                       const char                *string);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_bind                (IdeTweaksBinding          *self,
-                                                 gpointer                   instance,
-                                                 const char                *property_name);
+void           ide_tweaks_binding_bind                (IdeTweaksBinding          *self,
+                                                       gpointer                   instance,
+                                                       const char                *property_name);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_bind_with_transform (IdeTweaksBinding          *self,
-                                                 gpointer                   instance,
-                                                 const char                *property_name,
-                                                 IdeTweaksBindingTransform  get_transform,
-                                                 IdeTweaksBindingTransform  set_transform,
-                                                 gpointer                   user_data,
-                                                 GDestroyNotify             notify);
+void           ide_tweaks_binding_bind_with_transform (IdeTweaksBinding          *self,
+                                                       gpointer                   instance,
+                                                       const char                *property_name,
+                                                       IdeTweaksBindingTransform  get_transform,
+                                                       IdeTweaksBindingTransform  set_transform,
+                                                       gpointer                   user_data,
+                                                       GDestroyNotify             notify);
 IDE_AVAILABLE_IN_ALL
-void     ide_tweaks_binding_unbind              (IdeTweaksBinding          *self);
+void           ide_tweaks_binding_unbind              (IdeTweaksBinding          *self);
 IDE_AVAILABLE_IN_ALL
-gboolean ide_tweaks_binding_get_expected_type   (IdeTweaksBinding          *self,
-                                                 GType                     *type);
+gboolean       ide_tweaks_binding_get_expected_type   (IdeTweaksBinding          *self,
+                                                       GType                     *type);
+IDE_AVAILABLE_IN_ALL
+GtkAdjustment *ide_tweaks_binding_create_adjustment   (IdeTweaksBinding          *self);
 
 G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-property.c b/src/libide/tweaks/ide-tweaks-property.c
index bbcb66a37..b0d74bd78 100644
--- a/src/libide/tweaks/ide-tweaks-property.c
+++ b/src/libide/tweaks/ide-tweaks-property.c
@@ -170,6 +170,90 @@ ide_tweaks_property_get_expected_type (IdeTweaksBinding *binding)
   return G_TYPE_INVALID;
 }
 
+static GtkAdjustment *
+ide_tweaks_property_create_adjustment (IdeTweaksBinding *binding)
+{
+  IdeTweaksProperty *self = (IdeTweaksProperty *)binding;
+  g_autoptr(GObject) object = NULL;
+  double lower = .0;
+  double upper = .0;
+  double page_increment = 10.;
+  double step_increment = 1.;
+
+  g_assert (IDE_IS_TWEAKS_PROPERTY (self));
+
+  if (!(ide_tweaks_property_acquire (self)))
+    return NULL;
+
+  g_assert (self->pspec != NULL);
+
+  if (G_IS_PARAM_SPEC_DOUBLE (self->pspec))
+    {
+      GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else if (G_IS_PARAM_SPEC_FLOAT (self->pspec))
+    {
+      GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else if (G_IS_PARAM_SPEC_INT (self->pspec))
+    {
+      GParamSpecInt *pspec = G_PARAM_SPEC_INT (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else if (G_IS_PARAM_SPEC_UINT (self->pspec))
+    {
+      GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else if (G_IS_PARAM_SPEC_INT64 (self->pspec))
+    {
+      GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else if (G_IS_PARAM_SPEC_UINT64 (self->pspec))
+    {
+      GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (self->pspec);
+
+      lower = pspec->minimum;
+      upper = pspec->maximum;
+    }
+  else
+    {
+      return NULL;
+    }
+
+  if (G_IS_PARAM_SPEC_DOUBLE (self->pspec) ||
+      G_IS_PARAM_SPEC_FLOAT (self->pspec))
+    {
+      double distance = ABS (upper - lower);
+
+      if (distance <= 1.)
+        {
+          step_increment = .05;
+          page_increment = .2;
+        }
+      else if (distance <= 50.)
+        {
+          step_increment = .1;
+          page_increment = 1;
+        }
+    }
+
+  return gtk_adjustment_new (0, lower, upper, step_increment, page_increment, 0);
+}
+
 static void
 ide_tweaks_property_dispose (GObject *object)
 {
@@ -257,6 +341,7 @@ ide_tweaks_property_class_init (IdeTweaksPropertyClass *klass)
   tweaks_binding_class->get_value = ide_tweaks_property_get_value;
   tweaks_binding_class->set_value = ide_tweaks_property_set_value;
   tweaks_binding_class->get_expected_type = ide_tweaks_property_get_expected_type;
+  tweaks_binding_class->create_adjustment = ide_tweaks_property_create_adjustment;
 
   properties[PROP_NAME] =
     g_param_spec_string ("name", NULL, NULL,
diff --git a/src/libide/tweaks/ide-tweaks-setting.c b/src/libide/tweaks/ide-tweaks-setting.c
index 05b9334a1..e95fd45c5 100644
--- a/src/libide/tweaks/ide-tweaks-setting.c
+++ b/src/libide/tweaks/ide-tweaks-setting.c
@@ -198,6 +198,95 @@ ide_tweaks_setting_get_expected_type (IdeTweaksBinding *binding)
   return _ide_tweaks_variant_type_to_gtype (expected_type);
 }
 
+static double
+get_value_as_double (GVariant *value)
+{
+  if (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE))
+    return g_variant_get_double (value);
+
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT16))
+    return g_variant_get_int16 (value);
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT16))
+    return g_variant_get_uint16 (value);
+
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32))
+    return g_variant_get_int32 (value);
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
+    return g_variant_get_uint32 (value);
+
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT64))
+    return g_variant_get_int64 (value);
+  else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT64))
+    return g_variant_get_uint64 (value);
+
+  return 0;
+}
+
+static GtkAdjustment *
+ide_tweaks_setting_create_adjustment (IdeTweaksBinding *binding)
+{
+  IdeTweaksSetting *self = (IdeTweaksSetting *)binding;
+  GSettingsSchemaSource *source;
+  GSettingsSchemaKey *schema_key = NULL;
+  GSettingsSchema *schema = NULL;
+  g_autofree char *type = NULL;
+  g_autoptr(GVariant) lval = NULL;
+  g_autoptr(GVariant) uval = NULL;
+  g_autoptr(GVariant) range = NULL;
+  g_autoptr(GVariant) values = NULL;
+  double step_increment = 1;
+  double page_increment = 10;
+  double lower = .0;
+  double upper = .0;
+  GVariantIter iter;
+  GtkAdjustment *ret = NULL;
+
+  g_assert (IDE_IS_TWEAKS_SETTING (self));
+
+  if (self->schema_id == NULL || self->schema_key == NULL)
+    return NULL;
+
+  source = g_settings_schema_source_get_default ();
+  schema = g_settings_schema_source_lookup (source, self->schema_id, TRUE);
+  schema_key = g_settings_schema_get_key (schema, self->schema_key);
+  range = g_settings_schema_key_get_range (schema_key);
+  g_variant_get (range, "(sv)", &type, &values);
+
+  if (!ide_str_equal0 (type, "range") ||
+      (2 != g_variant_iter_init (&iter, values)))
+    goto cleanup;
+
+  lval = g_variant_iter_next_value (&iter);
+  uval = g_variant_iter_next_value (&iter);
+
+  lower = get_value_as_double (lval);
+  upper = get_value_as_double (uval);
+
+  if (g_variant_is_of_type (lval, G_VARIANT_TYPE_DOUBLE))
+    {
+      double distance = ABS (upper - lower);
+
+      if (distance <= 1.)
+        {
+          step_increment = .05;
+          page_increment = .2;
+        }
+      else if (distance <= 50.)
+        {
+          step_increment = .1;
+          page_increment = 1;
+        }
+    }
+
+  ret = gtk_adjustment_new (0, lower, upper, step_increment, page_increment, 0);
+
+cleanup:
+  g_clear_pointer (&schema, g_settings_schema_unref);
+  g_clear_pointer (&schema_key, g_settings_schema_key_unref);
+
+  return ret;
+}
+
 static void
 ide_tweaks_setting_dispose (GObject *object)
 {
@@ -276,6 +365,7 @@ ide_tweaks_setting_class_init (IdeTweaksSettingClass *klass)
   tweaks_binding_class->get_value = ide_tweaks_setting_get_value;
   tweaks_binding_class->set_value = ide_tweaks_setting_set_value;
   tweaks_binding_class->get_expected_type = ide_tweaks_setting_get_expected_type;
+  tweaks_binding_class->create_adjustment = ide_tweaks_setting_create_adjustment;
 
   properties[PROP_SCHEMA_ID] =
     g_param_spec_string ("schema-id", NULL, NULL,


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