1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-05 21:02:42 +02:00

libgimp, libgimpwidgets: Add GimpCoordinates widget...

...to GimpProcedureDialog.
This patch allows plugin developers to create a
GimpCoordinates widget (two GimpSizeEntries linked
together with a chain and with a units combo) in the
GimpProcedureDialog.

It is largely a wrapper for gimp_prop_coordinates_new ().
This patch also makes that function more responsive
to the unit property, now that GimpUnit has a proper
GParamSpec implementation. The default unit and
whether we show pixels, percents, or the resolution
spinners can now be determined via the unit
parameter (if set) rather than relying on
hardcoded values.

As a demonstration, the Tile plug-in's width/height
entries were restored to what they were before the
GimpProcedureDialog port, with units and a chain
link between values.
This commit is contained in:
Alx Sa
2025-06-10 19:37:35 +00:00
parent c1a56ff0b3
commit 963830fd91
5 changed files with 169 additions and 13 deletions

View File

@@ -1089,6 +1089,115 @@ gimp_procedure_dialog_get_color_widget (GimpProcedureDialog *dialog,
return widget;
}
/**
* gimp_procedure_dialog_get_coordinates:
* @dialog: the associated #GimpProcedureDialog.
* @coordinates_id: Identifier for #GimpCoordinates widget.
* @x_property: Name of int or double property for X coordinate.
* @y_property: Name of int or double property for Y coordinate.
* @unit_property: Name of unit property.
* @unit_format: A printf-like unit-format string as is used with
* gimp_unit_menu_new().
* @update_policy: How the automatic pixel <-> real-world-unit
* calculations should be done.
* @x_resolution: The resolution (in dpi) for the X coordinate.
* @y_resolution: The resolution (in dpi) for the Y coordinate.
*
* Creates a new #GimpCoordinates for @x_property and @y_property which
* must necessarily be an integer or double property.
* The associated @unit_property must be a GimpUnit property.
*
* If a widget has already been created for this procedure, it will be
* returned instead (whatever its actual widget type).
*
* Returns: (transfer none): the #GtkWidget representing @coordinates_id.
* The object belongs to @dialog and must not be
* freed.
*/
GtkWidget *
gimp_procedure_dialog_get_coordinates (GimpProcedureDialog *dialog,
const gchar *coordinates_id,
const gchar *x_property,
const gchar *y_property,
const gchar *unit_property,
const gchar *unit_format,
GimpSizeEntryUpdatePolicy update_policy,
gdouble x_resolution,
gdouble y_resolution)
{
GimpProcedureDialogPrivate *priv;
GtkWidget *widget = NULL;
GtkWidget *label = NULL;
GParamSpec *pspec_x;
GParamSpec *pspec_y;
GParamSpec *pspec_unit;
g_return_val_if_fail (GIMP_IS_PROCEDURE_DIALOG (dialog), NULL);
g_return_val_if_fail (coordinates_id != NULL, NULL);
g_return_val_if_fail (x_property != NULL, NULL);
g_return_val_if_fail (y_property != NULL, NULL);
g_return_val_if_fail (unit_property != NULL, NULL);
priv = gimp_procedure_dialog_get_instance_private (dialog);
pspec_x = g_object_class_find_property (G_OBJECT_GET_CLASS (priv->config),
x_property);
pspec_y = g_object_class_find_property (G_OBJECT_GET_CLASS (priv->config),
y_property);
pspec_unit = g_object_class_find_property (G_OBJECT_GET_CLASS (priv->config),
unit_property);
if (! pspec_x)
{
g_warning ("%s: parameter %s does not exist.",
G_STRFUNC, x_property);
return NULL;
}
if (! pspec_y)
{
g_warning ("%s: parameter %s does not exist.",
G_STRFUNC, y_property);
return NULL;
}
if (! pspec_unit)
{
g_warning ("%s: unit parameter %s does not exist.",
G_STRFUNC, unit_property);
return NULL;
}
g_return_val_if_fail (G_PARAM_SPEC_TYPE (pspec_x) == G_TYPE_PARAM_INT ||
G_PARAM_SPEC_TYPE (pspec_x) == G_TYPE_PARAM_UINT ||
G_PARAM_SPEC_TYPE (pspec_x) == G_TYPE_PARAM_DOUBLE, NULL);
g_return_val_if_fail (G_PARAM_SPEC_TYPE (pspec_y) == G_TYPE_PARAM_INT ||
G_PARAM_SPEC_TYPE (pspec_y) == G_TYPE_PARAM_UINT ||
G_PARAM_SPEC_TYPE (pspec_y) == G_TYPE_PARAM_DOUBLE, NULL);
g_return_val_if_fail (G_PARAM_SPEC_TYPE (pspec_unit) == GIMP_TYPE_PARAM_UNIT, NULL);
/* First check if it already exists. */
widget = g_hash_table_lookup (priv->widgets, coordinates_id);
if (widget)
return widget;
widget = gimp_prop_coordinates_new (G_OBJECT (priv->config), x_property,
y_property, unit_property, unit_format,
update_policy, x_resolution,
y_resolution, TRUE);
/* Add labels */
label = gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (widget),
g_param_spec_get_nick (pspec_x), 0, 1, 0.0);
gtk_widget_set_margin_end (label, 6);
label = gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (widget),
g_param_spec_get_nick (pspec_y), 0, 2, 0.0);
gtk_widget_set_margin_end (label, 6);
g_hash_table_insert (priv->widgets, g_strdup (coordinates_id), widget);
if (g_object_is_floating (widget))
g_object_ref_sink (widget);
return widget;
}
/**
* gimp_procedure_dialog_get_int_combo:
* @dialog: the associated #GimpProcedureDialog.

View File

@@ -75,6 +75,16 @@ GtkWidget * gimp_procedure_dialog_get_color_widget (GimpProcedureDialog *dialog
const gchar *property,
gboolean editable,
GimpColorAreaType type);
GtkWidget * gimp_procedure_dialog_get_coordinates (GimpProcedureDialog *dialog,
const gchar *coordinates_id,
const gchar *x_property,
const gchar *y_property,
const gchar *unit_property,
const gchar *unit_format,
GimpSizeEntryUpdatePolicy
update_policy,
gdouble x_resolution,
gdouble y_resolution);
GtkWidget * gimp_procedure_dialog_get_int_combo (GimpProcedureDialog *dialog,
const gchar *property,
GimpIntStore *store);

View File

@@ -49,6 +49,7 @@ EXPORTS
gimp_procedure_dialog_fill_paned
gimp_procedure_dialog_fill_scrolled_window
gimp_procedure_dialog_get_color_widget
gimp_procedure_dialog_get_coordinates
gimp_procedure_dialog_get_drawable_preview
gimp_procedure_dialog_get_int_combo
gimp_procedure_dialog_get_int_radio

View File

@@ -3944,12 +3944,39 @@ gimp_prop_coordinates_new (GObject *config,
gdouble yresolution,
gboolean has_chainbutton)
{
GimpUnit *unit_type;
GtkWidget *entry;
GtkWidget *chainbutton = NULL;
GtkWidget *chainbutton = NULL;
gboolean show_pixels = FALSE;
gboolean show_percents = FALSE;
gboolean show_resolution = TRUE;
entry = gimp_size_entry_new (2, gimp_unit_inch (), unit_format,
FALSE, FALSE, TRUE, 10,
update_policy);
if (unit_property_name != NULL)
{
GParamSpec *pspec_unit = NULL;
pspec_unit = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
unit_property_name);
if (pspec_unit && GIMP_IS_PARAM_SPEC_UNIT (pspec_unit))
{
show_pixels = gimp_param_spec_unit_pixel_allowed (pspec_unit);
show_percents = gimp_param_spec_unit_percent_allowed (pspec_unit);
if (show_pixels)
show_resolution = FALSE;
g_object_get (config, unit_property_name, &unit_type, NULL);
}
}
else
{
unit_type = gimp_unit_inch ();
}
entry = gimp_size_entry_new (2, unit_type, unit_format,
show_pixels, show_percents, show_resolution,
10, update_policy);
if (has_chainbutton)
{

View File

@@ -168,6 +168,12 @@ tile_create_procedure (GimpPlugIn *plug_in,
1, GIMP_MAX_IMAGE_SIZE, 1,
G_PARAM_READWRITE);
gimp_procedure_add_unit_aux_argument (procedure, "tile-size-unit",
_("Tile size unit of measure"),
_("Tile size unit of measure"),
TRUE, TRUE, gimp_unit_pixel (),
GIMP_PARAM_READWRITE);
gimp_procedure_add_boolean_argument (procedure, "new-image",
_("New _image"),
_("Create a new image"),
@@ -452,6 +458,8 @@ tile_dialog (GimpProcedure *procedure,
GtkWidget *dlg;
gint width;
gint height;
gdouble xres;
gdouble yres;
gboolean run;
gimp_ui_init (PLUG_IN_BINARY);
@@ -459,6 +467,8 @@ tile_dialog (GimpProcedure *procedure,
width = gimp_drawable_get_width (drawable);
height = gimp_drawable_get_height (drawable);
gimp_image_get_resolution (image, &xres, &yres);
g_object_set (config,
"new-width", width,
"new-height", height,
@@ -470,17 +480,16 @@ tile_dialog (GimpProcedure *procedure,
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dlg),
"new-size-label", _("Tile to New Size"),
FALSE, FALSE);
/* TODO: we should have a new GimpProcedureDialog widget which would tie 2
* arguments for dimensions (or coordinates), and possibly more aux args for
* the constrain boolean choice, the unit, etc.
*/
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dlg),
"new-size-box",
"new-width", "new-height",
NULL);
gimp_procedure_dialog_get_coordinates (GIMP_PROCEDURE_DIALOG (dlg),
"coordinates", "new-width",
"new-height", "tile-size-unit",
"%a", GIMP_SIZE_ENTRY_UPDATE_SIZE,
xres, yres);
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dlg),
"new-size-frame", "new-size-label", FALSE,
"new-size-box");
"coordinates");
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dlg), "new-size-frame", "new-image", NULL);
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dlg));