libgimpwidgets: new GimpLabeled class and GimpLabelSpin subclass.

There is currently no property widget which just creates a
GimpSpinButton with a label. Just as the GimpScaleEntry was needed, this
one is as well.
I am creating a GimpLabeled abstract class which will represent various
widgets with a label. While this may seem a bit over-engineered for such
a basic feature, this will actually bring some consistency and a common
parent. In particular this can be used to get the GtkLabel with a common
interface to add them all in a common GtkSizeGroup when generating
dialogs automatically, hence make dialogs with properly aligned labels
and edition widgets.
This commit is contained in:
Jehan 2020-11-05 01:13:49 +01:00
parent 3449652fe8
commit 4ea2b430be
10 changed files with 983 additions and 0 deletions

View File

@ -34,6 +34,8 @@ libgimpwidgets_introspectable_headers = \
../libgimpwidgets/gimpicons.h \
../libgimpwidgets/gimpintcombobox.h \
../libgimpwidgets/gimpintstore.h \
../libgimpwidgets/gimplabeled.h \
../libgimpwidgets/gimplabelspin.h \
../libgimpwidgets/gimpmemsizeentry.h \
../libgimpwidgets/gimpnumberpairentry.h \
../libgimpwidgets/gimpoffsetarea.h \
@ -95,6 +97,8 @@ libgimpwidgets_introspectable = \
../libgimpwidgets/gimpicons.c \
../libgimpwidgets/gimpintcombobox.c \
../libgimpwidgets/gimpintstore.c \
../libgimpwidgets/gimplabeled.c \
../libgimpwidgets/gimplabelspin.c \
../libgimpwidgets/gimpmemsizeentry.c \
../libgimpwidgets/gimpnumberpairentry.c \
../libgimpwidgets/gimpoffsetarea.c \

View File

@ -0,0 +1,243 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimplabeled.c
* Copyright (C) 2020 Jehan
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpbase/gimpbase.h"
#include "gimpwidgets.h"
/**
* SECTION: gimplabeled
* @title: GimpLabeled
* @short_description: Widget containing a label as mnemonic for another
* widget.
*
* This widget is a #GtkGrid showing a #GtkLabel used as mnemonic on
* another widget.
**/
enum
{
PROP_0,
PROP_LABEL,
};
typedef struct _GimpLabeledPrivate
{
GtkWidget *label;
GtkWidget *mnemonic_widget;
} GimpLabeledPrivate;
static void gimp_labeled_constructed (GObject *object);
static void gimp_labeled_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_labeled_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_TYPE_WITH_PRIVATE (GimpLabeled, gimp_labeled, GTK_TYPE_GRID)
#define parent_class gimp_labeled_parent_class
static void
gimp_labeled_class_init (GimpLabeledClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_labeled_constructed;
object_class->set_property = gimp_labeled_set_property;
object_class->get_property = gimp_labeled_get_property;
/**
* GimpLabeled:label:
*
* Label text with pango markup and mnemonic.
*
* 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));
}
static void
gimp_labeled_init (GimpLabeled *labeled)
{
}
static void
gimp_labeled_constructed (GObject *object)
{
GimpLabeledClass *klass;
GimpLabeled *labeled = GIMP_LABELED (object);
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (labeled);
gint x = 0;
gint y = 0;
gint width = 1;
gint height = 1;
G_OBJECT_CLASS (parent_class)->constructed (object);
priv->label = gtk_label_new_with_mnemonic (NULL);
gtk_label_set_xalign (GTK_LABEL (priv->label), 0.0);
klass = GIMP_LABELED_GET_CLASS (labeled);
g_return_if_fail (klass->populate);
priv->mnemonic_widget = klass->populate (labeled, &x, &y, &width, &height);
if (priv->mnemonic_widget)
gtk_label_set_mnemonic_widget (GTK_LABEL (priv->label), priv->mnemonic_widget);
gtk_grid_attach (GTK_GRID (labeled), priv->label, x, y, width, height);
gtk_widget_show (priv->label);
}
static void
gimp_labeled_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLabeled *entry = GIMP_LABELED (object);
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (entry);
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 (priv->label);
gtk_label_set_markup_with_mnemonic (GTK_LABEL (priv->label),
g_value_get_string (value));
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_labeled_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLabeled *entry = GIMP_LABELED (object);
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (entry);
switch (property_id)
{
case PROP_LABEL:
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->label)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* Public functions */
/**
* gimp_labeled_get_label:
* @labeled: The #GimpLabeled.
*
* This function returns the #GtkLabel packed in @labeled. This can be
* useful if you need to customize some aspects of the widget.
*
* Returns: (transfer none): The #GtkLabel contained in @labeled.
**/
GtkWidget *
gimp_labeled_get_label (GimpLabeled *labeled)
{
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (labeled);
g_return_val_if_fail (GIMP_IS_LABELED (labeled), NULL);
return priv->label;
}
/**
* gimp_labeled_get_text:
* @labeled: the #GimpLabeled.
*
* This function will return exactly what you entered with
* gimp_labeled_set_text() or through the "label" property because this
* class expects labels to have mnemonics (and allows Pango formatting).
* To obtain instead the text as displayed with mnemonics and markup
* removed, call:
* |[<!-- language="C" -->
* gtk_label_get_text (GTK_LABEL (gimp_labeled_get_label (@labeled)));
* ]|
*
* Returns: the label text as entered, which includes pango markup and
* mnemonics similarly to gtk_label_get_label().
*/
const gchar *
gimp_labeled_get_text (GimpLabeled *labeled)
{
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (labeled);
g_return_val_if_fail (GIMP_IS_LABELED (labeled), NULL);
return gtk_label_get_label (GTK_LABEL (priv->label));
}
/**
* gimp_labeled_set_text:
* @labeled: the #GimpLabeled.
* @text: label text with Pango markup and mnemonic.
*
* This is the equivalent of running
* gtk_label_set_markup_with_mnemonic() on the #GtkLabel as a
* #GimpLabeled expects a mnemonic. Pango markup are also allowed.
*/
void
gimp_labeled_set_text (GimpLabeled *labeled,
const gchar *text)
{
GimpLabeledPrivate *priv = gimp_labeled_get_instance_private (labeled);
g_return_if_fail (GIMP_IS_LABELED (labeled));
gtk_label_set_markup_with_mnemonic (GTK_LABEL (priv->label), text);
}

View File

@ -0,0 +1,79 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimplabeled.h
* Copyright (C) 2020 Jehan
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_WIDGETS_H_INSIDE__) && !defined (GIMP_WIDGETS_COMPILATION)
#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
#endif
#ifndef __GIMP_LABELED_H__
#define __GIMP_LABELED_H__
G_BEGIN_DECLS
#define GIMP_TYPE_LABELED (gimp_labeled_get_type ())
G_DECLARE_DERIVABLE_TYPE (GimpLabeled, gimp_labeled, GIMP, LABELED, GtkGrid)
struct _GimpLabeledClass
{
GtkGridClass parent_class;
/* Class methods */
/**
* GimpLabelledClass::populate:
*
* Fill the #GtkGrid with any necessary widget and sets the
* coordinates and dimensions the #GtkLabel should be attached to.
* By default, @x, @y, @width and @height will be pre-filled with 0,
* 0, 1 and 1 respectively, i.e. the top-left of the grid. There is no
* need to edit these output variables unless your subclass wants the
* label to be placed elsewhere.
*
* Returns: (transfer none): the #GtkWidget which the label must be
* set as mnemonic to.
**/
GtkWidget * (* populate) (GimpLabeled *labeled,
gint *x,
gint *y,
gint *width,
gint *height);
/* 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);
};
GtkWidget * gimp_labeled_get_label (GimpLabeled *labeled);
const gchar * gimp_labeled_get_text (GimpLabeled *labeled);
void gimp_labeled_set_text (GimpLabeled *labeled,
const gchar *text);
G_END_DECLS
#endif /* __GIMP_LABELED_H__ */

View File

@ -0,0 +1,527 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimplabelspin.c
* Copyright (C) 2020 Jehan
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpbase/gimpbase.h"
#include "gimpwidgets.h"
/**
* SECTION: gimplabelspin
* @title: GimpLabelSpin
* @short_description: Widget containing a spin button and a label.
*
* This widget is a subclass of #GimpLabeled with a #GimpSpinButton.
**/
enum
{
VALUE_CHANGED,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_VALUE,
PROP_LOWER,
PROP_UPPER,
PROP_DIGITS,
};
typedef struct _GimpLabelSpinPrivate
{
GimpLabeled parent_instance;
GtkWidget *spinbutton;
GtkAdjustment *spin_adjustment;
} GimpLabelSpinPrivate;
static void gimp_label_spin_constructed (GObject *object);
static void gimp_label_spin_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_label_spin_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static GtkWidget * gimp_label_spin_populate (GimpLabeled *spin,
gint *x,
gint *y,
gint *width,
gint *height);
static void gimp_label_spin_update_spin_width (GimpLabelSpin *spin);
static void gimp_label_spin_update_increments (GimpLabelSpin *spin);
G_DEFINE_TYPE_WITH_PRIVATE (GimpLabelSpin, gimp_label_spin, GIMP_TYPE_LABELED)
#define parent_class gimp_label_spin_parent_class
static guint gimp_label_spin_signals[LAST_SIGNAL] = { 0 };
static void
gimp_label_spin_class_init (GimpLabelSpinClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpLabeledClass *labeled_class = GIMP_LABELED_CLASS (klass);
gimp_label_spin_signals[VALUE_CHANGED] =
g_signal_new ("value-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpLabelSpinClass, value_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
object_class->constructed = gimp_label_spin_constructed;
object_class->set_property = gimp_label_spin_set_property;
object_class->get_property = gimp_label_spin_get_property;
labeled_class->populate = gimp_label_spin_populate;
/**
* GimpLabelSpin:value:
*
* The currently set 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));
/**
* GimpLabelSpin:lower:
*
* The lower bound of the spin button.
*
* 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 |
G_PARAM_CONSTRUCT));
/**
* GimpLabelSpin:upper:
*
* The upper bound of the spin button.
*
* 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 |
G_PARAM_CONSTRUCT));
/**
* GimpLabelSpin:digits:
*
* The number of decimal places to display.
*
* 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_label_spin_init (GimpLabelSpin *spin)
{
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
/* We want the adjustment to exist at init so that construction
* properties can apply (default values are bogus but should be
* properly overrided with expected values if the object was created
* with gimp_label_spin_new().
*/
priv->spin_adjustment = gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 0.0);
gtk_grid_set_row_spacing (GTK_GRID (spin), 6);
gtk_grid_set_column_spacing (GTK_GRID (spin), 6);
}
static void
gimp_label_spin_constructed (GObject *object)
{
GimpLabelSpin *spin = GIMP_LABEL_SPIN (object);
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
G_OBJECT_CLASS (parent_class)->constructed (object);
/* 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 (priv->spin_adjustment), "value",
G_OBJECT (spin), "value",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
gimp_label_spin_update_spin_width (spin);
gimp_label_spin_update_increments (spin);
}
static void
gimp_label_spin_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLabelSpin *spin = GIMP_LABEL_SPIN (object);
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
switch (property_id)
{
case PROP_VALUE:
/* Avoid looping forever since we have bound this widget's
* "value" property with the spin button "value" property.
*/
if (gtk_adjustment_get_value (priv->spin_adjustment) != g_value_get_double (value))
gtk_adjustment_set_value (priv->spin_adjustment, g_value_get_double (value));
g_signal_emit (object, gimp_label_spin_signals[VALUE_CHANGED], 0);
break;
case PROP_LOWER:
gtk_adjustment_set_lower (priv->spin_adjustment,
g_value_get_double (value));
if (priv->spinbutton)
{
gimp_label_spin_update_spin_width (spin);
gimp_label_spin_update_increments (spin);
}
break;
case PROP_UPPER:
gtk_adjustment_set_upper (priv->spin_adjustment,
g_value_get_double (value));
if (priv->spinbutton)
{
gimp_label_spin_update_spin_width (spin);
gimp_label_spin_update_increments (spin);
}
break;
case PROP_DIGITS:
if (priv->spinbutton)
{
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->spinbutton),
g_value_get_uint (value));
gimp_label_spin_update_spin_width (spin);
gimp_label_spin_update_increments (spin);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_label_spin_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLabelSpin *spin = GIMP_LABEL_SPIN (object);
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
GtkSpinButton *spinbutton = GTK_SPIN_BUTTON (priv->spinbutton);
switch (property_id)
{
case PROP_VALUE:
g_value_set_double (value, gtk_adjustment_get_value (priv->spin_adjustment));
break;
case PROP_LOWER:
g_value_set_double (value, gtk_adjustment_get_lower (priv->spin_adjustment));
break;
case PROP_UPPER:
g_value_set_double (value, gtk_adjustment_get_upper (priv->spin_adjustment));
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 GtkWidget *
gimp_label_spin_populate (GimpLabeled *labeled,
gint *x,
gint *y,
gint *width,
gint *height)
{
GimpLabelSpin *spin = GIMP_LABEL_SPIN (labeled);
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
priv->spinbutton = gimp_spin_button_new (priv->spin_adjustment, 2.0, 2.0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (priv->spinbutton), TRUE);
gtk_grid_attach (GTK_GRID (spin), priv->spinbutton, 1, 0, 1, 1);
gtk_widget_show (priv->spinbutton);
return priv->spinbutton;
}
static void
gimp_label_spin_update_spin_width (GimpLabelSpin *spin)
{
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
gint width = 0;
gdouble lower;
gdouble upper;
gint digits;
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
g_object_get (spin,
"lower", &lower,
"upper", &upper,
"digits", &digits,
NULL);
/* Necessary size to display the max/min integer values, with optional
* negative sign.
*/
width = (gint) floor (log10 (upper) + 1) + (upper < 0.0 ? 1 : 0);
width = MAX (width, (gint) floor (log10 (lower) + 1) + (lower < 0.0 ? 1 : 0));
/* Adding decimal digits and separator. */
width += (digits > 0 ? 1 + digits : 0);
/* Overlong spin button are useless. */
width = MIN (10, width);
gtk_entry_set_width_chars (GTK_ENTRY (priv->spinbutton), width);
}
static void
gimp_label_spin_update_increments (GimpLabelSpin *spin)
{
gdouble lower;
gdouble upper;
gdouble range;
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
g_object_get (spin,
"lower", &lower,
"upper", &upper,
NULL);
g_return_if_fail (upper >= lower);
range = upper - lower;
if (range > 0 && range <= 1.0)
{
gdouble places = 10.0;
gdouble step;
gdouble page;
/* Compute some acceptable step and page increments always in the
* format `10**-X` where X is the rounded precision.
* So for instance:
* 0.8 will have increments 0.01 and 0.1.
* 0.3 will have increments 0.001 and 0.01.
* 0.06 will also have increments 0.001 and 0.01.
*/
while (range * places < 5.0)
places *= 10.0;
step = 0.1 / places;
page = 1.0 / places;
gimp_label_spin_set_increments (spin, step, page);
}
else if (range <= 2.0)
{
gimp_label_spin_set_increments (spin, 0.01, 0.1);
}
else if (range <= 5.0)
{
gimp_label_spin_set_increments (spin, 0.1, 1.0);
}
else if (range <= 40.0)
{
gimp_label_spin_set_increments (spin, 1.0, 2.0);
}
else
{
gimp_label_spin_set_increments (spin, 1.0, 10.0);
}
}
/* Public Functions */
/**
* gimp_label_spin_new:
* @text: The text for the #GtkLabel.
* @value: The initial value.
* @lower: The lower boundary.
* @upper: The upper boundary.
* @digits: The number of decimal digits.
*
* Returns: (transfer full): The new #GimpLabelSpin widget.
**/
GtkWidget *
gimp_label_spin_new (const gchar *text,
gdouble value,
gdouble lower,
gdouble upper,
guint digits)
{
GtkWidget *labeled;
labeled = g_object_new (GIMP_TYPE_LABEL_SPIN,
"label", text,
"value", value,
"lower", lower,
"upper", upper,
"digits", digits,
NULL);
return labeled;
}
/**
* gimp_label_spin_set_value:
* @spin: The #GtkLabelSpin.
* @value: A new value.
*
* This function sets the value shown by @spin.
**/
void
gimp_label_spin_set_value (GimpLabelSpin *spin,
gdouble value)
{
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
g_object_set (spin,
"value", value,
NULL);
}
/**
* gimp_label_spin_get_value:
* @spin: The #GtkLabelSpin.
*
* This function returns the value shown by @spin.
*
* Returns: The value currently set.
**/
gdouble
gimp_label_spin_get_value (GimpLabelSpin *spin)
{
gdouble value;
g_return_val_if_fail (GIMP_IS_LABEL_SPIN (spin), 0.0);
g_object_get (spin,
"value", &value,
NULL);
return value;
}
/**
* gimp_label_spin_set_increments:
* @spin: the #GimpLabelSpin.
* @step: the step increment.
* @page: the page increment.
*
* Set the step and page increments of the spin button.
* By default, these increment values are automatically computed
* depending on the range based on common usage. So you will likely not
* need to run this for most case. Yet if you want specific increments
* (which the widget cannot guess), you can call this function.
*/
void
gimp_label_spin_set_increments (GimpLabelSpin *spin,
gdouble step,
gdouble page)
{
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
GtkSpinButton *spinbutton;
gdouble lower;
gdouble upper;
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
g_return_if_fail (step < page);
spinbutton = GTK_SPIN_BUTTON (priv->spinbutton);
gtk_spin_button_get_range (spinbutton, &lower, &upper);
g_return_if_fail (upper >= lower);
g_return_if_fail (step < upper - lower && page < upper - lower);
g_object_freeze_notify (G_OBJECT (spinbutton));
gtk_adjustment_set_step_increment (gtk_spin_button_get_adjustment (spinbutton), step);
gtk_adjustment_set_page_increment (gtk_spin_button_get_adjustment (spinbutton), page);
g_object_thaw_notify (G_OBJECT (spinbutton));
g_object_set (priv->spinbutton,
"climb-rate", step,
NULL);
}
/**
* gimp_label_spin_get_spin_button:
* @spin: The #GimpLabelSpin
*
* This function returns the #GimpSpinButton packed in @spin.
*
* Returns: (transfer none): The #GimpSpinButton contained in @spin.
**/
GtkWidget *
gimp_label_spin_get_spin_button (GimpLabelSpin *spin)
{
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
g_return_val_if_fail (GIMP_IS_LABEL_SPIN (spin), NULL);
return priv->spinbutton;
}

View File

@ -0,0 +1,72 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpcolorscaleentry.h
* Copyright (C) 2020 Jehan
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_WIDGETS_H_INSIDE__) && !defined (GIMP_WIDGETS_COMPILATION)
#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
#endif
#ifndef __GIMP_LABEL_SPIN_H__
#define __GIMP_LABEL_SPIN_H__
#include <libgimpwidgets/gimplabeled.h>
G_BEGIN_DECLS
#define GIMP_TYPE_LABEL_SPIN (gimp_label_spin_get_type ())
G_DECLARE_DERIVABLE_TYPE (GimpLabelSpin, gimp_label_spin, GIMP, LABEL_SPIN, GimpLabeled)
struct _GimpLabelSpinClass
{
GimpLabeledClass parent_class;
/* Signals */
void (* value_changed) (GimpLabelSpin *spin);
/* 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);
};
GtkWidget * gimp_label_spin_new (const gchar *text,
gdouble value,
gdouble lower,
gdouble upper,
guint digits);
void gimp_label_spin_set_value (GimpLabelSpin *spin,
gdouble value);
gdouble gimp_label_spin_get_value (GimpLabelSpin *spin);
void gimp_label_spin_set_increments (GimpLabelSpin *spin,
gdouble step,
gdouble page);
GtkWidget * gimp_label_spin_get_spin_button (GimpLabelSpin *spin);
G_END_DECLS
#endif /* __GIMP_LABEL_SPIN_H__ */

View File

@ -1395,6 +1395,51 @@ gimp_prop_spin_button_new (GObject *config,
return spinbutton;
}
/**
* gimp_prop_label_spin_new:
* @config: Object to which property is attached.
* @digits: Number of digits after decimal point to display.
*
* Creates a #GimpLabelSpin to set and display the value of the
* specified double property.
*
* Returns: (transfer full): A new #libgimpwidgets-gimpspinbutton.
*
* Since: 2.4
*/
GtkWidget *
gimp_prop_label_spin_new (GObject *config,
const gchar *property_name,
gint digits)
{
const gchar *label;
GParamSpec *param_spec;
GtkWidget *widget;
gdouble value;
gdouble lower;
gdouble upper;
param_spec = find_param_spec (config, property_name, G_STRFUNC);
if (! param_spec)
return NULL;
if (! get_numeric_values (config,
param_spec, &value, &lower, &upper, G_STRFUNC))
return NULL;
if (! G_IS_PARAM_SPEC_DOUBLE (param_spec))
digits = 0;
label = g_param_spec_get_nick (param_spec);
widget = gimp_label_spin_new (label, value, lower, upper, digits);
g_object_bind_property (config, property_name,
widget, "value",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
return widget;
}
/**
* gimp_prop_hscale_new:
* @config: Object to which property is attached.

View File

@ -114,6 +114,11 @@ GtkWidget * gimp_prop_spin_button_new (GObject *config,
gdouble page_increment,
gint digits);
GtkWidget * gimp_prop_label_spin_new (GObject *config,
const gchar *property_name,
gint digits);
GtkWidget * gimp_prop_hscale_new (GObject *config,
const gchar *property_name,
gdouble step_increment,

View File

@ -61,6 +61,8 @@
#include <libgimpwidgets/gimpicons.h>
#include <libgimpwidgets/gimpintcombobox.h>
#include <libgimpwidgets/gimpintstore.h>
#include <libgimpwidgets/gimplabeled.h>
#include <libgimpwidgets/gimplabelspin.h>
#include <libgimpwidgets/gimpmemsizeentry.h>
#include <libgimpwidgets/gimpnumberpairentry.h>
#include <libgimpwidgets/gimpoffsetarea.h>

View File

@ -62,6 +62,8 @@ typedef struct _GimpFrame GimpFrame;
typedef struct _GimpHintBox GimpHintBox;
typedef struct _GimpIntComboBox GimpIntComboBox;
typedef struct _GimpIntStore GimpIntStore;
typedef struct _GimpLabeled GimpLabeled;
typedef struct _GimpLabelSpin GimpLabelSpin;
typedef struct _GimpMemsizeEntry GimpMemsizeEntry;
typedef struct _GimpNumberPairEntry GimpNumberPairEntry;
typedef struct _GimpOffsetArea GimpOffsetArea;

View File

@ -54,6 +54,8 @@ libgimpwidgets_sources_introspectable = files(
'gimpicons.c',
'gimpintcombobox.c',
'gimpintstore.c',
'gimplabeled.c',
'gimplabelspin.c',
'gimpmemsizeentry.c',
'gimpnumberpairentry.c',
'gimpoffsetarea.c',
@ -126,6 +128,8 @@ libgimpwidgets_headers_introspectable = files(
'gimphintbox.h',
'gimpicons.h',
'gimpintcombobox.h',
'gimplabeled.h',
'gimplabelspin.h',
'gimpintstore.h',
'gimpmemsizeentry.h',
'gimpnumberpairentry.h',