2003-10-01 07:19:48 +08:00
|
|
|
/* LIBGIMP - The GIMP Library
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
1998-12-05 11:38:13 +08:00
|
|
|
*
|
2000-02-26 11:41:06 +08:00
|
|
|
* gimpsizeentry.c
|
|
|
|
* Copyright (C) 1999-2000 Sven Neumann <sven@gimp.org>
|
2003-10-01 07:19:48 +08:00
|
|
|
* Michael Natterer <mitch@gimp.org>
|
2000-02-26 11:41:06 +08:00
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This library is free software: you can redistribute it and/or
|
1999-11-18 05:13:50 +08:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
1998-12-05 11:38:13 +08:00
|
|
|
* License as published by the Free Software Foundation; either
|
2009-01-18 06:28:01 +08:00
|
|
|
* version 3 of the License, or (at your option) any later version.
|
2003-10-01 07:19:48 +08:00
|
|
|
*
|
|
|
|
* 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
|
1998-12-05 11:38:13 +08:00
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
1999-11-18 05:13:50 +08:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2009-01-18 06:28:01 +08:00
|
|
|
* License along with this library. If not, see
|
2018-07-12 05:27:07 +08:00
|
|
|
* <https://www.gnu.org/licenses/>.
|
1999-02-25 02:30:58 +08:00
|
|
|
*/
|
2000-02-08 04:35:13 +08:00
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2013-11-02 05:32:06 +08:00
|
|
|
#include <gegl.h>
|
2000-05-31 07:38:46 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2001-05-21 21:58:46 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2001-01-25 06:36:18 +08:00
|
|
|
|
2005-04-19 07:38:25 +08:00
|
|
|
#include "gimpwidgets.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
#include "gimpeevl.h"
|
1999-02-22 05:45:50 +08:00
|
|
|
#include "gimpsizeentry.h"
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2000-05-31 07:38:46 +08:00
|
|
|
|
2010-07-06 00:01:28 +08:00
|
|
|
/**
|
|
|
|
* SECTION: gimpsizeentry
|
|
|
|
* @title: GimpSizeEntry
|
|
|
|
* @short_description: Widget for entering pixel values and resolutions.
|
2010-10-15 05:03:34 +08:00
|
|
|
* @see_also: #GimpUnit, #GimpUnitComboBox, gimp_coordinates_new()
|
2010-07-06 00:01:28 +08:00
|
|
|
*
|
|
|
|
* This widget is used to enter pixel distances/sizes and resolutions.
|
|
|
|
*
|
|
|
|
* You can specify the number of fields the widget should provide. For
|
|
|
|
* each field automatic mappings are performed between the field's
|
|
|
|
* "reference value" and its "value".
|
|
|
|
*
|
2010-10-15 05:03:34 +08:00
|
|
|
* There is a #GimpUnitComboBox right of the entry fields which lets
|
|
|
|
* you specify the #GimpUnit of the displayed values.
|
2010-07-06 00:01:28 +08:00
|
|
|
*
|
|
|
|
* For each field, there can be one or two #GtkSpinButton's to enter
|
|
|
|
* "value" and "reference value". If you specify @show_refval as
|
2019-08-03 06:04:28 +08:00
|
|
|
* %FALSE in gimp_size_entry_new() there will be only one
|
2010-10-15 05:03:34 +08:00
|
|
|
* #GtkSpinButton and the #GimpUnitComboBox will contain an item for
|
2010-07-06 00:01:28 +08:00
|
|
|
* selecting GIMP_UNIT_PIXEL.
|
|
|
|
*
|
|
|
|
* The "reference value" is either of GIMP_UNIT_PIXEL or dpi,
|
|
|
|
* depending on which #GimpSizeEntryUpdatePolicy you specify in
|
|
|
|
* gimp_size_entry_new(). The "value" is either the size in pixels
|
|
|
|
* mapped to the size in a real-world-unit (see #GimpUnit) or the dpi
|
|
|
|
* value mapped to pixels per real-world-unit.
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
1999-04-05 20:48:48 +08:00
|
|
|
#define SIZE_MAX_VALUE 500000.0
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2003-11-16 06:53:28 +08:00
|
|
|
#define GIMP_SIZE_ENTRY_DIGITS(unit) (MIN (gimp_unit_get_digits (unit), 5) + 1)
|
2000-10-24 08:00:31 +08:00
|
|
|
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
enum
|
|
|
|
{
|
1999-06-18 03:13:08 +08:00
|
|
|
VALUE_CHANGED,
|
|
|
|
REFVAL_CHANGED,
|
|
|
|
UNIT_CHANGED,
|
1998-12-05 11:38:13 +08:00
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
typedef struct _GimpSizeEntryField
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
GimpSizeEntry *gse;
|
|
|
|
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble resolution;
|
|
|
|
gdouble lower;
|
|
|
|
gdouble upper;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2010-10-20 00:37:00 +08:00
|
|
|
GtkAdjustment *value_adjustment;
|
1999-02-25 02:30:58 +08:00
|
|
|
GtkWidget *value_spinbutton;
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble value;
|
|
|
|
gdouble min_value;
|
|
|
|
gdouble max_value;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2010-10-20 00:37:00 +08:00
|
|
|
GtkAdjustment *refval_adjustment;
|
1999-02-25 02:30:58 +08:00
|
|
|
GtkWidget *refval_spinbutton;
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble refval;
|
|
|
|
gdouble min_refval;
|
|
|
|
gdouble max_refval;
|
1999-03-12 11:44:59 +08:00
|
|
|
gint refval_digits;
|
1999-05-05 01:20:05 +08:00
|
|
|
|
|
|
|
gint stop_recursion;
|
2024-08-01 11:55:31 +08:00
|
|
|
} GimpSizeEntryField;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2000-10-24 08:00:31 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
typedef struct _GimpSizeEntryPrivate
|
2018-05-25 10:08:59 +08:00
|
|
|
{
|
|
|
|
GSList *fields;
|
|
|
|
gint number_of_fields;
|
|
|
|
|
|
|
|
GtkWidget *unit_combo;
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit;
|
2018-05-25 10:08:59 +08:00
|
|
|
gboolean menu_show_pixels;
|
|
|
|
gboolean menu_show_percent;
|
|
|
|
|
|
|
|
gboolean show_refval;
|
|
|
|
GimpSizeEntryUpdatePolicy update_policy;
|
2024-08-01 11:55:31 +08:00
|
|
|
} GimpSizeEntryPrivate;
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
static void gimp_size_entry_finalize (GObject *object);
|
|
|
|
static void gimp_size_entry_update_value (GimpSizeEntryField *gsef,
|
|
|
|
gdouble value);
|
2018-06-25 00:15:16 +08:00
|
|
|
static void gimp_size_entry_value_callback (GtkAdjustment *adjustment,
|
2009-05-17 17:33:35 +08:00
|
|
|
gpointer data);
|
|
|
|
static void gimp_size_entry_update_refval (GimpSizeEntryField *gsef,
|
|
|
|
gdouble refval);
|
2018-06-25 00:15:16 +08:00
|
|
|
static void gimp_size_entry_refval_callback (GtkAdjustment *adjustment,
|
2009-05-17 17:33:35 +08:00
|
|
|
gpointer data);
|
|
|
|
static void gimp_size_entry_update_unit (GimpSizeEntry *gse,
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit);
|
2009-05-17 17:33:35 +08:00
|
|
|
static void gimp_size_entry_unit_callback (GtkWidget *widget,
|
|
|
|
GimpSizeEntry *sizeentry);
|
|
|
|
static void gimp_size_entry_attach_eevl (GtkSpinButton *spin_button,
|
|
|
|
GimpSizeEntryField *gsef);
|
|
|
|
static gint gimp_size_entry_eevl_input_callback (GtkSpinButton *spinner,
|
|
|
|
gdouble *return_val,
|
|
|
|
gpointer *data);
|
|
|
|
static gboolean gimp_size_entry_eevl_unit_resolver (const gchar *ident,
|
2020-01-06 17:41:25 +08:00
|
|
|
GimpEevlQuantity *factor,
|
|
|
|
gdouble *offset,
|
2009-05-17 17:33:35 +08:00
|
|
|
gpointer data);
|
2000-10-24 08:00:31 +08:00
|
|
|
|
|
|
|
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-19 00:09:39 +08:00
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpSizeEntry, gimp_size_entry, GTK_TYPE_GRID)
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2005-12-21 04:35:23 +08:00
|
|
|
#define parent_class gimp_size_entry_parent_class
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
|
2005-12-21 04:35:23 +08:00
|
|
|
static guint gimp_size_entry_signals[LAST_SIGNAL] = { 0 };
|
2003-10-01 07:19:48 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1998-12-05 11:38:13 +08:00
|
|
|
static void
|
2001-01-25 06:36:18 +08:00
|
|
|
gimp_size_entry_class_init (GimpSizeEntryClass *klass)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2005-12-21 04:35:23 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
|
|
|
|
gimp_size_entry_signals[VALUE_CHANGED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("value-changed",
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpSizeEntryClass, value_changed),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_NONE, 0);
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
|
|
|
|
gimp_size_entry_signals[REFVAL_CHANGED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("refval-changed",
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpSizeEntryClass, refval_changed),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_NONE, 0);
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
|
|
|
|
gimp_size_entry_signals[UNIT_CHANGED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("unit-changed",
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpSizeEntryClass, unit_changed),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2006-04-12 18:53:28 +08:00
|
|
|
G_TYPE_NONE, 0);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2001-09-21 18:47:19 +08:00
|
|
|
object_class->finalize = gimp_size_entry_finalize;
|
2001-01-25 06:36:18 +08:00
|
|
|
|
2001-09-21 18:47:19 +08:00
|
|
|
klass->value_changed = NULL;
|
|
|
|
klass->refval_changed = NULL;
|
|
|
|
klass->unit_changed = NULL;
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_size_entry_init (GimpSizeEntry *gse)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
priv->unit = gimp_unit_pixel ();
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->menu_show_pixels = TRUE;
|
|
|
|
priv->menu_show_percent = TRUE;
|
|
|
|
priv->show_refval = FALSE;
|
|
|
|
priv->update_policy = GIMP_SIZE_ENTRY_UPDATE_NONE;
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
2001-08-04 03:52:08 +08:00
|
|
|
static void
|
2001-09-21 18:47:19 +08:00
|
|
|
gimp_size_entry_finalize (GObject *object)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntry *gse = GIMP_SIZE_ENTRY (object);
|
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2001-08-04 03:52:08 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->fields)
|
2001-08-04 03:52:08 +08:00
|
|
|
{
|
2007-05-22 19:49:24 +08:00
|
|
|
GSList *list;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
for (list = priv->fields; list; list = list->next)
|
2007-05-22 19:49:24 +08:00
|
|
|
g_slice_free (GimpSizeEntryField, list->data);
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
g_slist_free (priv->fields);
|
|
|
|
priv->fields = NULL;
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
2001-08-04 03:52:08 +08:00
|
|
|
|
2001-09-21 18:47:19 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_new:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @number_of_fields: The number of input fields.
|
|
|
|
* @unit: The initial unit.
|
2003-02-07 05:17:12 +08:00
|
|
|
* @unit_format: A printf-like unit-format string as is used with
|
|
|
|
* gimp_unit_menu_new().
|
2017-06-25 20:06:05 +08:00
|
|
|
* @menu_show_pixels: %TRUE if the unit menu should contain an item for
|
2001-08-04 03:52:08 +08:00
|
|
|
* GIMP_UNIT_PIXEL (ignored if the @update_policy is not
|
|
|
|
* GIMP_SIZE_ENTRY_UPDATE_NONE).
|
2017-06-25 20:06:05 +08:00
|
|
|
* @menu_show_percent: %TRUE if the unit menu should contain an item for
|
2000-02-08 04:35:13 +08:00
|
|
|
* GIMP_UNIT_PERCENT.
|
2004-02-16 15:16:41 +08:00
|
|
|
* @show_refval: %TRUE if you want an extra "reference value"
|
2001-08-04 03:52:08 +08:00
|
|
|
* spinbutton per input field.
|
2001-11-12 02:35:25 +08:00
|
|
|
* @spinbutton_width: The minimal horizontal size of the #GtkSpinButton's.
|
2003-02-07 05:17:12 +08:00
|
|
|
* @update_policy: How the automatic pixel <-> real-world-unit
|
|
|
|
* calculations should be done.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* Creates a new #GimpSizeEntry widget.
|
|
|
|
*
|
|
|
|
* To have all automatic calculations performed correctly, set up the
|
|
|
|
* widget in the following order:
|
|
|
|
*
|
|
|
|
* 1. gimp_size_entry_new()
|
|
|
|
*
|
|
|
|
* 2. (for each additional input field) gimp_size_entry_add_field()
|
|
|
|
*
|
|
|
|
* 3. gimp_size_entry_set_unit()
|
|
|
|
*
|
|
|
|
* For each input field:
|
|
|
|
*
|
|
|
|
* 4. gimp_size_entry_set_resolution()
|
|
|
|
*
|
|
|
|
* 5. gimp_size_entry_set_refval_boundaries()
|
|
|
|
* (or gimp_size_entry_set_value_boundaries())
|
|
|
|
*
|
|
|
|
* 6. gimp_size_entry_set_size()
|
|
|
|
*
|
|
|
|
* 7. gimp_size_entry_set_refval() (or gimp_size_entry_set_value())
|
|
|
|
*
|
2018-05-03 02:23:05 +08:00
|
|
|
* The #GimpSizeEntry is derived from #GtkGrid and will have
|
2000-02-08 04:35:13 +08:00
|
|
|
* an empty border of one cell width on each side plus an empty column left
|
2010-10-15 05:03:34 +08:00
|
|
|
* of the #GimpUnitComboBox to allow the caller to add labels or a
|
2003-02-07 05:17:12 +08:00
|
|
|
* #GimpChainButton.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* Returns: A Pointer to the new #GimpSizeEntry widget.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
2000-02-08 04:35:13 +08:00
|
|
|
GtkWidget *
|
|
|
|
gimp_size_entry_new (gint number_of_fields,
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit,
|
2006-04-12 18:53:28 +08:00
|
|
|
const gchar *unit_format,
|
|
|
|
gboolean menu_show_pixels,
|
|
|
|
gboolean menu_show_percent,
|
|
|
|
gboolean show_refval,
|
|
|
|
gint spinbutton_width,
|
|
|
|
GimpSizeEntryUpdatePolicy update_policy)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntry *gse;
|
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpUnitStore *store;
|
|
|
|
gint i;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-05-19 01:33:39 +08:00
|
|
|
g_return_val_if_fail ((number_of_fields >= 0) && (number_of_fields <= 16),
|
2006-04-12 18:53:28 +08:00
|
|
|
NULL);
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2001-08-10 22:41:39 +08:00
|
|
|
gse = g_object_new (GIMP_TYPE_SIZE_ENTRY, NULL);
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
priv->number_of_fields = number_of_fields;
|
|
|
|
priv->unit = unit;
|
|
|
|
priv->show_refval = show_refval;
|
|
|
|
priv->update_policy = update_policy;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
/* show the 'pixels' menu entry only if we are a 'size' sizeentry and
|
|
|
|
* don't have the reference value spinbutton
|
|
|
|
*/
|
1999-04-05 20:48:48 +08:00
|
|
|
if ((update_policy == GIMP_SIZE_ENTRY_UPDATE_RESOLUTION) ||
|
|
|
|
(show_refval == TRUE))
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->menu_show_pixels = FALSE;
|
1999-03-12 11:44:59 +08:00
|
|
|
else
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->menu_show_pixels = menu_show_pixels;
|
1999-03-12 11:44:59 +08:00
|
|
|
|
1999-04-05 20:48:48 +08:00
|
|
|
/* show the 'percent' menu entry only if we are a 'size' sizeentry
|
|
|
|
*/
|
|
|
|
if (update_policy == GIMP_SIZE_ENTRY_UPDATE_RESOLUTION)
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->menu_show_percent = FALSE;
|
1999-04-05 20:48:48 +08:00
|
|
|
else
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->menu_show_percent = menu_show_percent;
|
1999-04-05 20:48:48 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
for (i = 0; i < number_of_fields; i++)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2007-05-22 19:49:24 +08:00
|
|
|
GimpSizeEntryField *gsef = g_slice_new0 (GimpSizeEntryField);
|
2005-04-17 23:28:28 +08:00
|
|
|
gint digits;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->fields = g_slist_append (priv->fields, gsef);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2002-05-28 00:56:28 +08:00
|
|
|
gsef->gse = gse;
|
|
|
|
gsef->resolution = 1.0; /* just to avoid division by zero */
|
|
|
|
gsef->lower = 0.0;
|
|
|
|
gsef->upper = 100.0;
|
|
|
|
gsef->value = 0;
|
|
|
|
gsef->min_value = 0;
|
|
|
|
gsef->max_value = SIZE_MAX_VALUE;
|
1999-04-03 03:46:59 +08:00
|
|
|
gsef->refval_adjustment = NULL;
|
2002-05-28 00:56:28 +08:00
|
|
|
gsef->value_adjustment = NULL;
|
|
|
|
gsef->refval = 0;
|
|
|
|
gsef->min_refval = 0;
|
|
|
|
gsef->max_refval = SIZE_MAX_VALUE;
|
2003-10-01 07:19:48 +08:00
|
|
|
gsef->refval_digits =
|
2006-04-12 18:53:28 +08:00
|
|
|
(update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE) ? 0 : 3;
|
2002-05-28 00:56:28 +08:00
|
|
|
gsef->stop_recursion = 0;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
digits = ((unit == gimp_unit_pixel ()) ?
|
|
|
|
gsef->refval_digits : ((unit == gimp_unit_percent ()) ?
|
2005-04-17 23:28:28 +08:00
|
|
|
2 : GIMP_SIZE_ENTRY_DIGITS (unit)));
|
|
|
|
|
2010-10-20 00:41:19 +08:00
|
|
|
gsef->value_adjustment = gtk_adjustment_new (gsef->value,
|
|
|
|
gsef->min_value,
|
|
|
|
gsef->max_value,
|
|
|
|
1.0, 10.0, 0.0);
|
2018-11-10 19:36:04 +08:00
|
|
|
gsef->value_spinbutton = gimp_spin_button_new (gsef->value_adjustment,
|
|
|
|
1.0, digits);
|
2014-06-22 06:00:46 +08:00
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
TRUE);
|
2002-09-07 04:44:47 +08:00
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
gimp_size_entry_attach_eevl (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
gsef);
|
|
|
|
|
2002-09-07 04:44:47 +08:00
|
|
|
if (spinbutton_width > 0)
|
|
|
|
{
|
|
|
|
if (spinbutton_width < 17)
|
|
|
|
gtk_entry_set_width_chars (GTK_ENTRY (gsef->value_spinbutton),
|
|
|
|
spinbutton_width);
|
|
|
|
else
|
|
|
|
gtk_widget_set_size_request (gsef->value_spinbutton,
|
|
|
|
spinbutton_width, -1);
|
|
|
|
}
|
|
|
|
|
2018-05-03 02:23:05 +08:00
|
|
|
gtk_grid_attach (GTK_GRID (gse), gsef->value_spinbutton,
|
2018-05-25 10:08:59 +08:00
|
|
|
i+1, priv->show_refval+1, 1, 1);
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_connect (gsef->value_adjustment, "value-changed",
|
2001-07-31 19:33:13 +08:00
|
|
|
G_CALLBACK (gimp_size_entry_value_callback),
|
|
|
|
gsef);
|
1999-04-03 03:46:59 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
gtk_widget_show (gsef->value_spinbutton);
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2006-04-12 18:53:28 +08:00
|
|
|
{
|
2010-10-20 00:41:19 +08:00
|
|
|
gsef->refval_adjustment = gtk_adjustment_new (gsef->refval,
|
|
|
|
gsef->min_refval,
|
|
|
|
gsef->max_refval,
|
|
|
|
1.0, 10.0, 0.0);
|
2018-11-10 19:36:04 +08:00
|
|
|
gsef->refval_spinbutton = gimp_spin_button_new (gsef->refval_adjustment,
|
|
|
|
1.0,
|
|
|
|
gsef->refval_digits);
|
2014-06-22 06:00:46 +08:00
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (gsef->refval_spinbutton),
|
|
|
|
TRUE);
|
2005-04-17 23:28:28 +08:00
|
|
|
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_widget_set_size_request (gsef->refval_spinbutton,
|
|
|
|
spinbutton_width, -1);
|
2018-05-03 02:23:05 +08:00
|
|
|
gtk_grid_attach (GTK_GRID (gse), gsef->refval_spinbutton,
|
|
|
|
i + 1, 1, 1, 1);
|
2006-04-12 18:53:28 +08:00
|
|
|
g_signal_connect (gsef->refval_adjustment,
|
2005-05-27 21:05:26 +08:00
|
|
|
"value-changed",
|
2001-07-31 19:33:13 +08:00
|
|
|
G_CALLBACK (gimp_size_entry_refval_callback),
|
|
|
|
gsef);
|
1999-04-03 03:46:59 +08:00
|
|
|
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_widget_show (gsef->refval_spinbutton);
|
|
|
|
}
|
1998-12-05 11:38:13 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->menu_show_pixels && (unit == gimp_unit_pixel ()) &&
|
2018-05-25 10:08:59 +08:00
|
|
|
! priv->show_refval)
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
gsef->refval_digits);
|
1999-03-12 11:44:59 +08:00
|
|
|
}
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
store = gimp_unit_store_new (priv->number_of_fields);
|
|
|
|
gimp_unit_store_set_has_pixels (store, priv->menu_show_pixels);
|
|
|
|
gimp_unit_store_set_has_percent (store, priv->menu_show_percent);
|
2010-10-15 06:15:48 +08:00
|
|
|
|
2010-11-05 23:30:23 +08:00
|
|
|
if (unit_format)
|
|
|
|
{
|
|
|
|
gchar *short_format = g_strdup (unit_format);
|
|
|
|
gchar *p;
|
|
|
|
|
|
|
|
p = strstr (short_format, "%s");
|
|
|
|
if (p)
|
|
|
|
strcpy (p, "%a");
|
|
|
|
|
|
|
|
p = strstr (short_format, "%p");
|
|
|
|
if (p)
|
|
|
|
strcpy (p, "%a");
|
|
|
|
|
|
|
|
g_object_set (store,
|
|
|
|
"short-format", short_format,
|
|
|
|
"long-format", unit_format,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_free (short_format);
|
|
|
|
}
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->unit_combo = gimp_unit_combo_box_new_with_model (store);
|
2010-10-15 05:03:34 +08:00
|
|
|
g_object_unref (store);
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gimp_unit_combo_box_set_active (GIMP_UNIT_COMBO_BOX (priv->unit_combo), unit);
|
2010-10-15 05:03:34 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gtk_grid_attach (GTK_GRID (gse), priv->unit_combo,
|
|
|
|
i+2, priv->show_refval+1, 1, 1);
|
|
|
|
g_signal_connect (priv->unit_combo, "changed",
|
2001-07-31 19:33:13 +08:00
|
|
|
G_CALLBACK (gimp_size_entry_unit_callback),
|
|
|
|
gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
gtk_widget_show (priv->unit_combo);
|
2003-10-01 07:19:48 +08:00
|
|
|
|
1998-12-05 11:38:13 +08:00
|
|
|
return GTK_WIDGET (gse);
|
|
|
|
}
|
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_add_field:
|
2003-02-07 05:17:12 +08:00
|
|
|
* @gse: The sizeentry you want to add a field to.
|
|
|
|
* @value_spinbutton: The spinbutton to display the field's value.
|
2020-12-25 22:02:09 +08:00
|
|
|
* @refval_spinbutton: (nullable): The spinbutton to display the field's reference value.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* Adds an input field to the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The new input field will have the index 0. If you specified @show_refval
|
2003-02-07 05:17:12 +08:00
|
|
|
* as %TRUE in gimp_size_entry_new() you have to pass an additional
|
|
|
|
* #GtkSpinButton to hold the reference value. If @show_refval was %FALSE,
|
2000-02-08 04:35:13 +08:00
|
|
|
* @refval_spinbutton will be ignored.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-04-03 03:46:59 +08:00
|
|
|
void
|
2000-02-08 04:35:13 +08:00
|
|
|
gimp_size_entry_add_field (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
GtkSpinButton *value_spinbutton,
|
|
|
|
GtkSpinButton *refval_spinbutton)
|
1999-04-03 03:46:59 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
|
|
|
gint digits;
|
1999-04-03 03:46:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
|
|
|
g_return_if_fail (GTK_IS_SPIN_BUTTON (value_spinbutton));
|
2001-08-04 03:52:08 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
if (priv->show_refval)
|
1999-04-03 03:46:59 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_SPIN_BUTTON (refval_spinbutton));
|
|
|
|
}
|
|
|
|
|
2007-05-22 19:49:24 +08:00
|
|
|
gsef = g_slice_new0 (GimpSizeEntryField);
|
2001-08-04 03:52:08 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->fields = g_slist_prepend (priv->fields, gsef);
|
|
|
|
priv->number_of_fields++;
|
1999-04-03 03:46:59 +08:00
|
|
|
|
2002-05-28 00:56:28 +08:00
|
|
|
gsef->gse = gse;
|
|
|
|
gsef->resolution = 1.0; /* just to avoid division by zero */
|
|
|
|
gsef->lower = 0.0;
|
|
|
|
gsef->upper = 100.0;
|
|
|
|
gsef->value = 0;
|
|
|
|
gsef->min_value = 0;
|
|
|
|
gsef->max_value = SIZE_MAX_VALUE;
|
|
|
|
gsef->refval = 0;
|
|
|
|
gsef->min_refval = 0;
|
|
|
|
gsef->max_refval = SIZE_MAX_VALUE;
|
|
|
|
gsef->refval_digits =
|
2018-05-25 10:08:59 +08:00
|
|
|
(priv->update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE) ? 0 : 3;
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion = 0;
|
1999-04-03 03:46:59 +08:00
|
|
|
|
2010-10-20 00:37:00 +08:00
|
|
|
gsef->value_adjustment = gtk_spin_button_get_adjustment (value_spinbutton);
|
1999-04-03 03:46:59 +08:00
|
|
|
gsef->value_spinbutton = GTK_WIDGET (value_spinbutton);
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_connect (gsef->value_adjustment, "value-changed",
|
2001-07-31 19:33:13 +08:00
|
|
|
G_CALLBACK (gimp_size_entry_value_callback),
|
|
|
|
gsef);
|
1999-04-03 03:46:59 +08:00
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
gimp_size_entry_attach_eevl (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
gsef);
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
1999-04-03 03:46:59 +08:00
|
|
|
{
|
2010-10-20 00:37:00 +08:00
|
|
|
gsef->refval_adjustment = gtk_spin_button_get_adjustment (refval_spinbutton);
|
1999-04-03 03:46:59 +08:00
|
|
|
gsef->refval_spinbutton = GTK_WIDGET (refval_spinbutton);
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_connect (gsef->refval_adjustment, "value-changed",
|
2001-07-31 19:33:13 +08:00
|
|
|
G_CALLBACK (gimp_size_entry_refval_callback),
|
|
|
|
gsef);
|
1999-04-03 03:46:59 +08:00
|
|
|
}
|
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
digits = ((priv->unit == gimp_unit_pixel ()) ? gsef->refval_digits :
|
|
|
|
(priv->unit == gimp_unit_percent ()) ? 2 :
|
2018-05-25 10:08:59 +08:00
|
|
|
GIMP_SIZE_ENTRY_DIGITS (priv->unit));
|
2003-10-01 07:19:48 +08:00
|
|
|
|
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (value_spinbutton), digits);
|
1999-04-03 03:46:59 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->menu_show_pixels &&
|
|
|
|
!priv->show_refval &&
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
(priv->unit == gimp_unit_pixel ()))
|
2000-10-24 08:00:31 +08:00
|
|
|
{
|
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->refval_digits);
|
2000-10-24 08:00:31 +08:00
|
|
|
}
|
1999-04-03 03:46:59 +08:00
|
|
|
}
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryUpdatePolicy
|
|
|
|
gimp_size_entry_get_update_policy (GimpSizeEntry *gse)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), GIMP_SIZE_ENTRY_UPDATE_SIZE);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
return priv->update_policy;
|
2018-05-25 10:08:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gimp_size_entry_get_n_fields (GimpSizeEntry *gse)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), 0);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
return priv->number_of_fields;
|
2018-05-25 10:08:59 +08:00
|
|
|
}
|
|
|
|
|
2019-08-09 18:59:41 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_get_unit_combo:
|
|
|
|
* @gse: a #GimpSizeEntry.
|
|
|
|
*
|
GIR: Try to return more specific GtkWidget subclass
In GTK, a common scheme is to let a function creating a specific widget
to return a `GtkWidget *`, rather than the specific subtype, since you
often need to call API of GtkWidget, avoiding some useless casts.
For bindings however (and especially bindings to compiled languages),
this is a bit annoying, as you have to explicitly change the type of the
return value (downcast), which is not trivial (or at least desirable) in
each language.
Luckily, we can use `(type ...)` annotation for this use case, leaving
the C API unchanged, while improving the experience for bindings.
2020-12-25 22:05:16 +08:00
|
|
|
* Returns: (transfer none) (type GimpUnitComboBox): the size entry's #GimpUnitComboBox.
|
2019-08-09 18:59:41 +08:00
|
|
|
**/
|
2018-05-25 10:08:59 +08:00
|
|
|
GtkWidget *
|
|
|
|
gimp_size_entry_get_unit_combo (GimpSizeEntry *gse)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), NULL);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
return priv->unit_combo;
|
2018-05-25 10:08:59 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_attach_label:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to add a label to.
|
|
|
|
* @text: The text of the label.
|
|
|
|
* @row: The row where the label will be attached.
|
|
|
|
* @column: The column where the label will be attached.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @alignment: The horizontal alignment of the label.
|
|
|
|
*
|
2018-05-03 02:23:05 +08:00
|
|
|
* Attaches a #GtkLabel to the #GimpSizeEntry (which is a #GtkGrid).
|
2004-05-19 01:06:06 +08:00
|
|
|
*
|
2019-08-01 20:02:21 +08:00
|
|
|
* Returns: (transfer none): A pointer to the new #GtkLabel widget.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
2004-05-19 01:06:06 +08:00
|
|
|
GtkWidget *
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_attach_label (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
const gchar *text,
|
|
|
|
gint row,
|
|
|
|
gint column,
|
|
|
|
gfloat alignment)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2002-05-28 00:56:28 +08:00
|
|
|
GtkWidget *label;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2004-05-19 01:06:06 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), NULL);
|
|
|
|
g_return_val_if_fail (text != NULL, NULL);
|
1999-03-12 11:44:59 +08:00
|
|
|
|
2002-05-26 02:10:04 +08:00
|
|
|
label = gtk_label_new_with_mnemonic (text);
|
2002-05-28 00:56:28 +08:00
|
|
|
|
|
|
|
if (column == 0)
|
|
|
|
{
|
2009-10-18 00:49:12 +08:00
|
|
|
GList *children;
|
|
|
|
GList *list;
|
2002-05-28 00:56:28 +08:00
|
|
|
|
2009-10-18 00:49:12 +08:00
|
|
|
children = gtk_container_get_children (GTK_CONTAINER (gse));
|
|
|
|
|
|
|
|
for (list = children; list; list = g_list_next (list))
|
2002-05-28 00:56:28 +08:00
|
|
|
{
|
2009-10-18 00:49:12 +08:00
|
|
|
GtkWidget *child = list->data;
|
|
|
|
gint left_attach;
|
|
|
|
gint top_attach;
|
|
|
|
|
|
|
|
gtk_container_child_get (GTK_CONTAINER (gse), child,
|
|
|
|
"left-attach", &left_attach,
|
|
|
|
"top-attach", &top_attach,
|
|
|
|
NULL);
|
2002-05-28 00:56:28 +08:00
|
|
|
|
2009-10-18 00:49:12 +08:00
|
|
|
if (left_attach == 1 && top_attach == row)
|
2002-05-28 00:56:28 +08:00
|
|
|
{
|
2009-10-18 00:49:12 +08:00
|
|
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), child);
|
2002-05-28 00:56:28 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-10-18 00:49:12 +08:00
|
|
|
|
|
|
|
g_list_free (children);
|
2002-05-28 00:56:28 +08:00
|
|
|
}
|
2003-10-01 07:19:48 +08:00
|
|
|
|
2016-09-09 01:11:20 +08:00
|
|
|
gtk_label_set_xalign (GTK_LABEL (label), alignment);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-03 02:23:05 +08:00
|
|
|
gtk_grid_attach (GTK_GRID (gse), label, column, row, 1, 1);
|
1999-02-25 02:30:58 +08:00
|
|
|
gtk_widget_show (label);
|
2004-05-19 01:06:06 +08:00
|
|
|
|
|
|
|
return label;
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
1999-03-12 11:44:59 +08:00
|
|
|
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_resolution:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set a resolution for.
|
|
|
|
* @field: The index of the field you want to set the resolution for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @resolution: The new resolution (in dpi) for the chosen @field.
|
2003-02-07 05:17:12 +08:00
|
|
|
* @keep_size: %TRUE if the @field's size in pixels should stay the same.
|
|
|
|
* %FALSE if the @field's size in units should stay the same.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* Sets the resolution (in dpi) for field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The @resolution passed will be clamped to fit in
|
|
|
|
* [#GIMP_MIN_RESOLUTION..#GIMP_MAX_RESOLUTION].
|
|
|
|
*
|
|
|
|
* This function does nothing if the #GimpSizeEntryUpdatePolicy specified in
|
2001-08-04 03:52:08 +08:00
|
|
|
* gimp_size_entry_new() doesn't equal to #GIMP_SIZE_ENTRY_UPDATE_SIZE.
|
|
|
|
**/
|
1998-12-05 11:38:13 +08:00
|
|
|
void
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_set_resolution (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gdouble resolution,
|
|
|
|
gboolean keep_size)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
|
|
|
gfloat val;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
2000-02-08 04:35:13 +08:00
|
|
|
|
|
|
|
resolution = CLAMP (resolution, GIMP_MIN_RESOLUTION, GIMP_MAX_RESOLUTION);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField*) g_slist_nth_data (priv->fields, field);
|
1999-02-25 02:30:58 +08:00
|
|
|
gsef->resolution = resolution;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
val = gsef->value;
|
|
|
|
|
|
|
|
gsef->stop_recursion = 0;
|
|
|
|
gimp_size_entry_set_refval_boundaries (gse, field,
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->min_refval, gsef->max_refval);
|
1999-05-05 01:20:05 +08:00
|
|
|
|
|
|
|
if (! keep_size)
|
|
|
|
gimp_size_entry_set_value (gse, field, val);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_size:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set a size for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @field: The index of the field you want to set the size for.
|
|
|
|
* @lower: The reference value which will be treated as 0%.
|
|
|
|
* @upper: The reference value which will be treated as 100%.
|
|
|
|
*
|
|
|
|
* Sets the pixel values for field # @field of the #GimpSizeEntry
|
|
|
|
* which will be treated as 0% and 100%.
|
|
|
|
*
|
2003-02-07 05:17:12 +08:00
|
|
|
* These values will be used if you specified @menu_show_percent as %TRUE
|
2000-02-08 04:35:13 +08:00
|
|
|
* in gimp_size_entry_new() and the user has selected GIMP_UNIT_PERCENT in
|
2010-10-15 05:03:34 +08:00
|
|
|
* the #GimpSizeEntry's #GimpUnitComboBox.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* This function does nothing if the #GimpSizeEntryUpdatePolicy specified in
|
|
|
|
* gimp_size_entry_new() doesn't equal to GIMP_SIZE_ENTRY_UPDATE_SIZE.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-04-06 20:13:54 +08:00
|
|
|
void
|
|
|
|
gimp_size_entry_set_size (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gdouble lower,
|
|
|
|
gdouble upper)
|
1999-04-06 20:13:54 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-04-06 20:13:54 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
1999-05-02 22:24:54 +08:00
|
|
|
g_return_if_fail (lower <= upper);
|
1999-04-06 20:13:54 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField*) g_slist_nth_data (priv->fields, field);
|
1999-04-06 20:13:54 +08:00
|
|
|
gsef->lower = lower;
|
|
|
|
gsef->upper = upper;
|
|
|
|
|
|
|
|
gimp_size_entry_set_refval (gse, field, gsef->refval);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_value_boundaries:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set value boundaries for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @field: The index of the field you want to set value boundaries for.
|
|
|
|
* @lower: The new lower boundary of the value of the chosen @field.
|
|
|
|
* @upper: The new upper boundary of the value of the chosen @field.
|
|
|
|
*
|
|
|
|
* Limits the range of possible values which can be entered in field # @field
|
|
|
|
* of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The current value of the @field will be clamped to fit in the @field's
|
|
|
|
* new boundaries.
|
|
|
|
*
|
2006-12-28 19:30:24 +08:00
|
|
|
* NOTE: In most cases you won't be interested in this function because the
|
2000-02-08 04:35:13 +08:00
|
|
|
* #GimpSizeEntry's purpose is to shield the programmer from unit
|
|
|
|
* calculations. Use gimp_size_entry_set_refval_boundaries() instead.
|
2003-10-24 01:35:18 +08:00
|
|
|
* Whatever you do, don't mix these calls. A size entry should either
|
|
|
|
* be clamped by the value or the reference value.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-02-25 02:30:58 +08:00
|
|
|
void
|
2001-08-04 03:52:08 +08:00
|
|
|
gimp_size_entry_set_value_boundaries (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gdouble lower,
|
|
|
|
gdouble upper)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
1999-05-02 22:24:54 +08:00
|
|
|
g_return_if_fail (lower <= upper);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField*) g_slist_nth_data (priv->fields, field);
|
2003-10-24 01:35:18 +08:00
|
|
|
gsef->min_value = lower;
|
|
|
|
gsef->max_value = upper;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2010-10-20 00:37:00 +08:00
|
|
|
g_object_freeze_notify (G_OBJECT (gsef->value_adjustment));
|
|
|
|
|
|
|
|
gtk_adjustment_set_lower (gsef->value_adjustment, gsef->min_value);
|
|
|
|
gtk_adjustment_set_upper (gsef->value_adjustment, gsef->max_value);
|
1999-04-03 03:46:59 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
if (gsef->stop_recursion) /* this is a hack (but useful ;-) */
|
2010-10-20 00:37:00 +08:00
|
|
|
{
|
|
|
|
g_object_thaw_notify (G_OBJECT (gsef->value_adjustment));
|
|
|
|
return;
|
|
|
|
}
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion++;
|
2018-05-25 10:08:59 +08:00
|
|
|
switch (priv->update_policy)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_NONE:
|
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_pixel ())
|
|
|
|
gimp_size_entry_set_refval_boundaries (gse, field,
|
|
|
|
gsef->min_value,
|
|
|
|
gsef->max_value);
|
|
|
|
else if (priv->unit == gimp_unit_percent ())
|
|
|
|
gimp_size_entry_set_refval_boundaries (gse, field,
|
|
|
|
gsef->lower +
|
|
|
|
(gsef->upper - gsef->lower) *
|
|
|
|
gsef->min_value / 100,
|
|
|
|
gsef->lower +
|
|
|
|
(gsef->upper - gsef->lower) *
|
|
|
|
gsef->max_value / 100);
|
|
|
|
else
|
|
|
|
gimp_size_entry_set_refval_boundaries (gse, field,
|
|
|
|
gsef->min_value *
|
|
|
|
gsef->resolution /
|
|
|
|
gimp_unit_get_factor (priv->unit),
|
|
|
|
gsef->max_value *
|
|
|
|
gsef->resolution /
|
|
|
|
gimp_unit_get_factor (priv->unit));
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
|
|
|
|
gimp_size_entry_set_refval_boundaries (gse, field,
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->min_value *
|
2018-05-25 10:08:59 +08:00
|
|
|
gimp_unit_get_factor (priv->unit),
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->max_value *
|
2018-05-25 10:08:59 +08:00
|
|
|
gimp_unit_get_factor (priv->unit));
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion--;
|
|
|
|
|
|
|
|
gimp_size_entry_set_value (gse, field, gsef->value);
|
2010-10-20 00:37:00 +08:00
|
|
|
|
|
|
|
g_object_thaw_notify (G_OBJECT (gsef->value_adjustment));
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
2010-07-06 01:04:15 +08:00
|
|
|
* gimp_size_entry_get_value:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to know a value of.
|
2003-10-15 19:57:36 +08:00
|
|
|
* @field: The index of the field you want to know the value of.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* Returns the value of field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The @value returned is a distance or resolution
|
|
|
|
* in the #GimpUnit the user has selected in the #GimpSizeEntry's
|
2010-10-15 05:03:34 +08:00
|
|
|
* #GimpUnitComboBox.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* NOTE: In most cases you won't be interested in this value because the
|
|
|
|
* #GimpSizeEntry's purpose is to shield the programmer from unit
|
|
|
|
* calculations. Use gimp_size_entry_get_refval() instead.
|
|
|
|
*
|
|
|
|
* Returns: The value of the chosen @field.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_get_value (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), 0);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail ((field >= 0) && (field < priv->number_of_fields), 0);
|
|
|
|
|
|
|
|
gsef = (GimpSizeEntryField *) g_slist_nth_data (priv->fields, field);
|
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
return gsef->value;
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
static void
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_value (GimpSizeEntryField *gsef,
|
2006-04-12 18:53:28 +08:00
|
|
|
gdouble value)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv = gimp_size_entry_get_instance_private (gsef->gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
if (gsef->stop_recursion > 1)
|
1999-02-25 02:30:58 +08:00
|
|
|
return;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
gsef->value = value;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
switch (priv->update_policy)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_pixel ())
|
|
|
|
gsef->refval = value;
|
|
|
|
else if (priv->unit == gimp_unit_percent ())
|
|
|
|
gsef->refval = CLAMP (gsef->lower + (gsef->upper - gsef->lower) * value / 100,
|
|
|
|
gsef->min_refval, gsef->max_refval);
|
|
|
|
else
|
|
|
|
gsef->refval = CLAMP (value * gsef->resolution /
|
|
|
|
gimp_unit_get_factor (priv->unit),
|
|
|
|
gsef->min_refval, gsef->max_refval);
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->refval_adjustment, gsef->refval);
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->refval =
|
2018-05-25 10:08:59 +08:00
|
|
|
CLAMP (value * gimp_unit_get_factor (priv->unit),
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->min_refval, gsef->max_refval);
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->refval_adjustment, gsef->refval);
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-01 07:19:48 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2003-10-31 04:58:37 +08:00
|
|
|
|
|
|
|
g_signal_emit (gsef->gse, gimp_size_entry_signals[VALUE_CHANGED], 0);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
2010-07-06 01:04:15 +08:00
|
|
|
* gimp_size_entry_set_value:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set a value for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @field: The index of the field you want to set a value for.
|
|
|
|
* @value: The new value for @field.
|
|
|
|
*
|
|
|
|
* Sets the value for field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The @value passed is treated to be a distance or resolution
|
|
|
|
* in the #GimpUnit the user has selected in the #GimpSizeEntry's
|
2010-10-15 05:03:34 +08:00
|
|
|
* #GimpUnitComboBox.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
|
|
|
* NOTE: In most cases you won't be interested in this value because the
|
|
|
|
* #GimpSizeEntry's purpose is to shield the programmer from unit
|
|
|
|
* calculations. Use gimp_size_entry_set_refval() instead.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1998-12-05 11:38:13 +08:00
|
|
|
void
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_set_value (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gdouble value)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
|
|
|
|
|
|
|
gsef = (GimpSizeEntryField *) g_slist_nth_data (priv->fields, field);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
value = CLAMP (value, gsef->min_value, gsef->max_value);
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->value_adjustment, value);
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_value (gsef, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2018-06-25 00:15:16 +08:00
|
|
|
gimp_size_entry_value_callback (GtkAdjustment *adjustment,
|
|
|
|
gpointer data)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble new_value;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2001-08-04 03:52:08 +08:00
|
|
|
gsef = (GimpSizeEntryField *) data;
|
1999-03-13 04:00:48 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
new_value = gtk_adjustment_get_value (adjustment);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
|
|
|
if (gsef->value != new_value)
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_update_value (gsef, new_value);
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_refval_boundaries:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set the reference value boundaries for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @field: The index of the field you want to set the reference value
|
|
|
|
* boundaries for.
|
|
|
|
* @lower: The new lower boundary of the reference value of the chosen @field.
|
|
|
|
* @upper: The new upper boundary of the reference value of the chosen @field.
|
|
|
|
*
|
|
|
|
* Limits the range of possible reference values which can be entered in
|
|
|
|
* field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The current reference value of the @field will be clamped to fit in the
|
|
|
|
* @field's new boundaries.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-02-25 02:30:58 +08:00
|
|
|
void
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_set_refval_boundaries (GimpSizeEntry *gse,
|
|
|
|
gint field,
|
|
|
|
gdouble lower,
|
|
|
|
gdouble upper)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
1999-05-02 22:24:54 +08:00
|
|
|
g_return_if_fail (lower <= upper);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField *) g_slist_nth_data (priv->fields, field);
|
1999-02-25 02:30:58 +08:00
|
|
|
gsef->min_refval = lower;
|
|
|
|
gsef->max_refval = upper;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2010-10-20 00:37:00 +08:00
|
|
|
g_object_freeze_notify (G_OBJECT (gsef->refval_adjustment));
|
|
|
|
|
|
|
|
gtk_adjustment_set_lower (gsef->refval_adjustment, gsef->min_refval);
|
|
|
|
gtk_adjustment_set_upper (gsef->refval_adjustment, gsef->max_refval);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
1999-02-22 05:45:50 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
if (gsef->stop_recursion) /* this is a hack (but useful ;-) */
|
2010-10-20 00:37:00 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2010-10-20 00:37:00 +08:00
|
|
|
g_object_thaw_notify (G_OBJECT (gsef->refval_adjustment));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
1998-12-05 11:38:13 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion++;
|
2018-05-25 10:08:59 +08:00
|
|
|
switch (priv->update_policy)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_pixel ())
|
|
|
|
gimp_size_entry_set_value_boundaries (gse, field,
|
|
|
|
gsef->min_refval,
|
|
|
|
gsef->max_refval);
|
|
|
|
else if (priv->unit == gimp_unit_percent ())
|
|
|
|
gimp_size_entry_set_value_boundaries (gse, field,
|
|
|
|
100 * (gsef->min_refval -
|
|
|
|
gsef->lower) /
|
|
|
|
(gsef->upper - gsef->lower),
|
|
|
|
100 * (gsef->max_refval -
|
|
|
|
gsef->lower) /
|
|
|
|
(gsef->upper - gsef->lower));
|
|
|
|
else
|
|
|
|
gimp_size_entry_set_value_boundaries (gse, field,
|
|
|
|
gsef->min_refval *
|
|
|
|
gimp_unit_get_factor (priv->unit) /
|
|
|
|
gsef->resolution,
|
|
|
|
gsef->max_refval *
|
|
|
|
gimp_unit_get_factor (priv->unit) /
|
|
|
|
gsef->resolution);
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
|
|
|
|
gimp_size_entry_set_value_boundaries (gse, field,
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->min_refval /
|
2018-05-25 10:08:59 +08:00
|
|
|
gimp_unit_get_factor (priv->unit),
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->max_refval /
|
2018-05-25 10:08:59 +08:00
|
|
|
gimp_unit_get_factor (priv->unit));
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion--;
|
|
|
|
|
|
|
|
gimp_size_entry_set_refval (gse, field, gsef->refval);
|
2010-10-20 00:37:00 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2010-10-20 00:37:00 +08:00
|
|
|
g_object_thaw_notify (G_OBJECT (gsef->refval_adjustment));
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_refval_digits:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set the reference value digits for.
|
|
|
|
* @field: The index of the field you want to set the reference value for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @digits: The new number of decimal digits for the #GtkSpinButton which
|
|
|
|
* displays @field's reference value.
|
|
|
|
*
|
|
|
|
* Sets the decimal digits of field # @field of the #GimpSizeEntry to
|
|
|
|
* @digits.
|
|
|
|
*
|
|
|
|
* If you don't specify this value explicitly, the reference value's number
|
2001-08-04 03:52:08 +08:00
|
|
|
* of digits will equal to 0 for #GIMP_SIZE_ENTRY_UPDATE_SIZE and to 2 for
|
|
|
|
* #GIMP_SIZE_ENTRY_UPDATE_RESOLUTION.
|
|
|
|
**/
|
1999-03-12 11:44:59 +08:00
|
|
|
void
|
|
|
|
gimp_size_entry_set_refval_digits (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gint digits)
|
1999-03-12 11:44:59 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-03-12 11:44:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail ((digits >= 0) && (digits <= 6));
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField*) g_slist_nth_data (priv->fields, field);
|
1999-03-12 11:44:59 +08:00
|
|
|
gsef->refval_digits = digits;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE)
|
1999-03-12 11:44:59 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->refval_spinbutton),
|
|
|
|
gsef->refval_digits);
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
else if (priv->unit == gimp_unit_pixel ())
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
gsef->refval_digits);
|
1999-03-12 11:44:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
2010-07-06 01:04:15 +08:00
|
|
|
* gimp_size_entry_get_refval:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to know a reference value of.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @field: The index of the field you want to know the reference value of.
|
|
|
|
*
|
|
|
|
* Returns the reference value for field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The reference value is either a distance in pixels or a resolution
|
|
|
|
* in dpi, depending on which #GimpSizeEntryUpdatePolicy you chose in
|
|
|
|
* gimp_size_entry_new().
|
|
|
|
*
|
|
|
|
* Returns: The reference value of the chosen @field.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_get_refval (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
/* return 1.0 to avoid division by zero */
|
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), 1.0);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail ((field >= 0) && (field < priv->number_of_fields), 1.0);
|
|
|
|
|
|
|
|
gsef = (GimpSizeEntryField*) g_slist_nth_data (priv->fields, field);
|
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
return gsef->refval;
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
static void
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_refval (GimpSizeEntryField *gsef,
|
2006-04-12 18:53:28 +08:00
|
|
|
gdouble refval)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv = gimp_size_entry_get_instance_private (gsef->gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
if (gsef->stop_recursion > 1)
|
1998-12-05 11:38:13 +08:00
|
|
|
return;
|
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
gsef->refval = refval;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
switch (priv->update_policy)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_pixel ())
|
|
|
|
gsef->value = refval;
|
|
|
|
else if (priv->unit == gimp_unit_percent ())
|
|
|
|
gsef->value = CLAMP (100 * (refval - gsef->lower) / (gsef->upper - gsef->lower),
|
|
|
|
gsef->min_value, gsef->max_value);
|
|
|
|
else
|
|
|
|
gsef->value = CLAMP (refval * gimp_unit_get_factor (priv->unit) /
|
|
|
|
gsef->resolution,
|
|
|
|
gsef->min_value, gsef->max_value);
|
|
|
|
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->value_adjustment, gsef->value);
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->value =
|
2018-05-25 10:08:59 +08:00
|
|
|
CLAMP (refval / gimp_unit_get_factor (priv->unit),
|
2006-04-12 18:53:28 +08:00
|
|
|
gsef->min_value, gsef->max_value);
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->value_adjustment, gsef->value);
|
1999-02-25 02:30:58 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2003-10-31 04:58:37 +08:00
|
|
|
|
|
|
|
g_signal_emit (gsef->gse, gimp_size_entry_signals[REFVAL_CHANGED], 0);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
2010-07-06 01:04:15 +08:00
|
|
|
* gimp_size_entry_set_refval:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to set a reference value for.
|
|
|
|
* @field: The index of the field you want to set the reference value for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @refval: The new reference value for @field.
|
|
|
|
*
|
|
|
|
* Sets the reference value for field # @field of the #GimpSizeEntry.
|
|
|
|
*
|
|
|
|
* The @refval passed is either a distance in pixels or a resolution in dpi,
|
|
|
|
* depending on which #GimpSizeEntryUpdatePolicy you chose in
|
|
|
|
* gimp_size_entry_new().
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-02-25 02:30:58 +08:00
|
|
|
void
|
|
|
|
gimp_size_entry_set_refval (GimpSizeEntry *gse,
|
2006-04-12 18:53:28 +08:00
|
|
|
gint field,
|
|
|
|
gdouble refval)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_if_fail ((field >= 0) && (field < priv->number_of_fields));
|
|
|
|
|
|
|
|
gsef = (GimpSizeEntryField *) g_slist_nth_data (priv->fields, field);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
refval = CLAMP (refval, gsef->min_refval, gsef->max_refval);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->show_refval)
|
2010-10-20 00:37:00 +08:00
|
|
|
gtk_adjustment_set_value (gsef->refval_adjustment, refval);
|
1999-05-05 01:20:05 +08:00
|
|
|
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_refval (gsef, refval);
|
|
|
|
}
|
1998-12-05 11:38:13 +08:00
|
|
|
|
|
|
|
static void
|
2018-06-25 00:15:16 +08:00
|
|
|
gimp_size_entry_refval_callback (GtkAdjustment *adjustment,
|
|
|
|
gpointer data)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
1999-02-25 02:30:58 +08:00
|
|
|
GimpSizeEntryField *gsef;
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble new_refval;
|
1998-12-05 11:38:13 +08:00
|
|
|
|
2001-08-04 03:52:08 +08:00
|
|
|
gsef = (GimpSizeEntryField *) data;
|
1999-03-13 04:00:48 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
new_refval = gtk_adjustment_get_value (adjustment);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
|
|
|
if (gsef->refval != new_refval)
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_update_refval (gsef, new_refval);
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_get_unit:
|
|
|
|
* @gse: The sizeentry you want to know the unit of.
|
|
|
|
*
|
|
|
|
* Returns the #GimpUnit the user has selected in the #GimpSizeEntry's
|
2010-10-15 05:03:34 +08:00
|
|
|
* #GimpUnitComboBox.
|
2000-02-08 04:35:13 +08:00
|
|
|
*
|
2019-08-01 05:48:32 +08:00
|
|
|
* Returns: (transfer none): The sizeentry's unit.
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_get_unit (GimpSizeEntry *gse)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), gimp_unit_inch ());
|
1999-03-12 11:44:59 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
return priv->unit;
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
|
|
|
|
2000-01-26 08:39:40 +08:00
|
|
|
static void
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_unit (GimpSizeEntry *gse,
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryField *gsef;
|
|
|
|
gint i;
|
|
|
|
gint digits;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
priv->unit = unit;
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2010-10-15 05:03:34 +08:00
|
|
|
digits = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (gse),
|
|
|
|
"gimp-pixel-digits"));
|
2003-10-01 07:19:48 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
for (i = 0; i < priv->number_of_fields; i++)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
gsef = (GimpSizeEntryField *) g_slist_nth_data (priv->fields, i);
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE)
|
2006-04-12 18:53:28 +08:00
|
|
|
{
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (unit == gimp_unit_pixel ())
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
gsef->refval_digits + digits);
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
else if (unit == gimp_unit_percent ())
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
2 + digits);
|
|
|
|
else
|
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
GIMP_SIZE_ENTRY_DIGITS (unit) + digits);
|
|
|
|
}
|
2018-05-25 10:08:59 +08:00
|
|
|
else if (priv->update_policy == GIMP_SIZE_ENTRY_UPDATE_RESOLUTION)
|
2006-04-12 18:53:28 +08:00
|
|
|
{
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
digits = (gimp_unit_get_digits (gimp_unit_inch ()) - gimp_unit_get_digits (unit));
|
2006-04-12 18:53:28 +08:00
|
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gsef->value_spinbutton),
|
|
|
|
MAX (3 + digits, 3));
|
|
|
|
}
|
1999-02-25 02:30:58 +08:00
|
|
|
|
1999-05-05 01:20:05 +08:00
|
|
|
gsef->stop_recursion = 0; /* hack !!! */
|
2000-01-26 08:39:40 +08:00
|
|
|
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_set_refval_boundaries (gse, i,
|
|
|
|
gsef->min_refval,
|
|
|
|
gsef->max_refval);
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
2000-01-26 08:39:40 +08:00
|
|
|
|
2003-10-01 07:19:48 +08:00
|
|
|
g_signal_emit (gse, gimp_size_entry_signals[UNIT_CHANGED], 0);
|
1999-02-25 02:30:58 +08:00
|
|
|
}
|
|
|
|
|
2003-10-01 07:19:48 +08:00
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_unit:
|
2001-08-04 03:52:08 +08:00
|
|
|
* @gse: The sizeentry you want to change the unit for.
|
2000-02-08 04:35:13 +08:00
|
|
|
* @unit: The new unit.
|
|
|
|
*
|
|
|
|
* Sets the #GimpSizeEntry's unit. The reference value for all fields will
|
|
|
|
* stay the same but the value in units or pixels per unit will change
|
|
|
|
* according to which #GimpSizeEntryUpdatePolicy you chose in
|
|
|
|
* gimp_size_entry_new().
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-02-25 02:30:58 +08:00
|
|
|
void
|
2003-10-01 07:19:48 +08:00
|
|
|
gimp_size_entry_set_unit (GimpSizeEntry *gse,
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit)
|
1999-02-25 02:30:58 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
1999-03-12 11:44:59 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
1999-02-25 02:30:58 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
g_return_if_fail (priv->menu_show_pixels || (unit != gimp_unit_pixel ()));
|
|
|
|
g_return_if_fail (priv->menu_show_percent || (unit != gimp_unit_percent ()));
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
gimp_unit_combo_box_set_active (GIMP_UNIT_COMBO_BOX (priv->unit_combo), unit);
|
1999-02-25 02:30:58 +08:00
|
|
|
gimp_size_entry_update_unit (gse, unit);
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_unit_callback (GtkWidget *widget,
|
2006-04-12 18:53:28 +08:00
|
|
|
GimpSizeEntry *gse)
|
1998-12-05 11:38:13 +08:00
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *new_unit;
|
2003-10-31 04:58:37 +08:00
|
|
|
|
2010-10-15 05:03:34 +08:00
|
|
|
new_unit = gimp_unit_combo_box_get_active (GIMP_UNIT_COMBO_BOX (widget));
|
2003-10-31 04:58:37 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
if (priv->unit != new_unit)
|
2003-10-31 04:58:37 +08:00
|
|
|
gimp_size_entry_update_unit (gse, new_unit);
|
2003-10-01 07:19:48 +08:00
|
|
|
}
|
2000-10-24 08:00:31 +08:00
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_attach_eevl:
|
2010-07-06 01:04:15 +08:00
|
|
|
* @spin_button: one of the size_entry's spinbuttons.
|
|
|
|
* @gsef: a size entry field.
|
2009-05-17 17:33:35 +08:00
|
|
|
*
|
|
|
|
* Hooks in the GimpEevl unit expression parser into the
|
|
|
|
* #GtkSpinButton of the #GimpSizeEntryField.
|
|
|
|
**/
|
|
|
|
static void
|
|
|
|
gimp_size_entry_attach_eevl (GtkSpinButton *spin_button,
|
|
|
|
GimpSizeEntryField *gsef)
|
|
|
|
{
|
2010-07-06 01:04:15 +08:00
|
|
|
gtk_spin_button_set_numeric (spin_button, FALSE);
|
|
|
|
gtk_spin_button_set_update_policy (spin_button, GTK_UPDATE_IF_VALID);
|
|
|
|
|
2019-03-12 00:35:00 +08:00
|
|
|
g_signal_connect_after (spin_button, "input",
|
|
|
|
G_CALLBACK (gimp_size_entry_eevl_input_callback),
|
|
|
|
gsef);
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gimp_size_entry_eevl_input_callback (GtkSpinButton *spinner,
|
|
|
|
gdouble *return_val,
|
|
|
|
gpointer *data)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryField *gsef = (GimpSizeEntryField *) data;
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpEevlOptions options = GIMP_EEVL_OPTIONS_INIT;
|
|
|
|
gboolean success = FALSE;
|
2021-08-22 18:22:50 +08:00
|
|
|
const gchar *error_pos = NULL;
|
2018-05-25 10:08:59 +08:00
|
|
|
GError *error = NULL;
|
|
|
|
GimpEevlQuantity result;
|
2009-05-17 17:33:35 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (GTK_IS_SPIN_BUTTON (spinner), FALSE);
|
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gsef->gse), FALSE);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gsef->gse);
|
|
|
|
|
2017-10-04 20:41:16 +08:00
|
|
|
options.unit_resolver_proc = gimp_size_entry_eevl_unit_resolver;
|
|
|
|
options.data = data;
|
|
|
|
|
2017-10-05 00:37:45 +08:00
|
|
|
/* enable ratio expressions when there are two fields */
|
2018-05-25 10:08:59 +08:00
|
|
|
if (priv->number_of_fields == 2)
|
2017-10-05 00:37:45 +08:00
|
|
|
{
|
|
|
|
GimpSizeEntryField *other_gsef;
|
2017-10-05 20:50:34 +08:00
|
|
|
GimpEevlQuantity default_unit_factor;
|
2020-01-06 17:41:25 +08:00
|
|
|
gdouble default_unit_offset;
|
2017-10-05 00:37:45 +08:00
|
|
|
|
|
|
|
options.ratio_expressions = TRUE;
|
|
|
|
|
2018-05-25 10:08:59 +08:00
|
|
|
if (gsef == priv->fields->data)
|
2017-10-05 00:37:45 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
other_gsef = priv->fields->next->data;
|
2017-10-05 00:37:45 +08:00
|
|
|
|
|
|
|
options.ratio_invert = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
other_gsef = priv->fields->data;
|
2017-10-05 00:37:45 +08:00
|
|
|
|
|
|
|
options.ratio_invert = TRUE;
|
|
|
|
}
|
|
|
|
|
2020-01-06 17:41:25 +08:00
|
|
|
options.unit_resolver_proc (NULL,
|
|
|
|
&default_unit_factor, &default_unit_offset,
|
|
|
|
options.data);
|
2017-10-05 20:50:34 +08:00
|
|
|
|
|
|
|
options.ratio_quantity.value = other_gsef->value /
|
|
|
|
default_unit_factor.value;
|
|
|
|
options.ratio_quantity.dimension = default_unit_factor.dimension;
|
2017-10-05 00:37:45 +08:00
|
|
|
}
|
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
success = gimp_eevl_evaluate (gtk_entry_get_text (GTK_ENTRY (spinner)),
|
2017-10-04 20:41:16 +08:00
|
|
|
&options,
|
2009-05-17 17:33:35 +08:00
|
|
|
&result,
|
|
|
|
&error_pos,
|
|
|
|
&error);
|
|
|
|
if (! success)
|
|
|
|
{
|
|
|
|
if (error && error_pos)
|
|
|
|
{
|
|
|
|
g_printerr ("ERROR: %s at '%s'\n",
|
|
|
|
error->message,
|
|
|
|
*error_pos ? error_pos : "<End of input>");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_printerr ("ERROR: Expression evaluation failed without error.\n");
|
|
|
|
}
|
2021-08-22 18:22:50 +08:00
|
|
|
g_clear_error (&error);
|
2009-05-17 17:33:35 +08:00
|
|
|
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (spinner));
|
|
|
|
return GTK_INPUT_ERROR;
|
|
|
|
}
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
else if (result.dimension != 1 && priv->unit != gimp_unit_percent ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
|
|
|
g_printerr ("ERROR: result has wrong dimension (expected 1, got %d)\n", result.dimension);
|
|
|
|
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (spinner));
|
|
|
|
return GTK_INPUT_ERROR;
|
|
|
|
}
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
else if (result.dimension != 0 && priv->unit == gimp_unit_percent ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
|
|
|
g_printerr ("ERROR: result has wrong dimension (expected 0, got %d)\n", result.dimension);
|
|
|
|
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (spinner));
|
|
|
|
return GTK_INPUT_ERROR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* transform back to UI-unit */
|
2013-02-23 04:19:59 +08:00
|
|
|
GimpEevlQuantity ui_unit;
|
|
|
|
GtkAdjustment *adj;
|
|
|
|
gdouble val;
|
2009-05-17 17:33:35 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_pixel ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
|
|
|
ui_unit.value = gsef->resolution;
|
|
|
|
ui_unit.dimension = 1;
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
}
|
|
|
|
else if (priv->unit == gimp_unit_percent ())
|
|
|
|
{
|
2009-05-17 17:33:35 +08:00
|
|
|
ui_unit.value = 1.0;
|
|
|
|
ui_unit.dimension = 0;
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
ui_unit.value = gimp_unit_get_factor(priv->unit);
|
2009-05-17 17:33:35 +08:00
|
|
|
ui_unit.dimension = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*return_val = result.value * ui_unit.value;
|
|
|
|
|
2013-02-23 04:19:59 +08:00
|
|
|
/* CLAMP() to adjustment bounds, or too large/small values
|
|
|
|
* will make the validation machinery revert to the old value.
|
|
|
|
* See bug #694477.
|
|
|
|
*/
|
|
|
|
adj = gtk_spin_button_get_adjustment (spinner);
|
|
|
|
|
|
|
|
val = CLAMP (*return_val,
|
|
|
|
gtk_adjustment_get_lower (adj),
|
|
|
|
gtk_adjustment_get_upper (adj));
|
|
|
|
|
|
|
|
if (val != *return_val)
|
|
|
|
{
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (spinner));
|
|
|
|
*return_val = val;
|
|
|
|
}
|
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_size_entry_eevl_unit_resolver (const gchar *identifier,
|
2020-01-06 17:41:25 +08:00
|
|
|
GimpEevlQuantity *factor,
|
|
|
|
gdouble *offset,
|
2009-05-17 17:33:35 +08:00
|
|
|
gpointer data)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryField *gsef = (GimpSizeEntryField *) data;
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
2018-05-25 10:08:59 +08:00
|
|
|
gboolean resolve_default_unit = (identifier == NULL);
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
GimpUnit *unit = gimp_unit_pixel ();
|
|
|
|
gint i = 1;
|
2016-06-02 07:50:16 +08:00
|
|
|
|
2009-05-17 17:33:35 +08:00
|
|
|
g_return_val_if_fail (gsef, FALSE);
|
2020-01-06 17:41:25 +08:00
|
|
|
g_return_val_if_fail (factor != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (offset != NULL, FALSE);
|
2009-05-17 17:33:35 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gsef->gse), FALSE);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gsef->gse);
|
|
|
|
|
2020-01-06 17:41:25 +08:00
|
|
|
*offset = 0.0;
|
2009-05-17 17:33:35 +08:00
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
while (unit != NULL)
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
if ((resolve_default_unit && unit == priv->unit) ||
|
2009-05-17 17:33:35 +08:00
|
|
|
(identifier &&
|
|
|
|
(strcmp (gimp_unit_get_symbol (unit), identifier) == 0 ||
|
|
|
|
strcmp (gimp_unit_get_abbreviation (unit), identifier) == 0)))
|
|
|
|
{
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (unit == gimp_unit_percent ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_percent ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
2020-01-06 17:41:25 +08:00
|
|
|
factor->value = 1;
|
|
|
|
factor->dimension = 0;
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* gsef->upper contains the '100%'-value */
|
2020-01-06 17:41:25 +08:00
|
|
|
factor->value = 100*gsef->resolution/(gsef->upper - gsef->lower);
|
|
|
|
/* gsef->lower contains the '0%'-value */
|
|
|
|
*offset = gsef->lower/gsef->resolution;
|
|
|
|
factor->dimension = 1;
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
/* return here, don't perform percentage conversion */
|
|
|
|
return TRUE;
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
}
|
|
|
|
else if (unit == gimp_unit_pixel ())
|
|
|
|
{
|
|
|
|
factor->value = gsef->resolution;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
factor->value = gimp_unit_get_factor (unit);
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
if (priv->unit == gimp_unit_percent ())
|
2009-05-17 17:33:35 +08:00
|
|
|
{
|
|
|
|
/* map non-percentages onto percent */
|
2020-01-06 17:41:25 +08:00
|
|
|
factor->value = gsef->upper/(100*gsef->resolution);
|
|
|
|
factor->dimension = 0;
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-01-06 17:41:25 +08:00
|
|
|
factor->dimension = 1;
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We are done */
|
|
|
|
return TRUE;
|
|
|
|
}
|
Issue #8900 and #9923: reimplementing GimpUnit as a proper class.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes #10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
2024-07-26 02:55:21 +08:00
|
|
|
|
|
|
|
unit = gimp_unit_get_by_id (i++);
|
|
|
|
|
|
|
|
/* Hack to handle percent within the loop */
|
|
|
|
if (unit == NULL && unit != gimp_unit_percent ())
|
|
|
|
unit = gimp_unit_percent ();
|
2009-05-17 17:33:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-03-10 06:22:38 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_show_unit_menu:
|
|
|
|
* @gse: a #GimpSizeEntry
|
|
|
|
* @show: Boolean
|
|
|
|
*
|
|
|
|
* Controls whether a unit menu is shown in the size entry. If
|
2019-08-03 06:04:28 +08:00
|
|
|
* @show is %TRUE, the menu is shown; otherwise it is hidden.
|
2005-03-10 07:47:39 +08:00
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.4
|
2005-03-10 06:22:38 +08:00
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_size_entry_show_unit_menu (GimpSizeEntry *gse,
|
|
|
|
gboolean show)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
|
2005-03-10 06:22:38 +08:00
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
|
|
|
|
gtk_widget_set_visible (priv->unit_combo, show);
|
2005-03-10 06:22:38 +08:00
|
|
|
}
|
|
|
|
|
2003-10-01 07:19:48 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_pixel_digits:
|
|
|
|
* @gse: a #GimpSizeEntry
|
|
|
|
* @digits: the number of digits to display for a pixel size
|
|
|
|
*
|
2010-10-15 05:03:34 +08:00
|
|
|
* This function allows you set up a #GimpSizeEntry so that sub-pixel
|
|
|
|
* sizes can be entered.
|
2003-10-01 07:19:48 +08:00
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_size_entry_set_pixel_digits (GimpSizeEntry *gse,
|
|
|
|
gint digits)
|
|
|
|
{
|
2024-08-01 11:55:31 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpUnitComboBox *combo;
|
2003-10-01 07:19:48 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
|
|
|
combo = GIMP_UNIT_COMBO_BOX (priv->unit_combo);
|
2003-10-01 07:19:48 +08:00
|
|
|
|
2010-10-15 05:03:34 +08:00
|
|
|
g_object_set_data (G_OBJECT (gse), "gimp-pixel-digits",
|
|
|
|
GINT_TO_POINTER (digits));
|
|
|
|
gimp_size_entry_update_unit (gse, gimp_unit_combo_box_get_active (combo));
|
1998-12-05 11:38:13 +08:00
|
|
|
}
|
1999-03-15 02:03:58 +08:00
|
|
|
|
2003-10-01 07:19:48 +08:00
|
|
|
|
2000-02-08 04:35:13 +08:00
|
|
|
/**
|
|
|
|
* gimp_size_entry_grab_focus:
|
|
|
|
* @gse: The sizeentry you want to grab the keyboard focus.
|
|
|
|
*
|
|
|
|
* This function is rather ugly and just a workaround for the fact that
|
2018-05-03 02:23:05 +08:00
|
|
|
* it's impossible to implement gtk_widget_grab_focus() for a #GtkGrid (is this actually true after the Table->Grid conversion?).
|
2001-08-04 03:52:08 +08:00
|
|
|
**/
|
1999-03-15 02:03:58 +08:00
|
|
|
void
|
|
|
|
gimp_size_entry_grab_focus (GimpSizeEntry *gse)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
1999-03-15 02:03:58 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
gsef = priv->fields->data;
|
2005-02-10 00:57:18 +08:00
|
|
|
if (gsef)
|
2018-05-25 10:08:59 +08:00
|
|
|
gtk_widget_grab_focus (priv->show_refval ?
|
2005-02-10 00:57:18 +08:00
|
|
|
gsef->refval_spinbutton : gsef->value_spinbutton);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_size_entry_set_activates_default:
|
2010-07-06 01:04:15 +08:00
|
|
|
* @gse: A #GimpSizeEntry
|
2005-02-10 00:57:18 +08:00
|
|
|
* @setting: %TRUE to activate window's default widget on Enter keypress
|
|
|
|
*
|
|
|
|
* Iterates over all entries in the #GimpSizeEntry and calls
|
|
|
|
* gtk_entry_set_activates_default() on them.
|
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.4
|
2005-02-10 00:57:18 +08:00
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_size_entry_set_activates_default (GimpSizeEntry *gse,
|
|
|
|
gboolean setting)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GSList *list;
|
2005-02-10 00:57:18 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_SIZE_ENTRY (gse));
|
1999-03-15 02:03:58 +08:00
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
for (list = priv->fields; list; list = g_slist_next (list))
|
2005-02-10 00:57:18 +08:00
|
|
|
{
|
|
|
|
GimpSizeEntryField *gsef = list->data;
|
|
|
|
|
|
|
|
if (gsef->value_spinbutton)
|
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (gsef->value_spinbutton),
|
|
|
|
setting);
|
|
|
|
|
|
|
|
if (gsef->refval_spinbutton)
|
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (gsef->refval_spinbutton),
|
|
|
|
setting);
|
|
|
|
}
|
1999-03-15 02:03:58 +08:00
|
|
|
}
|
2003-10-15 19:57:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_size_entry_get_help_widget:
|
|
|
|
* @gse: a #GimpSizeEntry
|
|
|
|
* @field: the index of the widget you want to get a pointer to
|
|
|
|
*
|
|
|
|
* You shouldn't fiddle with the internals of a #GimpSizeEntry but
|
|
|
|
* if you want to set tooltips using gimp_help_set_help_data() you
|
|
|
|
* can use this function to get a pointer to the spinbuttons.
|
|
|
|
*
|
2019-08-03 06:10:14 +08:00
|
|
|
* Returns: (transfer none): a #GtkWidget pointer that you can attach a tooltip to.
|
2003-10-15 19:57:36 +08:00
|
|
|
**/
|
|
|
|
GtkWidget *
|
|
|
|
gimp_size_entry_get_help_widget (GimpSizeEntry *gse,
|
|
|
|
gint field)
|
|
|
|
{
|
2018-05-25 10:08:59 +08:00
|
|
|
GimpSizeEntryPrivate *priv;
|
|
|
|
GimpSizeEntryField *gsef;
|
2003-10-15 19:57:36 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (gse), NULL);
|
|
|
|
|
2024-08-01 11:55:31 +08:00
|
|
|
priv = gimp_size_entry_get_instance_private (gse);
|
2018-05-25 10:08:59 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail ((field >= 0) && (field < priv->number_of_fields), NULL);
|
|
|
|
|
|
|
|
gsef = g_slist_nth_data (priv->fields, field);
|
2003-10-15 19:57:36 +08:00
|
|
|
if (!gsef)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return (gsef->refval_spinbutton ?
|
|
|
|
gsef->refval_spinbutton : gsef->value_spinbutton);
|
|
|
|
}
|