libgimp*, plug-ins: reorganize the resource property choosers.

- Move the property widget functions for GimpResource properties into a new
  libgimp/gimppropwidgets.[ch] file. This mirrors the files
  libgimpwidgets/gimppropwidgets.[ch] which are for more generic property types.
- Rename the functions gimp_prop_chooser_*_new() to gimp_prop_*_chooser_new().
- gimp_prop_chooser_factory() doesn't need to be public.
- Add a label to GimpResourceSelectButton, make so that the
  gimp_prop_chooser_*_new() functions set the property nick to this label and
  add this label to the size group in GimpProcedureDialog.
This commit is contained in:
Jehan 2023-08-17 23:02:38 +02:00
parent 538cdea996
commit ead5d01d27
28 changed files with 428 additions and 382 deletions

View File

@ -149,7 +149,8 @@ gimp_brush_select_button_draw_interior (GimpResourceSelectButton *self)
/**
* gimp_brush_select_button_new:
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @label: (nullable): Button label or %NULL for no label.
* @resource: (nullable): Initial brush.
*
* Creates a new #GtkWidget that lets a user choose a brush.
@ -163,6 +164,7 @@ gimp_brush_select_button_draw_interior (GimpResourceSelectButton *self)
*/
GtkWidget *
gimp_brush_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource)
{
GtkWidget *self;
@ -173,10 +175,12 @@ gimp_brush_select_button_new (const gchar *title,
if (title)
self = g_object_new (GIMP_TYPE_BRUSH_SELECT_BUTTON,
"title", title,
"label", label,
"resource", resource,
NULL);
else
self = g_object_new (GIMP_TYPE_BRUSH_SELECT_BUTTON,
"label", label,
"resource", resource,
NULL);

View File

@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (GimpBrushSelectButton,
GtkWidget * gimp_brush_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource);

View File

@ -119,7 +119,8 @@ gimp_font_select_button_draw_interior (GimpResourceSelectButton *self)
/**
* gimp_font_select_button_new:
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @label: (nullable): Button label or %NULL for no label.
* @resource: (nullable): Initial font.
*
* Creates a new #GtkWidget that lets a user choose a font.
@ -133,6 +134,7 @@ gimp_font_select_button_draw_interior (GimpResourceSelectButton *self)
*/
GtkWidget *
gimp_font_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource)
{
GtkWidget *self;
@ -145,10 +147,12 @@ gimp_font_select_button_new (const gchar *title,
if (title)
self = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"title", title,
"label", label,
"resource", resource,
NULL);
else
self = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"label", label,
"resource", resource,
NULL);

View File

@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (GimpFontSelectButton,
GtkWidget * gimp_font_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource);

View File

@ -124,7 +124,8 @@ gimp_gradient_select_button_draw_interior (GimpResourceSelectButton *self)
/**
* gimp_gradient_select_button_new:
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @label: (nullable): Button label or %NULL for no label.
* @gradient: (nullable): Initial gradient.
*
* Creates a new #GtkWidget that lets a user choose a gradient.
@ -136,6 +137,7 @@ gimp_gradient_select_button_draw_interior (GimpResourceSelectButton *self)
*/
GtkWidget *
gimp_gradient_select_button_new (const gchar *title,
const gchar *label,
GimpResource *gradient)
{
GtkWidget *self;
@ -146,10 +148,12 @@ gimp_gradient_select_button_new (const gchar *title,
if (title)
self = g_object_new (GIMP_TYPE_GRADIENT_SELECT_BUTTON,
"title", title,
"label", label,
"resource", gradient,
NULL);
else
self = g_object_new (GIMP_TYPE_GRADIENT_SELECT_BUTTON,
"label", label,
"resource", gradient,
NULL);

View File

@ -38,6 +38,7 @@ G_DECLARE_FINAL_TYPE (GimpGradientSelectButton,
GtkWidget * gimp_gradient_select_button_new (const gchar *title,
const gchar *label,
GimpResource *gradient);

View File

@ -118,7 +118,8 @@ gimp_palette_select_button_draw_interior (GimpResourceSelectButton *self)
/**
* gimp_palette_select_button_new:
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @label: (nullable): Button label or %NULL for no label.
* @resource: (nullable): Initial palette.
*
* Creates a new #GtkWidget that lets a user choose a palette.
@ -132,6 +133,7 @@ gimp_palette_select_button_draw_interior (GimpResourceSelectButton *self)
*/
GtkWidget *
gimp_palette_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource)
{
GtkWidget *self;
@ -142,10 +144,12 @@ gimp_palette_select_button_new (const gchar *title,
if (title)
self = g_object_new (GIMP_TYPE_PALETTE_SELECT_BUTTON,
"title", title,
"label", label,
"resource", resource,
NULL);
else
self = g_object_new (GIMP_TYPE_PALETTE_SELECT_BUTTON,
"label", label,
"resource", resource,
NULL);

View File

@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (GimpPaletteSelectButton,
GtkWidget * gimp_palette_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource);

View File

@ -161,7 +161,8 @@ gimp_pattern_select_button_draw_interior (GimpResourceSelectButton *self)
/**
* gimp_pattern_select_button_new:
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
* @label: (nullable): Button label or %NULL for no label.
* @resource: (nullable): Initial pattern.
*
* Creates a new #GtkWidget that lets a user choose a pattern.
@ -175,6 +176,7 @@ gimp_pattern_select_button_draw_interior (GimpResourceSelectButton *self)
*/
GtkWidget *
gimp_pattern_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource)
{
GtkWidget *self;
@ -186,10 +188,12 @@ gimp_pattern_select_button_new (const gchar *title,
if (title)
self = g_object_new (GIMP_TYPE_PATTERN_SELECT_BUTTON,
"title", title,
"label", label,
"resource", resource,
NULL);
else
self = g_object_new (GIMP_TYPE_PATTERN_SELECT_BUTTON,
"label", label,
"resource", resource,
NULL);

View File

@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (GimpPatternSelectButton,
GtkWidget * gimp_pattern_select_button_new (const gchar *title,
const gchar *label,
GimpResource *resource);

View File

@ -26,9 +26,10 @@
#include "libgimpwidgets/gimpwidgets.h"
#include "libgimp/gimppropchooser-private.h"
#include "libgimp/gimppropwidgets.h"
#include "gimp.h"
#include "gimppropwidgets.h"
#include "gimpui.h"
#include "gimpprocedureconfig-private.h"
@ -776,23 +777,23 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
/* FUTURE: title the chooser more specifically, with a prefix that is the nick of the property. */
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_BRUSH)
{
widget = gimp_prop_chooser_brush_new (G_OBJECT (dialog->priv->config), property, _("Brush Chooser"));
widget = gimp_prop_brush_chooser_new (G_OBJECT (dialog->priv->config), property, _("Brush Chooser"));
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_FONT)
{
widget = gimp_prop_chooser_font_new (G_OBJECT (dialog->priv->config), property, _("Font Chooser"));
widget = gimp_prop_font_chooser_new (G_OBJECT (dialog->priv->config), property, _("Font Chooser"));
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_GRADIENT)
{
widget = gimp_prop_chooser_gradient_new (G_OBJECT (dialog->priv->config), property, _("Gradient Chooser"));
widget = gimp_prop_gradient_chooser_new (G_OBJECT (dialog->priv->config), property, _("Gradient Chooser"));
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_PALETTE)
{
widget = gimp_prop_chooser_palette_new (G_OBJECT (dialog->priv->config), property, _("Palette Chooser"));
widget = gimp_prop_palette_chooser_new (G_OBJECT (dialog->priv->config), property, _("Palette Chooser"));
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_PATTERN)
{
widget = gimp_prop_chooser_pattern_new (G_OBJECT (dialog->priv->config), property, _("Pattern Chooser"));
widget = gimp_prop_pattern_chooser_new (G_OBJECT (dialog->priv->config), property, _("Pattern Chooser"));
}
else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_ENUM)
{
@ -827,15 +828,19 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
else
{
const gchar *tooltip = g_param_spec_get_blurb (pspec);
if (tooltip)
gimp_help_set_help_data (widget, tooltip, NULL);
if (GIMP_IS_LABELED (widget) || label)
{
if (! label)
label = gimp_labeled_get_label (GIMP_LABELED (widget));
gtk_size_group_add_widget (dialog->priv->label_group, label);
if (label == NULL)
{
if (GIMP_IS_LABELED (widget))
label = gimp_labeled_get_label (GIMP_LABELED (widget));
else if (GIMP_IS_RESOURCE_SELECT_BUTTON (widget))
label = gimp_resource_select_button_get_label (GIMP_RESOURCE_SELECT_BUTTON (widget));
}
if (label != NULL)
gtk_size_group_add_widget (dialog->priv->label_group, label);
}
if ((binding = g_hash_table_lookup (dialog->priv->sensitive_data, property)))

View File

@ -1,92 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gegl-paramspecs.h>
#include <gtk/gtk.h>
#include "gimpui.h"
#include "gimppropchooser-private.h"
/* PropChooser
* A GtkWidget, more specifically a GtkButtonWidget.
* Pops up a chooser widget.
* Has Prop widget trait, i.e. binds property of the chooser widget
* to a property of a ProcedureConfig.
*
* For now, only for Resource choosers,
* which are named GimpResourceSelectButton ("select" means "choose")
*
* A factory creates the widgets.
*/
/* Not public i.e. not annotated.
*
* Used only by GimpProcedureDialog.
* These could be in the public API,
* if we want plugins to create their own widget that updates the plugin's own property.
*
* The following is in the style of GObject annotations, but is not public.
* @config: Object to which property is attached.
* @property_name: Name of property controlled by button.
*
* Creates a #GimpBrushSelectButton that displays and sets the property.
*
* @config is usually a GimpProcedureConfig (but it could be otherwise.)
* The @config must have a property with name @property_name.
* The property must be type #GimpBrush.
* The @property_name need not be "brush",
* since the @config may have more than one property of type #GimpBrush.
*
* The button is labeled with the @property_name's nick.
*
* When pushed, the button shows a dialog that lets the user choose a brush.
*/
GtkWidget *
gimp_prop_chooser_brush_new (GObject *config, const gchar *property_name, const gchar *title)
{
return gimp_prop_chooser_factory (gimp_brush_select_button_new, config, property_name, title);
};
GtkWidget *
gimp_prop_chooser_font_new (GObject *config, const gchar *property_name, const gchar *title)
{
return gimp_prop_chooser_factory (gimp_font_select_button_new, config, property_name, title);
};
GtkWidget *
gimp_prop_chooser_gradient_new (GObject *config, const gchar *property_name, const gchar *title)
{
return gimp_prop_chooser_factory (gimp_gradient_select_button_new, config, property_name, title);
};
GtkWidget *
gimp_prop_chooser_palette_new (GObject *config, const gchar *property_name, const gchar *title)
{
return gimp_prop_chooser_factory (gimp_palette_select_button_new, config, property_name, title);
};
GtkWidget *
gimp_prop_chooser_pattern_new (GObject *config, const gchar *property_name, const gchar *title)
{
return gimp_prop_chooser_factory (gimp_pattern_select_button_new, config, property_name, title);
};

View File

@ -1,47 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimpui.h> can be included directly."
#endif
#ifndef __GIMP_PROP_CHOOSER_H__
#define __GIMP_PROP_CHOOSER_H__
G_BEGIN_DECLS
GtkWidget *gimp_prop_chooser_brush_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget *gimp_prop_chooser_font_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget *gimp_prop_chooser_gradient_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget *gimp_prop_chooser_palette_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget *gimp_prop_chooser_pattern_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
G_END_DECLS
#endif /* __GIMP_PROP_CHOOSER_H__ */

View File

@ -1,118 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
static GimpResource * get_initial_resource_from_config (GObject *config,
const gchar *property_name);
/**
* gimp_prop_chooser_factory:
* @widget_creator_func: (scope async): Function that creates a chooser widget
* @config: Object to which property is attached.
* @property_name: Name of property set by the widget.
* @chooser_title: Title for the popup chooser dialog.
*
* Creates a #GimpResourceSelectButton that displays
* and sets the named property of the config.
*
* The factory makes many kinds of widgets.
* Parameterized by passing a creator function for a kind of widget.
* E.G. creator function is gimp_brush_select_button_new.
* The created widget must have a property named "resource".
*
* The factory wraps the widget so that it is a *prop* widget.
* A prop widget gets the initial choice from the @config
* and binds the property named @property_name
* of the @config to the widget's "resource" property.
*
* @config is usually a #GimpProcedureConfig (but it could be otherwise.)
* The @config must have a property with name @property_name.
* The property must be of type that matches that of the @widget_creator_func,
* e.g. #GimpBrush.
* The @property_name need not be "brush",
* since the @config may have more than one property of the same type e.g. #GimpBrush.
*
* Returns: (transfer full): The newly created #GimpResourceSelectButton widget.
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_chooser_factory (GimpResourceWidgetCreator widget_creator_func,
GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
GtkWidget *result_widget;
GimpResource *initial_resource;
g_debug ("%s called", G_STRFUNC);
initial_resource = get_initial_resource_from_config (config, property_name);
/* initial_resource may be NULL.
* When NULL, the widget creator will set it's resource property from context.
* We bind with G_BINDING_SYNC_CREATE which immediately flows widget to config.
* So the config property is not NULL after this.
*/
/* Create the wrapped widget. For example, call gimp_font_select_button_new.*/
result_widget = widget_creator_func (chooser_title, initial_resource);
g_object_unref (initial_resource);
/* Bind the wrapped widget's property to the config's property.
*
* The property name of the config can vary, e.g. "font" or "font1"
* The property name on widget is generic "resource" not specific e.g. "font"
*
* We bind G_BINDING_BIDIRECTIONAL.
* But we expect no other actor beside widget will change the config,
* (at least while the widget lives.)
* Bind from widget source to config target,
* because G_BINDING_SYNC_CREATE initially flows that way.
*/
g_object_bind_property (result_widget, /* Source for initial transfer */
"resource",
config, /* Target of initial transfer. */
property_name,
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
return result_widget;
}
static GimpResource *
get_initial_resource_from_config (GObject *config,
const gchar *property_name)
{
GimpResource *initial_resource;
g_debug ("%s called", G_STRFUNC);
g_object_get (config,
property_name, &initial_resource,
NULL);
return initial_resource;
}

View File

@ -1,46 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimpui.h> can be included directly."
#endif
#ifndef __GIMP_PROP_CHOOSER_FACTORY_H__
#define __GIMP_PROP_CHOOSER_FACTORY_H__
G_BEGIN_DECLS
/**
* GimpResourceWidgetCreator:
* @title: title of the popup chooser dialog
* @initial_resource: Resource to show as initial choice
*
* Function producing a chooser widget for a specific GimpResource object type.
* e.g. gimp_font_select_button_new
* Widgets for resource subclass choosers all have the same signature.
**/
typedef GtkWidget* (*GimpResourceWidgetCreator)(const gchar* title, GimpResource * initial_resource);
GtkWidget *gimp_prop_chooser_factory (GimpResourceWidgetCreator widget_creator_func,
GObject *config,
const gchar *property_name,
const gchar *chooser_title);
G_END_DECLS
#endif /* __GIMP_PROP_CHOOSER_FACTORY_H__ */

190
libgimp/gimppropwidgets.c Normal file
View File

@ -0,0 +1,190 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppropwidgets.c
* Copyright (C) 2023 Jehan
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "libgimp/gimpui.h"
/**
* SECTION: gimppropwidgets
* @title: GimpPropWidgets
* @short_description: Editable views on #GObject properties.
*
* Editable views on #GObject properties of types from libgimp, such as
* [class@Gimp.Resource] or [class@Gimp.Item] subclasses.
**/
typedef GtkWidget* (*GimpResourceWidgetCreator) (const gchar *title,
const gchar *label,
GimpResource *initial_resource);
/* utility function prototypes */
static GtkWidget * gimp_prop_resource_chooser_factory (GimpResourceWidgetCreator widget_creator_func,
GObject *config,
const gchar *property_name,
const gchar *chooser_title);
/**
* gimp_prop_brush_chooser_new:
* @config: Object to which property is attached.
* @property_name: Name of a [class@Gimp.Brush] property.
* @title: (nullable): title for the poppable dialog.
*
* Creates a [class@Gimp.BrushSelectButton] controlled by the specified property.
*
* Returns: (transfer full): A new [class@Gimp.BrushSelectButton].
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_brush_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
return gimp_prop_resource_chooser_factory (gimp_brush_select_button_new,
config, property_name, chooser_title);
}
/**
* gimp_prop_font_chooser_new:
* @config: Object to which property is attached.
* @property_name: Name of a [class@Gimp.Font] property.
* @title: (nullable): title for the poppable dialog.
*
* Creates a [class@Gimp.FontSelectButton] controlled by the specified property.
*
* Returns: (transfer full): A new [class@Gimp.FontSelectButton].
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_font_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
return gimp_prop_resource_chooser_factory (gimp_font_select_button_new,
config, property_name, chooser_title);
}
/**
* gimp_prop_gradient_chooser_new:
* @config: Object to which property is attached.
* @property_name: Name of a [class@Gimp.Gradient] property.
* @title: (nullable): title for the poppable dialog.
*
* Creates a [class@Gimp.GradientSelectButton] controlled by the specified property.
*
* Returns: (transfer full): A new [class@Gimp.GradientSelectButton].
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_gradient_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
return gimp_prop_resource_chooser_factory (gimp_gradient_select_button_new,
config, property_name, chooser_title);
}
/**
* gimp_prop_palette_chooser_new:
* @config: Object to which property is attached.
* @property_name: Name of a [class@Gimp.Palette] property.
* @title: (nullable): title for the poppable dialog.
*
* Creates a [class@Gimp.PaletteSelectButton] controlled by the specified property.
*
* Returns: (transfer full): A new [class@Gimp.PaletteSelectButton].
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_palette_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
return gimp_prop_resource_chooser_factory (gimp_palette_select_button_new,
config, property_name, chooser_title);
}
/**
* gimp_prop_pattern_chooser_new:
* @config: Object to which property is attached.
* @property_name: Name of a [class@Gimp.Pattern] property.
* @title: (nullable): title for the poppable dialog.
*
* Creates a [class@Gimp.PatternSelectButton] controlled by the specified property.
*
* Returns: (transfer full): A new [class@Gimp.PatternSelectButton].
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_pattern_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
return gimp_prop_resource_chooser_factory (gimp_pattern_select_button_new,
config, property_name, chooser_title);
}
/*******************************/
/* private utility functions */
/*******************************/
static GtkWidget *
gimp_prop_resource_chooser_factory (GimpResourceWidgetCreator widget_creator_func,
GObject *config,
const gchar *property_name,
const gchar *chooser_title)
{
GParamSpec *param_spec;
GtkWidget *prop_chooser;
GimpResource *initial_resource;
const gchar *label;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
property_name);
g_return_val_if_fail (param_spec != NULL, NULL);
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_OBJECT) &&
g_type_is_a (param_spec->value_type, GIMP_TYPE_RESOURCE), NULL);
g_object_get (config,
property_name, &initial_resource,
NULL);
label = g_param_spec_get_nick (param_spec);
/* Create the wrapped widget. For example, call gimp_font_select_button_new.
* When initial_resource is NULL, the widget creator will set it's resource
* property from context.
*/
prop_chooser = widget_creator_func (chooser_title, label, initial_resource);
g_object_unref (initial_resource);
g_object_bind_property (prop_chooser, "resource",
config, property_name,
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
return prop_chooser;
}

54
libgimp/gimppropwidgets.h Normal file
View File

@ -0,0 +1,54 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppropwidgets.h
* Copyright (C) 2023 Jehan
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimpui.h> can be included directly."
#endif
#ifndef __GIMP_PROP_WIDGETS_H__
#define __GIMP_PROP_WIDGETS_H__
G_BEGIN_DECLS
/* GimpParamResource */
GtkWidget * gimp_prop_brush_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget * gimp_prop_font_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget * gimp_prop_gradient_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget * gimp_prop_palette_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
GtkWidget * gimp_prop_pattern_chooser_new (GObject *config,
const gchar *property_name,
const gchar *chooser_title);
G_END_DECLS
#endif /* __GIMP_PROP_WIDGETS_H__ */

View File

@ -78,6 +78,7 @@ enum
{
PROP_0,
PROP_TITLE,
PROP_LABEL,
PROP_RESOURCE,
N_PROPS
};
@ -87,13 +88,16 @@ typedef struct
{
GimpResource *resource;
gchar *title;
gchar *label;
gchar *callback;
GtkWidget *interior_widget;
GtkWidget *label_widget;
} GimpResourceSelectButtonPrivate;
/* local function prototypes */
static void gimp_resource_select_button_constructed (GObject *object);
static void gimp_resource_select_button_dispose (GObject *object);
static void gimp_resource_select_button_finalize (GObject *object);
@ -135,6 +139,7 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_resource_select_button_constructed;
object_class->dispose = gimp_resource_select_button_dispose;
object_class->finalize = gimp_resource_select_button_finalize;
object_class->set_property = gimp_resource_select_button_set_property;
@ -157,6 +162,21 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
/**
* GimpResourceSelectButton:label:
*
* Label text with mnemonic.
*
* Since: 3.0
*/
resource_button_props[PROP_LABEL] =
g_param_spec_string ("label",
"Label",
"The label to be used next to the button",
NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
/**
* GimpResourceSelectButton:resource:
*
@ -199,9 +219,28 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
static void
gimp_resource_select_button_init (GimpResourceSelectButton *self)
{
GimpResourceSelectButtonPrivate *priv;
priv = gimp_resource_select_button_get_instance_private (GIMP_RESOURCE_SELECT_BUTTON (self));
gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing (GTK_BOX (self), 6);
priv->label_widget = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (self), priv->label_widget, FALSE, FALSE, 0);
}
static void
gimp_resource_select_button_constructed (GObject *object)
{
GimpResourceSelectButtonPrivate *priv;
priv = gimp_resource_select_button_get_instance_private (GIMP_RESOURCE_SELECT_BUTTON (object));
gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->label_widget), priv->label);
gtk_widget_show (GTK_WIDGET (priv->label_widget));
G_OBJECT_CLASS (gimp_resource_select_button_parent_class)->constructed (object);
}
static void
@ -244,6 +283,7 @@ gimp_resource_select_button_finalize (GObject *object)
GimpResourceSelectButtonPrivate *priv = gimp_resource_select_button_get_instance_private (self);
g_clear_pointer (&priv->title, g_free);
g_clear_pointer (&priv->label, g_free);
G_OBJECT_CLASS (gimp_resource_select_button_parent_class)->finalize (object);
}
@ -371,6 +411,26 @@ gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
}
}
/**
* gimp_resource_select_button_get_label:
* @widget: A [class@ResourceSelectButton].
*
* Returns the label widget.
*
* Returns: (transfer none): the [class@Gtk.Widget] showing the label text.
* Since: 3.0
*/
GtkWidget *
gimp_resource_select_button_get_label (GimpResourceSelectButton *widget)
{
GimpResourceSelectButtonPrivate *priv;
g_return_val_if_fail (GIMP_IS_RESOURCE_SELECT_BUTTON (widget), NULL);
priv = gimp_resource_select_button_get_instance_private (widget);
return priv->label_widget;
}
/* private functions */
@ -408,6 +468,10 @@ gimp_resource_select_button_set_property (GObject *object,
priv->title = g_value_dup_string (gvalue);
break;
case PROP_LABEL:
priv->label = g_value_dup_string (gvalue);
break;
case PROP_RESOURCE:
priv->resource = g_value_get_object (gvalue);
break;
@ -433,6 +497,10 @@ gimp_resource_select_button_get_property (GObject *object,
g_value_set_string (value, priv->title);
break;
case PROP_LABEL:
g_value_set_string (value, priv->label);
break;
case PROP_RESOURCE:
g_value_set_object (value, priv->resource);
break;

View File

@ -49,6 +49,8 @@ struct _GimpResourceSelectButtonClass
GimpResource * gimp_resource_select_button_get_resource (GimpResourceSelectButton *self);
void gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
GimpResource *resource);
GtkWidget * gimp_resource_select_button_get_label (GimpResourceSelectButton *widget);
/* API from below, used by subclasses e.g. GimpBrushSelectButton */

View File

@ -45,6 +45,13 @@ typedef struct _GimpVectors GimpVectors;
typedef struct _GimpDisplay GimpDisplay;
typedef struct _GimpResource GimpResource;
typedef struct _GimpBrush GimpBrush;
typedef struct _GimpFont GimpFont;
typedef struct _GimpGradient GimpGradient;
typedef struct _GimpPattern GimpPattern;
typedef struct _GimpPalette GimpPalette;
/* FIXME move somewhere else */

View File

@ -58,12 +58,12 @@ EXPORTS
gimp_procedure_dialog_set_sensitive_if_in
gimp_progress_bar_get_type
gimp_progress_bar_new
gimp_prop_chooser_brush_new
gimp_prop_chooser_factory
gimp_prop_chooser_font_new
gimp_prop_chooser_gradient_new
gimp_prop_chooser_palette_new
gimp_prop_chooser_pattern_new
gimp_prop_brush_chooser_new
gimp_prop_font_chooser_new
gimp_prop_gradient_chooser_new
gimp_prop_palette_chooser_new
gimp_prop_pattern_chooser_new
gimp_resource_select_button_get_label
gimp_resource_select_button_get_resource
gimp_resource_select_button_get_type
gimp_resource_select_button_set_clickable

View File

@ -44,7 +44,7 @@
#include <libgimp/gimpproceduredialog.h>
#include <libgimp/gimpprocview.h>
#include <libgimp/gimpprogressbar.h>
#include <libgimp/gimppropchooserfactory.h>
#include <libgimp/gimppropwidgets.h>
#include <libgimp/gimpsaveproceduredialog.h>
#include <libgimp/gimpzoompreview.h>

View File

@ -271,7 +271,7 @@ libgimpui_sources_introspectable = [
'gimpproceduredialog.c',
'gimpprocview.c',
'gimpprogressbar.c',
'gimppropchooserfactory.c',
'gimppropwidgets.c',
'gimpresourceselectbutton.c',
'gimpsaveproceduredialog.c',
'gimpui.c',
@ -281,7 +281,6 @@ libgimpui_sources_introspectable = [
libgimpui_sources = [
libgimpui_sources_introspectable,
gimpuimarshal,
'gimppropchooser-private.c',
]
libgimpui_headers_introspectable = [
@ -304,7 +303,7 @@ libgimpui_headers_introspectable = [
'gimpproceduredialog.h',
'gimpprocview.h',
'gimpprogressbar.h',
'gimppropchooserfactory.h',
'gimppropwidgets.h',
'gimpresourceselectbutton.h',
'gimpsaveproceduredialog.h',
'gimpzoompreview.h',

View File

@ -45,50 +45,49 @@
/* utility function prototypes */
static void set_param_spec (GObject *object,
GtkWidget *widget,
GParamSpec *param_spec);
static void set_radio_spec (GObject *object,
GParamSpec *param_spec);
static GParamSpec * get_param_spec (GObject *object);
static void set_param_spec (GObject *object,
GtkWidget *widget,
GParamSpec *param_spec);
static void set_radio_spec (GObject *object,
GParamSpec *param_spec);
static GParamSpec * get_param_spec (GObject *object);
static GParamSpec * find_param_spec (GObject *object,
const gchar *property_name,
const gchar *strloc);
static GParamSpec * check_param_spec_quiet (
GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static GParamSpec * check_param_spec (GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static GParamSpec * check_param_spec_w (GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static GParamSpec * find_param_spec (GObject *object,
const gchar *property_name,
const gchar *strloc);
static GParamSpec * check_param_spec_quiet (GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static GParamSpec * check_param_spec (GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static GParamSpec * check_param_spec_w (GObject *object,
const gchar *property_name,
GType type,
const gchar *strloc);
static gboolean get_numeric_values (GObject *object,
GParamSpec *param_spec,
gdouble *value,
gdouble *lower,
gdouble *upper,
const gchar *strloc);
static gboolean get_numeric_values (GObject *object,
GParamSpec *param_spec,
gdouble *value,
gdouble *lower,
gdouble *upper,
const gchar *strloc);
static void connect_notify (GObject *config,
const gchar *property_name,
GCallback callback,
gpointer callback_data);
static void connect_notify (GObject *config,
const gchar *property_name,
GCallback callback,
gpointer callback_data);
static gboolean gimp_prop_widget_double_to_factor (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data);
static gboolean gimp_prop_widget_double_from_factor (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data);
static gboolean gimp_prop_widget_double_to_factor (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data);
static gboolean gimp_prop_widget_double_from_factor (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data);
/******************/

View File

@ -23,8 +23,8 @@
#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
#endif
#ifndef __GIMP_PROP_WIDGETS_H__
#define __GIMP_PROP_WIDGETS_H__
#ifndef __GIMPWIDGETS_PROP_WIDGETS_H__
#define __GIMPWIDGETS_PROP_WIDGETS_H__
G_BEGIN_DECLS
@ -252,4 +252,4 @@ GtkWidget * gimp_prop_icon_image_new (GObject *config,
G_END_DECLS
#endif /* __GIMP_PROP_WIDGETS_H__ */
#endif /* __GIMPWIDGETS_PROP_WIDGETS_H__ */

View File

@ -1160,7 +1160,7 @@ explorer_dialog (void)
&gradient_samples);
gradient_button = gimp_gradient_select_button_new (_("FractalExplorer Gradient"),
GIMP_RESOURCE (gradient));
NULL, GIMP_RESOURCE (gradient));
g_signal_connect (gradient_button, "resource-set",
G_CALLBACK (explorer_gradient_select_callback), NULL);

View File

@ -507,7 +507,7 @@ gfig_dialog (GimpGfig *gfig)
/* brush selector in Stroke frame */
gfig_context->brush_select
= gimp_brush_select_button_new ("Brush",
= gimp_brush_select_button_new ("Brush", "Brush",
GIMP_RESOURCE (gfig_context->default_style.brush));
g_signal_connect (gfig_context->brush_select, "resource-set",
G_CALLBACK (gfig_brush_changed_callback), NULL);
@ -573,7 +573,7 @@ gfig_dialog (GimpGfig *gfig)
/* A page for the pattern selector */
gfig_context->pattern_select
= gimp_pattern_select_button_new ("Pattern",
= gimp_pattern_select_button_new ("Pattern", "Pattern",
GIMP_RESOURCE (gfig_context->default_style.pattern));
g_signal_connect (gfig_context->pattern_select, "resource-set",
G_CALLBACK (gfig_pattern_changed_callback), NULL);
@ -583,7 +583,7 @@ gfig_dialog (GimpGfig *gfig)
/* A page for the gradient selector */
gfig_context->gradient_select
= gimp_gradient_select_button_new ("Gradient",
= gimp_gradient_select_button_new ("Gradient", "Gradient",
GIMP_RESOURCE (gfig_context->default_style.gradient));
g_signal_connect (gfig_context->gradient_select, "resource-set",
G_CALLBACK (gfig_gradient_changed_callback), NULL);

View File

@ -606,23 +606,23 @@ script_fu_resource_widget (const gchar *title,
if (g_type_is_a (resource_type, GIMP_TYPE_FONT))
{
result_widget = gimp_font_select_button_new (title, resource);
result_widget = gimp_font_select_button_new (title, title, resource);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_BRUSH))
{
result_widget = gimp_brush_select_button_new (title, resource);
result_widget = gimp_brush_select_button_new (title, title, resource);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_GRADIENT))
{
result_widget = gimp_gradient_select_button_new (title, resource);
result_widget = gimp_gradient_select_button_new (title, title, resource);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PALETTE))
{
result_widget = gimp_palette_select_button_new (title, resource);
result_widget = gimp_palette_select_button_new (title, title, resource);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PATTERN))
{
result_widget = gimp_pattern_select_button_new (title, resource);
result_widget = gimp_pattern_select_button_new (title, title, resource);
}
else
{