[gimp] libgimpwidgets: make GimpScaleEntry into its own widget.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimpwidgets: make GimpScaleEntry into its own widget.
- Date: Fri, 30 Oct 2020 10:54:27 +0000 (UTC)
commit 5238958e55e279a6359adaaa8dbfe4c41e796fbc
Author: Jehan <jehan girinstud io>
Date: Fri Oct 30 00:30:03 2020 +0100
libgimpwidgets: make GimpScaleEntry into its own widget.
Instead of the gimp_scale_entry_new() which creates several bound yet
independant widgets, and in the same time pack them into an existing
grid and return a GtkAdjustment (while heavily relying on GObject data
to link widgets), let's have a proper custom widget with its own clean
API.
This also simplifies the gimp_prop_scale_entry_new() property widget
variant.
First advantage is that we don't force the usage of a grid to use this
widget (there are a few pieces of code which create a GtkGrid with only
this inside just to be able to use this feature).
Second thing is that I am creating a much simpler API.
gimp_scale_entry_new() had 17 parameters! How crazy is that? So I
removed all the grid packing related parameters. Also I moved the spin
button/scale unconstraining parameters into their separate function,
because the constrained behavior is the most common use case, so it's
stupid to add 3 permanent dummy parameters for most calls. Instead the
few times where we'll want different ranges for the spin button and the
scale, we'll call the separate API gimp_scale_entry_set_range().
Thirdly the tooltip can be set directly with gimp_help_set_help_data()
since this is now its own widget. No need to have dedicated logics
anymore, better stay generic. Similarly no need of a custom function to
switch sensitivitivy (instead of generic gtk_widget_set_sensitive()).
Fourth thing is that we should not use macros for the public API, but
proper functions, because macros are not properly introspected for
binding.
For future improvements, maybe we could even make this widget implement
GtkOrientable interface, in order to be able to use it vertically.
Note: right now, I created a separate gimp_scale_entry_new2() and only
modified the property widget API to use this new code. Eventually I will
remove fully the old gimp_scale_entry_new() function (and the new code
will replace it).
libgimpwidgets/gimppropwidgets.c | 110 +++-----
libgimpwidgets/gimppropwidgets.h | 10 +-
libgimpwidgets/gimpscaleentry.c | 530 ++++++++++++++++++++++++++++++++++++++
libgimpwidgets/gimpscaleentry.h | 52 ++++
libgimpwidgets/gimpwidgetstypes.h | 1 +
5 files changed, 625 insertions(+), 78 deletions(-)
---
diff --git a/libgimpwidgets/gimppropwidgets.c b/libgimpwidgets/gimppropwidgets.c
index 453144f041..1ff31c29a6 100644
--- a/libgimpwidgets/gimppropwidgets.c
+++ b/libgimpwidgets/gimppropwidgets.c
@@ -1462,39 +1462,32 @@ gimp_prop_hscale_new (GObject *config,
/**
* gimp_prop_scale_entry_new:
* @config: Object to which property is attached.
- * @property_name: Name of double property controlled by the spin button.
- * @grid: The #GtkGrid the widgets will be attached to.
- * @column: The column to start with.
- * @row: The row to attach the widgets.
* @label: (nullable): The text for the #GtkLabel which will appear left of
* the #GtkHScale.
+ * @property_name: Name of integer or double property controlled by the scale.
* @step_increment: Step size.
* @page_increment: Page size.
- * @digits: Number of digits after decimal point to display.
+ * @digits: Number of digits after decimal point to display. For
+ * integer properties, this will be ignored (always 0).
* @limit_scale: %FALSE if the range of possible values of the
* GtkHScale should be the same as of the GtkSpinButton.
* @lower_limit: The scale's lower boundary if @scale_limits is %TRUE.
* @upper_limit: The scale's upper boundary if @scale_limits is %TRUE.
*
- * Creates a #libgimpwidgets-gimpscaleentry (slider and spin button)
- * to set and display the value of the specified double property. See
- * gimp_scale_entry_new() for more information.
+ * Creates a #GimpScaleEntry (slider and spin button) to set and display
+ * the value of a specified int or double property.
+ * See gimp_scale_entry_new() for more information.
+ *
* If @label is %NULL, the @property_name's nick will be used as label
* of the returned object.
*
- * Note that the @scale_limits boolean is the inverse of
- * gimp_scale_entry_new()'s "constrain" parameter.
- *
- * Returns: (transfer full): The #GtkSpinButton's #GtkAdjustment.
+ * Returns: (transfer full): The newly allocated #GimpScaleEntry.
*
* Since: 2.4
*/
-GtkAdjustment *
+GtkWidget *
gimp_prop_scale_entry_new (GObject *config,
const gchar *property_name,
- GtkGrid *grid,
- gint column,
- gint row,
const gchar *label,
gdouble step_increment,
gdouble page_increment,
@@ -1503,12 +1496,12 @@ gimp_prop_scale_entry_new (GObject *config,
gdouble lower_limit,
gdouble upper_limit)
{
- GParamSpec *param_spec;
- GtkAdjustment *adjustment;
- const gchar *tooltip;
- gdouble value;
- gdouble lower;
- gdouble upper;
+ GtkWidget *widget;
+ GParamSpec *param_spec;
+ const gchar *tooltip;
+ gdouble value;
+ gdouble lower;
+ gdouble upper;
param_spec = find_param_spec (config, property_name, G_STRFUNC);
if (! param_spec)
@@ -1518,45 +1511,30 @@ gimp_prop_scale_entry_new (GObject *config,
param_spec, &value, &lower, &upper, G_STRFUNC))
return NULL;
+ if (G_IS_PARAM_SPEC_INT (param_spec) || G_IS_PARAM_SPEC_UINT (param_spec))
+ digits = 0;
+
if (! label)
label = g_param_spec_get_nick (param_spec);
- tooltip = g_param_spec_get_blurb (param_spec);
-
- if (! limit_scale)
+ widget = gimp_scale_entry_new2 (label, value, lower, upper,
+ step_increment, page_increment,
+ digits);
+ if (limit_scale)
{
- adjustment = gimp_scale_entry_new (grid, column, row,
- label, -1, -1,
- value, lower, upper,
- step_increment, page_increment,
- digits,
- TRUE, 0.0, 0.0,
- tooltip,
- NULL);
+ gimp_scale_entry_set_range (GIMP_SCALE_ENTRY (widget),
+ lower_limit, upper_limit,
+ FALSE);
}
- else
- {
- adjustment = gimp_scale_entry_new (grid, column, row,
- label, -1, -1,
- value, lower_limit, upper_limit,
- step_increment, page_increment,
- digits,
- FALSE, lower, upper,
- tooltip,
- NULL);
- }
-
- set_param_spec (G_OBJECT (adjustment), NULL, param_spec);
- g_signal_connect (adjustment, "value-changed",
- G_CALLBACK (gimp_prop_adjustment_callback),
- config);
+ tooltip = g_param_spec_get_blurb (param_spec);
+ gimp_help_set_help_data (widget, tooltip, NULL);
- connect_notify (config, property_name,
- G_CALLBACK (gimp_prop_adjustment_notify),
- adjustment);
+ g_object_bind_property (config, property_name,
+ widget, "value",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- return adjustment;
+ return widget;
}
static void
@@ -1620,9 +1598,6 @@ gimp_prop_widget_set_factor (GtkWidget *widget,
* gimp_prop_opacity_entry_new:
* @config: Object to which property is attached.
* @property_name: Name of double property controlled by the spin button.
- * @grid: The #GtkGrid the widgets will be attached to.
- * @column: The column to start with.
- * @row: The row to attach the widgets.
* @label: The text for the #GtkLabel which will appear left of the
* #GtkHScale.
*
@@ -1635,32 +1610,27 @@ gimp_prop_widget_set_factor (GtkWidget *widget,
*
* Since: 2.4
*/
-GtkAdjustment *
+GtkWidget *
gimp_prop_opacity_entry_new (GObject *config,
const gchar *property_name,
- GtkGrid *grid,
- gint column,
- gint row,
const gchar *label)
{
- GtkAdjustment *adjustment;
+ GtkWidget *widget;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (property_name != NULL, NULL);
- adjustment = gimp_prop_scale_entry_new (config, property_name,
- grid, column, row, label,
- 0.01, 0.1, 1,
- FALSE, 0.0, 0.0);
+ widget = gimp_prop_scale_entry_new (config, property_name,
+ label, 0.01, 0.1, 1,
+ FALSE, 0.0, 0.0);
- if (adjustment)
+ if (widget)
{
- gimp_prop_widget_set_factor (GIMP_SCALE_ENTRY_SPINBUTTON (adjustment),
- adjustment,
- 100.0, 0.0, 0.0, 1);
+ gimp_prop_widget_set_factor (gimp_scale_entry_get_spin_button (GIMP_SCALE_ENTRY (widget)),
+ NULL, 100.0, 0.0, 0.0, 1);
}
- return adjustment;
+ return widget;
}
diff --git a/libgimpwidgets/gimppropwidgets.h b/libgimpwidgets/gimppropwidgets.h
index 4e0343ecf2..e871229ee5 100644
--- a/libgimpwidgets/gimppropwidgets.h
+++ b/libgimpwidgets/gimppropwidgets.h
@@ -120,11 +120,8 @@ GtkWidget * gimp_prop_hscale_new (GObject *config,
gdouble page_increment,
gint digits);
-GtkAdjustment * gimp_prop_scale_entry_new (GObject *config,
+GtkWidget * gimp_prop_scale_entry_new (GObject *config,
const gchar *property_name,
- GtkGrid *grid,
- gint column,
- gint row,
const gchar *label,
gdouble step_increment,
gdouble page_increment,
@@ -135,11 +132,8 @@ GtkAdjustment * gimp_prop_scale_entry_new (GObject *config,
/* special form of gimp_prop_scale_entry_new() for GParamDouble */
-GtkAdjustment * gimp_prop_opacity_entry_new (GObject *config,
+GtkWidget * gimp_prop_opacity_entry_new (GObject *config,
const gchar *property_name,
- GtkGrid *grid,
- gint column,
- gint row,
const gchar *label);
diff --git a/libgimpwidgets/gimpscaleentry.c b/libgimpwidgets/gimpscaleentry.c
index 7e95b1a9e0..819fc4709f 100644
--- a/libgimpwidgets/gimpscaleentry.c
+++ b/libgimpwidgets/gimpscaleentry.c
@@ -31,6 +31,50 @@
#include "gimpwidgets.h"
+/**
+ * SECTION: gimpscaleentry
+ * @title: GimpScaleEntry
+ * @short_description: Widget containing a scale, a spin button and a
+ * label.
+ *
+ * This widget is a #GtkGrid showing a #GtkSpinButton and a #GtkScale
+ * bound together. It also displays a #GtkLabel which is used as
+ * mnemonic on the #GtkSpinButton.
+ **/
+
+
+enum
+{
+ PROP_0,
+ PROP_LABEL,
+ PROP_VALUE,
+ PROP_LOWER,
+ PROP_UPPER,
+ PROP_STEP_INCREMENT,
+ PROP_PAGE_INCREMENT,
+ PROP_DIGITS,
+};
+
+struct _GimpScaleEntryPrivate
+{
+ GtkWidget *label;
+ GtkWidget *spinbutton;
+ GtkWidget *scale;
+
+ GBinding *binding;
+};
+
+
+static void gimp_scale_entry_constructed (GObject *object);
+static void gimp_scale_entry_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_scale_entry_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
static gboolean gimp_scale_entry_linear_to_log (GBinding *binding,
const GValue *from_value,
GValue *to_value,
@@ -60,6 +104,326 @@ static GtkAdjustment * gimp_scale_entry_new_internal (gboolean color_scale
const gchar *help_id);
+G_DEFINE_TYPE_WITH_PRIVATE (GimpScaleEntry, gimp_scale_entry, GTK_TYPE_GRID)
+
+#define parent_class gimp_scale_entry_parent_class
+
+
+static void
+gimp_scale_entry_class_init (GimpScaleEntryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = gimp_scale_entry_constructed;
+ object_class->set_property = gimp_scale_entry_set_property;
+ object_class->get_property = gimp_scale_entry_get_property;
+
+ /**
+ * GimpScaleEntry:label:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_LABEL,
+ g_param_spec_string ("label",
+ "Label text",
+ "The text of the label part of this widget",
+ NULL,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:value:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_VALUE,
+ g_param_spec_double ("value", NULL,
+ "Current value",
+ -G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:lower:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_LOWER,
+ g_param_spec_double ("lower", NULL,
+ "Minimum value",
+ -G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:upper:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_UPPER,
+ g_param_spec_double ("upper", NULL,
+ "Max value",
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:step-increment:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_STEP_INCREMENT,
+ g_param_spec_double ("step-increment", NULL,
+ "Step increment",
+ G_MINDOUBLE, G_MAXDOUBLE, 1.0,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:page-increment:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_PAGE_INCREMENT,
+ g_param_spec_double ("page-increment", NULL,
+ "Page increment",
+ G_MINDOUBLE, G_MAXDOUBLE, 10.0,
+ GIMP_PARAM_READWRITE));
+
+ /**
+ * GimpScaleEntry:digits:
+ *
+ * Since: 3.0
+ **/
+ g_object_class_install_property (object_class, PROP_DIGITS,
+ g_param_spec_uint ("digits", NULL,
+ "The number of decimal places to display",
+ 0, G_MAXUINT, 2,
+ GIMP_PARAM_READWRITE));
+}
+
+static void
+gimp_scale_entry_init (GimpScaleEntry *entry)
+{
+ entry->priv = gimp_scale_entry_get_instance_private (entry);
+}
+
+static void
+gimp_scale_entry_constructed (GObject *object)
+{
+ GimpScaleEntry *entry = GIMP_SCALE_ENTRY (object);
+ GtkAdjustment *adjustment;
+
+ /* Construction values are a bit random but should be properly
+ * overrided with expected values if the object was created with
+ * gimp_scale_entry_new().
+ */
+
+ entry->priv->label = gtk_label_new_with_mnemonic (NULL);
+ gtk_label_set_xalign (GTK_LABEL (entry->priv->label), 0.0);
+
+ adjustment = gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 0.0);
+
+ entry->priv->spinbutton = gimp_spin_button_new (adjustment, 2.0, 2.0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (entry->priv->spinbutton), TRUE);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (entry->priv->label), entry->priv->spinbutton);
+
+ entry->priv->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+ gtk_scale_set_draw_value (GTK_SCALE (entry->priv->scale), FALSE);
+ gtk_widget_set_hexpand (entry->priv->scale, TRUE);
+
+ gtk_grid_attach (GTK_GRID (entry), entry->priv->label, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (entry), entry->priv->scale, 1, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (entry), entry->priv->spinbutton, 2, 0, 1, 1);
+ gtk_widget_show (entry->priv->label);
+ gtk_widget_show (entry->priv->scale);
+ gtk_widget_show (entry->priv->spinbutton);
+
+ /* This is important to make this object into a property widget. It
+ * will allow config object to bind the "value" property of this
+ * widget, and therefore be updated automatically.
+ */
+ g_object_bind_property (G_OBJECT (adjustment), "value",
+ object, "value",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+gimp_scale_entry_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpScaleEntry *entry = GIMP_SCALE_ENTRY (object);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ {
+ /* This should not happen since the property is **not** set with
+ * G_PARAM_CONSTRUCT, hence the label should exist when the
+ * property is first set.
+ */
+ g_return_if_fail (entry->priv->label);
+
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (entry->priv->label),
+ g_value_get_string (value));
+ }
+ break;
+ case PROP_VALUE:
+ {
+ GtkSpinButton *spinbutton;
+ GtkAdjustment *adj;
+
+ g_return_if_fail (entry->priv->spinbutton);
+
+ /* Set on the spin button, because it might have a bigger
+ * range, hence shows the real value.
+ */
+ spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+
+ /* Avoid looping forever since we have bound this widget's
+ * "value" property with the spin button "value" property.
+ */
+ if (gtk_adjustment_get_value (adj) != g_value_get_double (value))
+ gtk_adjustment_set_value (adj, g_value_get_double (value));
+ }
+ break;
+ case PROP_LOWER:
+ {
+ GtkSpinButton *spinbutton;
+ GtkAdjustment *adj;
+
+ g_return_if_fail (entry->priv->spinbutton);
+
+ /* This sets the range only on the spin button which may share
+ * or not its adjustment with the scale.
+ * To change only the scale, see gimp_scale_entry_set_range().
+ */
+ spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ gtk_adjustment_set_lower (adj, g_value_get_double (value));
+ }
+ break;
+ case PROP_UPPER:
+ {
+ GtkSpinButton *spinbutton;
+ GtkAdjustment *adj;
+
+ g_return_if_fail (entry->priv->spinbutton);
+
+ spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ gtk_adjustment_set_upper (adj, g_value_get_double (value));
+ }
+ break;
+ case PROP_STEP_INCREMENT:
+ {
+ GtkSpinButton *spinbutton;
+ GtkAdjustment *adj;
+
+ g_return_if_fail (entry->priv->scale && entry->priv->spinbutton);
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (entry->priv->scale));
+ gtk_adjustment_set_step_increment (adj, g_value_get_double (value));
+
+ spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ if (adj != gtk_spin_button_get_adjustment (spinbutton))
+ gtk_adjustment_set_step_increment (gtk_spin_button_get_adjustment (spinbutton),
g_value_get_double (value));
+
+ g_object_set (entry->priv->spinbutton,
+ "climb-rate", g_value_get_double (value),
+ NULL);
+ }
+ break;
+ case PROP_PAGE_INCREMENT:
+ {
+ GtkSpinButton *spinbutton;
+ GtkAdjustment *adj;
+
+ g_return_if_fail (entry->priv->scale && entry->priv->spinbutton);
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (entry->priv->scale));
+ gtk_adjustment_set_page_increment (adj, g_value_get_double (value));
+
+ spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ if (adj != gtk_spin_button_get_adjustment (spinbutton))
+ gtk_adjustment_set_page_increment (gtk_spin_button_get_adjustment (spinbutton),
g_value_get_double (value));
+ }
+ break;
+ case PROP_DIGITS:
+ {
+ g_return_if_fail (entry->priv->scale && entry->priv->spinbutton);
+
+ gtk_scale_set_digits (GTK_SCALE (entry->priv->scale),
+ g_value_get_uint (value));
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (entry->priv->spinbutton),
+ g_value_get_uint (value));
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_scale_entry_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpScaleEntry *entry = GIMP_SCALE_ENTRY (object);
+ GtkSpinButton *spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ g_value_set_string (value, gtk_label_get_label (GTK_LABEL (entry->priv->label)));
+ break;
+ case PROP_VALUE:
+ g_value_set_double (value, gtk_spin_button_get_value (spinbutton));
+ break;
+ case PROP_LOWER:
+ {
+ GtkAdjustment *adj;
+
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ g_value_set_double (value, gtk_adjustment_get_lower (adj));
+ }
+ break;
+ case PROP_UPPER:
+ {
+ GtkAdjustment *adj;
+
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ g_value_set_double (value, gtk_adjustment_get_upper (adj));
+ }
+ break;
+ case PROP_STEP_INCREMENT:
+ {
+ GtkAdjustment *adj;
+
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ g_value_set_double (value, gtk_adjustment_get_step_increment (adj));
+ }
+ break;
+ case PROP_PAGE_INCREMENT:
+ {
+ GtkAdjustment *adj;
+
+ adj = gtk_spin_button_get_adjustment (spinbutton);
+ g_value_set_double (value, gtk_adjustment_get_page_increment (adj));
+ }
+ break;
+ case PROP_DIGITS:
+ g_value_set_uint (value, gtk_spin_button_get_digits (spinbutton));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
static gboolean
gimp_scale_entry_linear_to_log (GBinding *binding,
const GValue *from_value,
@@ -209,6 +573,172 @@ gimp_scale_entry_new_internal (gboolean color_scale,
return spin_adjustment;
}
+/**
+ * gimp_scale_entry_new2:
+ * @text: The text for the #GtkLabel which will appear left of
+ * the #GtkHScale.
+ * @value: The initial value.
+ * @lower: The lower boundary.
+ * @upper: The upper boundary.
+ * @step_increment: The step increment.
+ * @page_increment: The page increment.
+ * @digits: The number of decimal digits.
+ *
+ * This function creates a #GtkLabel, a #GtkHScale and a #GtkSpinButton and
+ * attaches them to a 3-column #GtkGrid.
+ *
+ * Returns: (transfer full): The new #GtkScaleEntry.
+ **/
+GtkWidget *
+gimp_scale_entry_new2 (const gchar *text,
+ gdouble value,
+ gdouble lower,
+ gdouble upper,
+ gdouble step_increment,
+ gdouble page_increment,
+ guint digits)
+{
+ GtkWidget *entry;
+
+ entry = g_object_new (GIMP_TYPE_SCALE_ENTRY,
+ "label", text,
+ "value", value,
+ "lower", lower,
+ "upper", upper,
+ "step-increment", step_increment,
+ "page-increment", page_increment,
+ "digits", digits,
+ NULL);
+
+ return entry;
+}
+
+
+/**
+ * gimp_scale_entry_get_label:
+ * @entry: The #GtkScaleEntry.
+ *
+ * This function returns the #GtkLabel packed in @entry. This can be
+ * useful if you need to customize some aspects of the widget.
+ *
+ * Returns: (transfer none): The new #GtkLabel contained in @entry.
+ **/
+GtkWidget *
+gimp_scale_entry_get_label (GimpScaleEntry *entry)
+{
+ return entry->priv->label;
+}
+
+/**
+ * gimp_scale_entry_get_spin_button:
+ * @entry: The #GtkScaleEntry.
+ *
+ * This function returns the #GtkSpinButton packed in @entry. This can
+ * be useful if you need to customize some aspects of the widget.
+ *
+ * Returns: (transfer none): The new #GtkSpinButton contained in @entry.
+ **/
+GtkWidget *
+gimp_scale_entry_get_spin_button (GimpScaleEntry *entry)
+{
+ return entry->priv->spinbutton;
+}
+
+/**
+ * gimp_scale_entry_get_scale:
+ * @entry: The #GtkScaleEntry.
+ *
+ * This function returns the #GtkScale packed in @entry. This can be
+ * useful if you need to customize some aspects of the widget
+ *
+ * Returns: (transfer none): The new #GtkScale contained in @entry.
+ **/
+GtkWidget *
+gimp_scale_entry_get_scale (GimpScaleEntry *entry)
+{
+ return entry->priv->scale;
+}
+
+/**
+ * gimp_scale_entry_set_range:
+ * @entry: The #GtkScaleEntry.
+ * @lower: the lower value for the whole widget if @limit_scale is
+ * %FALSE, or only for the #GtkScale if %TRUE.
+ * @upper: the upper value for the whole widget if @limit_scale is
+ * %FALSE, or only for the #GtkSpinButton if %TRUE.
+ * @limit_scale: Whether the range should only apply to the #GtkScale or
+ * if it should share its #GtkAdjustement with the
+ * #GtkScale. If %TRUE, both @lower and @upper must be
+ * included in current #GtkSpinButton range.
+ *
+ * By default the #GtkSpinButton and #GtkScale will have the same range
+ * (they will even share their GtkAdjustment). In some case, you want to
+ * set a different range. In particular when the finale range is huge,
+ * the #GtkScale might become nearly useless as every tiny slider move
+ * would dramatically update the value. In this case, it is common to
+ * set the #GtkScale to a smaller common range, while the #GtkSpinButton
+ * would allow for the full allowed range.
+ * This function allows this. Obviously the #GtkAdjustment of both
+ * widgets would be synced but if the set value is out of the #GtkScale
+ * range, the slider would simply show at one extreme.
+ *
+ * If @limit_scale is %FALSE though, it would sync back both widgets
+ * range to the new values.
+ **/
+void
+gimp_scale_entry_set_range (GimpScaleEntry *entry,
+ gdouble lower,
+ gdouble upper,
+ gboolean limit_scale)
+{
+ GtkSpinButton *spinbutton = GTK_SPIN_BUTTON (entry->priv->spinbutton);
+ GtkAdjustment *spin_adjustment;
+ GtkAdjustment *scale_adjustment;
+
+ spin_adjustment = gtk_spin_button_get_adjustment (spinbutton);
+ scale_adjustment = gtk_range_get_adjustment (GTK_RANGE (entry->priv->scale));
+
+ if (limit_scale)
+ {
+ g_return_if_fail (lower >= gtk_adjustment_get_lower (spin_adjustment) &&
+ upper <= gtk_adjustment_get_upper (spin_adjustment));
+
+ if (spin_adjustment == scale_adjustment)
+ {
+ scale_adjustment = gtk_adjustment_new (gtk_adjustment_get_value (spin_adjustment),
+ lower, upper,
+ gtk_adjustment_get_step_increment (spin_adjustment),
+ gtk_adjustment_get_page_increment (spin_adjustment),
+ gtk_adjustment_get_page_size (spin_adjustment));
+ gtk_range_set_adjustment (GTK_RANGE (entry->priv->scale), scale_adjustment);
+
+ entry->priv->binding = g_object_bind_property (G_OBJECT (spin_adjustment), "value",
+ G_OBJECT (scale_adjustment), "value",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+ }
+ else
+ {
+ gtk_adjustment_set_lower (scale_adjustment, lower);
+ gtk_adjustment_set_upper (scale_adjustment, upper);
+ }
+ }
+ else if (! limit_scale)
+ {
+ if (spin_adjustment != scale_adjustment)
+ {
+ g_clear_object (&entry->priv->binding);
+
+ gtk_range_set_adjustment (GTK_RANGE (entry->priv->scale), spin_adjustment);
+ }
+
+ g_object_set (entry,
+ "lower", lower,
+ "upper", upper,
+ NULL);
+ }
+}
+
/**
* gimp_scale_entry_new:
* @grid: The #GtkGrid the widgets will be attached to.
diff --git a/libgimpwidgets/gimpscaleentry.h b/libgimpwidgets/gimpscaleentry.h
index bdb810a4b6..76fd7defff 100644
--- a/libgimpwidgets/gimpscaleentry.h
+++ b/libgimpwidgets/gimpscaleentry.h
@@ -29,6 +29,58 @@
G_BEGIN_DECLS
+#define GIMP_TYPE_SCALE_ENTRY (gimp_scale_entry_get_type ())
+#define GIMP_SCALE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SCALE_ENTRY,
GimpScaleEntry))
+#define GIMP_SCALE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SCALE_ENTRY,
GimpScaleEntryClass))
+#define GIMP_IS_SCALE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_SCALE_ENTRY))
+#define GIMP_IS_SCALE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SCALE_ENTRY))
+#define GIMP_SCALE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SCALE_ENTRY,
GimpScaleEntryClass))
+
+
+typedef struct _GimpScaleEntryPrivate GimpScaleEntryPrivate;
+typedef struct _GimpScaleEntryClass GimpScaleEntryClass;
+
+struct _GimpScaleEntry
+{
+ GtkGrid parent_instance;
+
+ GimpScaleEntryPrivate *priv;
+};
+
+struct _GimpScaleEntryClass
+{
+ GtkGridClass parent_class;
+
+ /* Padding for future expansion */
+ void (* _gimp_reserved1) (void);
+ void (* _gimp_reserved2) (void);
+ void (* _gimp_reserved3) (void);
+ void (* _gimp_reserved4) (void);
+ void (* _gimp_reserved5) (void);
+ void (* _gimp_reserved6) (void);
+ void (* _gimp_reserved7) (void);
+ void (* _gimp_reserved8) (void);
+};
+
+GType gimp_scale_entry_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gimp_scale_entry_new2 (const gchar *text,
+ gdouble value,
+ gdouble lower,
+ gdouble upper,
+ gdouble step_increment,
+ gdouble page_increment,
+ guint digits);
+
+GtkWidget * gimp_scale_entry_get_label (GimpScaleEntry *entry);
+GtkWidget * gimp_scale_entry_get_spin_button (GimpScaleEntry *entry);
+GtkWidget * gimp_scale_entry_get_scale (GimpScaleEntry *entry);
+
+void gimp_scale_entry_set_range (GimpScaleEntry *entry,
+ gdouble lower,
+ gdouble upper,
+ gboolean limit_scale);
+
/**
* GIMP_SCALE_ENTRY_LABEL:
diff --git a/libgimpwidgets/gimpwidgetstypes.h b/libgimpwidgets/gimpwidgetstypes.h
index 0fea008b97..687f3efb53 100644
--- a/libgimpwidgets/gimpwidgetstypes.h
+++ b/libgimpwidgets/gimpwidgetstypes.h
@@ -70,6 +70,7 @@ typedef struct _GimpPickButton GimpPickButton;
typedef struct _GimpPreview GimpPreview;
typedef struct _GimpPreviewArea GimpPreviewArea;
typedef struct _GimpRuler GimpRuler;
+typedef struct _GimpScaleEntry GimpScaleEntry;
typedef struct _GimpScrolledPreview GimpScrolledPreview;
typedef struct _GimpSizeEntry GimpSizeEntry;
typedef struct _GimpSpinButton GimpSpinButton;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]