app, libgimp, plug-ins: a lot of cleanup in GimpResourceSelect* code.

- Removing useless or redundant code.
- Simplifying various logics.
- Using GimpResource directly in temporary PDB procedures, not resource names.
- Better cleanup of the core resource chooser when the plug-in dialog quits (we
  need it to ask core to close also any visible resource chooser dialog).
- Replace the "Close" button by more common OK/Cancel. In particular, the
  GimpPdbDialog now properly keeps track of the initial object and when hitting
  "Cancel" (or Escape key), this initial object is set back.
- Clean up some of the comments, especially when the code is self explanatory.

There is still much more to clean and improve, but it's a first welcome step.
This commit is contained in:
Jehan 2023-08-16 23:53:33 +02:00
parent 19a005ad0f
commit b578fd8cf1
13 changed files with 160 additions and 336 deletions

View file

@ -278,7 +278,7 @@ gimp_brush_select_run_callback (GimpPdbDialog *dialog,
dialog->caller_context, dialog->caller_context,
NULL, error, NULL, error,
dialog->callback_name, dialog->callback_name,
G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_RESOURCE, object,
G_TYPE_DOUBLE, gimp_context_get_opacity (dialog->context) * 100.0, G_TYPE_DOUBLE, gimp_context_get_opacity (dialog->context) * 100.0,
G_TYPE_INT, GIMP_BRUSH_SELECT (dialog)->spacing, G_TYPE_INT, GIMP_BRUSH_SELECT (dialog)->spacing,
GIMP_TYPE_LAYER_MODE, gimp_context_get_paint_mode (dialog->context), GIMP_TYPE_LAYER_MODE, gimp_context_get_paint_mode (dialog->context),

View file

@ -106,7 +106,7 @@ gimp_font_select_run_callback (GimpPdbDialog *dialog,
dialog->caller_context, dialog->caller_context,
NULL, error, NULL, error,
dialog->callback_name, dialog->callback_name,
G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_RESOURCE, object,
G_TYPE_BOOLEAN, closing, G_TYPE_BOOLEAN, closing,
G_TYPE_NONE); G_TYPE_NONE);
} }

View file

@ -183,7 +183,7 @@ gimp_gradient_select_run_callback (GimpPdbDialog *dialog,
dialog->caller_context, dialog->caller_context,
NULL, error, NULL, error,
dialog->callback_name, dialog->callback_name,
G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_RESOURCE, object,
G_TYPE_INT, array->length / sizeof (gdouble), G_TYPE_INT, array->length / sizeof (gdouble),
GIMP_TYPE_FLOAT_ARRAY, array->data, GIMP_TYPE_FLOAT_ARRAY, array->data,
G_TYPE_BOOLEAN, closing, G_TYPE_BOOLEAN, closing,

View file

@ -109,8 +109,8 @@ gimp_palette_select_run_callback (GimpPdbDialog *dialog,
dialog->caller_context, dialog->caller_context,
NULL, error, NULL, error,
dialog->callback_name, dialog->callback_name,
G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_RESOURCE, object,
G_TYPE_INT, gimp_palette_get_n_colors (palette), G_TYPE_INT, gimp_palette_get_n_colors (palette),
G_TYPE_BOOLEAN, closing, G_TYPE_BOOLEAN, closing,
G_TYPE_NONE); G_TYPE_NONE);
} }

View file

@ -124,7 +124,7 @@ gimp_pattern_select_run_callback (GimpPdbDialog *dialog,
dialog->caller_context, dialog->caller_context,
NULL, error, NULL, error,
dialog->callback_name, dialog->callback_name,
G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_RESOURCE, object,
G_TYPE_INT, gimp_temp_buf_get_width (pattern->mask), G_TYPE_INT, gimp_temp_buf_get_width (pattern->mask),
G_TYPE_INT, gimp_temp_buf_get_height (pattern->mask), G_TYPE_INT, gimp_temp_buf_get_height (pattern->mask),
G_TYPE_INT, babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (pattern->mask)), G_TYPE_INT, babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (pattern->mask)),

View file

@ -138,7 +138,9 @@ static void
gimp_pdb_dialog_init (GimpPdbDialog *dialog) gimp_pdb_dialog_init (GimpPdbDialog *dialog)
{ {
gtk_dialog_add_button (GTK_DIALOG (dialog), gtk_dialog_add_button (GTK_DIALOG (dialog),
_("_Close"), GTK_RESPONSE_CLOSE); _("_OK"), GTK_RESPONSE_OK);
gtk_dialog_add_button (GTK_DIALOG (dialog),
_("_Cancel"), GTK_RESPONSE_CANCEL);
} }
static void static void
@ -163,8 +165,6 @@ gimp_pdb_dialog_constructed (GObject *object)
gimp_context_set_by_type (dialog->context, dialog->select_type, gimp_context_set_by_type (dialog->context, dialog->select_type,
dialog->initial_object); dialog->initial_object);
dialog->initial_object = NULL;
signal_name = gimp_context_type_to_signal_name (dialog->select_type); signal_name = gimp_context_type_to_signal_name (dialog->select_type);
g_signal_connect_object (dialog->context, signal_name, g_signal_connect_object (dialog->context, signal_name,
@ -187,6 +187,7 @@ gimp_pdb_dialog_dispose (GObject *object)
g_clear_object (&dialog->pdb); g_clear_object (&dialog->pdb);
g_clear_object (&dialog->caller_context); g_clear_object (&dialog->caller_context);
g_clear_object (&dialog->context); g_clear_object (&dialog->context);
g_clear_object (&dialog->initial_object);
g_clear_pointer (&dialog->callback_name, g_free); g_clear_pointer (&dialog->callback_name, g_free);
@ -218,8 +219,7 @@ gimp_pdb_dialog_set_property (GObject *object,
break; break;
case PROP_INITIAL_OBJECT: case PROP_INITIAL_OBJECT:
/* don't ref, see constructor */ dialog->initial_object = g_value_dup_object (value);
dialog->initial_object = g_value_get_object (value);
break; break;
case PROP_CALLBACK_NAME: case PROP_CALLBACK_NAME:
@ -244,9 +244,12 @@ gimp_pdb_dialog_response (GtkDialog *gtk_dialog,
{ {
GimpPdbDialog *dialog = GIMP_PDB_DIALOG (gtk_dialog); GimpPdbDialog *dialog = GIMP_PDB_DIALOG (gtk_dialog);
if (response_id != GTK_RESPONSE_OK)
gimp_context_set_by_type (dialog->context, dialog->select_type,
dialog->initial_object);
gimp_pdb_dialog_run_callback (&dialog, TRUE); gimp_pdb_dialog_run_callback (&dialog, TRUE);
if (dialog) gtk_widget_destroy (GTK_WIDGET (dialog));
gtk_widget_destroy (GTK_WIDGET (dialog));
} }
void void

View file

@ -814,7 +814,6 @@ EXPORTS
gimp_resource_is_pattern gimp_resource_is_pattern
gimp_resource_is_valid gimp_resource_is_valid
gimp_resource_rename gimp_resource_rename
gimp_resource_select_destroy
gimp_resource_select_new gimp_resource_select_new
gimp_resource_select_set gimp_resource_select_set
gimp_save_procedure_get_support_comment gimp_save_procedure_get_support_comment

View file

@ -20,27 +20,9 @@
#include "gimp.h" #include "gimp.h"
/* Data bounced back and forth to/from core and libgimp,
* and here from the temp PDB procedure to the idle func.
* But it is opaque to core, passed and returned unaltered.
*
* Not all fields are meaningful in each direction or transfer.
* !!! We don't pass resource to core in this struct,
* only from the temp callback to the idle func.
*
* Lifetime is as long as the remote dialog is open.
* Closing the chooser dialog frees the adaption struct.
*/
typedef struct typedef struct
{ {
/* This portion is passed to and from idle. */ GType resource_type;
guint idle_id;
gint resource_id;
GType resource_type;
gboolean closing;
/* This portion is passed to and from core, and to idle. */
gchar *temp_PDB_callback_name;
GimpResourceChoosedCallback callback; GimpResourceChoosedCallback callback;
gpointer owner_data; gpointer owner_data;
GDestroyNotify data_destroy; GDestroyNotify data_destroy;
@ -49,12 +31,12 @@ typedef struct
/* local */ /* local */
static void gimp_resource_data_free (GimpResourceAdaption *adaption); static void gimp_resource_data_free (GimpResourceAdaption *adaption);
static GimpValueArray * gimp_temp_resource_run (GimpProcedure *procedure, static GimpValueArray * gimp_temp_resource_run (GimpProcedure *procedure,
GimpProcedureConfig *config, GimpProcedureConfig *config,
gpointer run_data); gpointer run_data);
static gboolean gimp_temp_resource_idle (GimpResourceAdaption *adaption); static gboolean gimp_resource_select_remove_after_run (const gchar *procedure_name);
/* public */ /* public */
@ -131,11 +113,10 @@ static void
create_callback_PDB_procedure_params (GimpProcedure *procedure, create_callback_PDB_procedure_params (GimpProcedure *procedure,
GType resource_type) GType resource_type)
{ {
GIMP_PROC_ARG_STRING (procedure, "resource-name", GIMP_PROC_ARG_RESOURCE (procedure, "resource",
"Resource name", "Resource",
"The resource name", "The resource",
NULL, G_PARAM_READWRITE);
G_PARAM_READWRITE);
/* Create args for the extra, superfluous args that core is passing.*/ /* Create args for the extra, superfluous args that core is passing.*/
if (g_type_is_a (resource_type, GIMP_TYPE_FONT)) if (g_type_is_a (resource_type, GIMP_TYPE_FONT))
@ -247,7 +228,7 @@ static gboolean
popup_remote_chooser (const gchar *title, popup_remote_chooser (const gchar *title,
GBytes *parent_handle, GBytes *parent_handle,
GimpResource *resource, GimpResource *resource,
gchar *temp_PDB_callback_name, const gchar *temp_PDB_callback_name,
GType resource_type) GType resource_type)
{ {
gboolean result = FALSE; gboolean result = FALSE;
@ -284,52 +265,19 @@ popup_remote_chooser (const gchar *title,
return result; return result;
} }
/*Does nothing, quietly, when the remote dialog is not open. */
static void
close_remote_chooser (gchar *temp_PDB_callback_name,
GType resource_type)
{
if (g_type_is_a (resource_type, GIMP_TYPE_FONT))
{
gimp_fonts_close_popup (temp_PDB_callback_name);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_GRADIENT))
{
gimp_gradients_close_popup (temp_PDB_callback_name);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_BRUSH))
{
gimp_brushes_close_popup (temp_PDB_callback_name);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PALETTE))
{
gimp_palettes_close_popup (temp_PDB_callback_name);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PATTERN))
{
gimp_patterns_close_popup (temp_PDB_callback_name);
}
else
{
g_warning ("%s: unhandled resource type", G_STRFUNC);
}
}
/** /**
* gimp_resource_select_new: * gimp_resource_select_new:
* @title: Title of the resource selection dialog. * @title: Title of the resource selection dialog.
* @resource: The resource to set as the initial choice. * @resource: The resource to set as the initial choice.
* @resource_type: The type of the subclass of resource. * @resource_type: The type of the subclass of [class@Resource].
* @callback: (scope notified): The callback function to call when a user chooses a resource. * @callback: (scope notified): The callback function to call when the user chooses a resource.
* @owner_data: (closure callback): The run_data given to @callback. * @owner_data: (closure callback): The run_data given to @callback.
* @data_destroy: (destroy owner_data): The destroy function for @owner_data. * @data_destroy: (destroy owner_data): The destroy function for @owner_data.
* *
* Invoke a resource chooser dialog which may call @callback with the chosen * Invoke a resource chooser dialog which may call @callback with the chosen
* resource and owner's @data. * @resource and @owner_data.
* *
* A proxy to a remote dialog in core, which knows the model i.e. installed resources. * A proxy to a remote dialog in core, which knows the installed resources.
*
* Generic on type of #GimpResource subclass passed in @resource_type.
* *
* Returns: (transfer none): the name of a temporary PDB procedure. The * Returns: (transfer none): the name of a temporary PDB procedure. The
* string belongs to the resource selection dialog and will be * string belongs to the resource selection dialog and will be
@ -349,23 +297,18 @@ gimp_resource_select_new (const gchar *title,
gchar *temp_PDB_callback_name; gchar *temp_PDB_callback_name;
GimpResourceAdaption *adaption; GimpResourceAdaption *adaption;
g_debug ("%s", G_STRFUNC);
g_return_val_if_fail (resource != NULL, NULL); g_return_val_if_fail (resource != NULL, NULL);
g_return_val_if_fail (callback != NULL, NULL); g_return_val_if_fail (callback != NULL, NULL);
g_return_val_if_fail (resource_type != 0, NULL); g_return_val_if_fail (g_type_is_a (resource_type, GIMP_TYPE_RESOURCE), NULL);
temp_PDB_callback_name = gimp_pdb_temp_procedure_name (gimp_get_pdb ()); temp_PDB_callback_name = gimp_pdb_temp_procedure_name (gimp_get_pdb ());
adaption = g_slice_new0 (GimpResourceAdaption); adaption = g_slice_new0 (GimpResourceAdaption);
adaption->temp_PDB_callback_name = temp_PDB_callback_name; adaption->callback = callback;
adaption->callback = callback; adaption->owner_data = owner_data;
adaption->owner_data = owner_data; adaption->data_destroy = data_destroy;
adaption->data_destroy = data_destroy; adaption->resource_type = resource_type;
adaption->resource_type = resource_type;
/* !!! Only part of the adaption has been initialized. */
procedure = gimp_procedure_new (plug_in, procedure = gimp_procedure_new (plug_in,
temp_PDB_callback_name, temp_PDB_callback_name,
@ -378,13 +321,14 @@ gimp_resource_select_new (const gchar *title,
gimp_plug_in_add_temp_procedure (plug_in, procedure); gimp_plug_in_add_temp_procedure (plug_in, procedure);
g_object_unref (procedure); g_object_unref (procedure);
g_free (temp_PDB_callback_name);
if (popup_remote_chooser (title, parent_handle, resource, temp_PDB_callback_name, resource_type)) if (popup_remote_chooser (title, parent_handle, resource, gimp_procedure_get_name (procedure), resource_type))
{ {
/* Allow callbacks to be watched */ /* Allow callbacks to be watched */
gimp_plug_in_extension_enable (plug_in); gimp_plug_in_extension_enable (plug_in);
return temp_PDB_callback_name; return gimp_procedure_get_name (procedure);
} }
else else
{ {
@ -395,78 +339,42 @@ gimp_resource_select_new (const gchar *title,
} }
void /* gimp_resource_select_set:
gimp_resource_select_destroy (const gchar *temp_PDB_callback_name) * @callback_name: a callback name as returned by [func@resource_select_new].
{ * @resource: a [class@Resource] of type @resource_type.
GimpPlugIn *plug_in = gimp_get_plug_in ();
g_return_if_fail (temp_PDB_callback_name != NULL);
gimp_plug_in_remove_temp_procedure (plug_in, temp_PDB_callback_name);
}
/* Set currently selected resource in remote chooser.
* *
* Calls a PDB procedure. * Set currently selected resource in remote chooser.
*
* Note core is still using string name of resource,
* so pdb/groups/<foo>_select.pdb, <foo>_set_popup must have type string.
*/ */
void void
gimp_resource_select_set (const gchar *temp_pdb_callback, gimp_resource_select_set (const gchar *callback_name,
GimpResource *resource, GimpResource *resource)
GType resource_type)
{ {
GType resource_type;
g_return_if_fail (resource != NULL);
resource_type = G_TYPE_FROM_INSTANCE (resource);
g_return_if_fail (g_type_is_a (resource_type, GIMP_TYPE_RESOURCE));
if (g_type_is_a (resource_type, GIMP_TYPE_FONT)) if (g_type_is_a (resource_type, GIMP_TYPE_FONT))
{ gimp_fonts_set_popup (callback_name, GIMP_FONT (resource));
gimp_fonts_set_popup (temp_pdb_callback, GIMP_FONT (resource));
}
else if (g_type_is_a (resource_type, GIMP_TYPE_GRADIENT)) else if (g_type_is_a (resource_type, GIMP_TYPE_GRADIENT))
{ gimp_gradients_set_popup (callback_name, GIMP_GRADIENT (resource));
gimp_gradients_set_popup (temp_pdb_callback, GIMP_GRADIENT (resource));
}
else if (g_type_is_a (resource_type, GIMP_TYPE_BRUSH)) else if (g_type_is_a (resource_type, GIMP_TYPE_BRUSH))
{ gimp_brushes_set_popup (callback_name, GIMP_BRUSH (resource));
gimp_brushes_set_popup (temp_pdb_callback, GIMP_BRUSH (resource));
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PALETTE)) else if (g_type_is_a (resource_type, GIMP_TYPE_PALETTE))
{ gimp_palettes_set_popup (callback_name, GIMP_PALETTE (resource));
gimp_palettes_set_popup (temp_pdb_callback, GIMP_PALETTE (resource));
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PATTERN)) else if (g_type_is_a (resource_type, GIMP_TYPE_PATTERN))
{ gimp_patterns_set_popup (callback_name, GIMP_PATTERN (resource));
gimp_patterns_set_popup (temp_pdb_callback, GIMP_PATTERN (resource));
}
else else
{ g_return_if_reached ();
g_warning ("%s: unhandled resource type", G_STRFUNC);
}
} }
/* private functions */ /* private functions */
/* Free a GimpResourceAdaption struct.
* A GimpResourceAdaption and this func are passed to a GimpProcedure
* and this func is called back when the procedure is removed.
*
* This can be called for the exception: failed to open remote dialog.
*
* Each allocated field must be safely freed (not assuming it is valid pointer.)
*/
static void static void
gimp_resource_data_free (GimpResourceAdaption *adaption) gimp_resource_data_free (GimpResourceAdaption *adaption)
{ {
if (adaption->idle_id)
g_source_remove (adaption->idle_id);
if (adaption->temp_PDB_callback_name)
{
close_remote_chooser (adaption->temp_PDB_callback_name,
adaption->resource_type);
g_free (adaption->temp_PDB_callback_name);
}
if (adaption->data_destroy) if (adaption->data_destroy)
adaption->data_destroy (adaption->owner_data); adaption->data_destroy (adaption->owner_data);
@ -482,48 +390,33 @@ gimp_temp_resource_run (GimpProcedure *procedure,
gpointer run_data) gpointer run_data)
{ {
GimpResourceAdaption *adaption = run_data; GimpResourceAdaption *adaption = run_data;
gchar *resource_name;
GimpResource *resource; GimpResource *resource;
gboolean closing;
g_object_get (config, g_object_get (config,
"resource-name", &resource_name, "resource", &resource,
"closing", &adaption->closing, "closing", &closing,
NULL); NULL);
resource = gimp_resource_get_by_name (adaption->resource_type, if (adaption->callback)
resource_name); adaption->callback (resource, closing,
adaption->owner_data);
adaption->resource_id = gimp_resource_get_id (resource); if (closing)
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc) gimp_resource_select_remove_after_run,
g_strdup (gimp_procedure_get_name (procedure)),
g_free);
if (! adaption->idle_id) g_object_unref (resource);
adaption->idle_id = g_idle_add ((GSourceFunc) gimp_temp_resource_idle,
adaption);
g_free (resource_name);
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL); return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
} }
static gboolean static gboolean
gimp_temp_resource_idle (GimpResourceAdaption *adaption) gimp_resource_select_remove_after_run (const gchar *procedure_name)
{ {
adaption->idle_id = 0; gimp_plug_in_remove_temp_procedure (gimp_get_plug_in (), procedure_name);
if (adaption->callback)
adaption->callback (gimp_resource_get_by_id (adaption->resource_id),
adaption->closing,
adaption->owner_data);
adaption->resource_id = 0;
if (adaption->closing)
{
gchar *temp_PDB_callback_name = adaption->temp_PDB_callback_name;
adaption->temp_PDB_callback_name = NULL;
gimp_resource_select_destroy (temp_PDB_callback_name);
g_free (temp_PDB_callback_name);
}
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }

View file

@ -45,11 +45,8 @@ const gchar * gimp_resource_select_new (const gchar *title
gpointer owner_data, gpointer owner_data,
GDestroyNotify data_destroy); GDestroyNotify data_destroy);
void gimp_resource_select_destroy (const gchar *temp_pdb_callback); void gimp_resource_select_set (const gchar *callback_name,
GimpResource *resource);
void gimp_resource_select_set (const gchar *temp_pdb_callback,
GimpResource *resource,
GType resource_type);
G_END_DECLS G_END_DECLS

View file

@ -94,44 +94,42 @@ typedef struct
{ {
GimpResource *resource; GimpResource *resource;
gchar *title; gchar *title;
const gchar *temp_callback_from_remote_dialog; gchar *callback;
GtkWidget *interior_widget; GtkWidget *interior_widget;
} GimpResourceSelectButtonPrivate; } GimpResourceSelectButtonPrivate;
/* local function prototypes */ /* local function prototypes */
static void gimp_resource_select_button_dispose (GObject *object); static void gimp_resource_select_button_dispose (GObject *object);
static void gimp_resource_select_button_finalize (GObject *object); static void gimp_resource_select_button_finalize (GObject *object);
static void gimp_resource_select_button_set_property (GObject *object, static void gimp_resource_select_button_set_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_resource_select_button_get_property (GObject *object, static void gimp_resource_select_button_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_resource_select_button_clicked (GimpResourceSelectButton *self); static void gimp_resource_select_button_clicked (GimpResourceSelectButton *self);
static void gimp_resource_select_button_callback (GimpResource *resource, static void gimp_resource_select_button_callback (GimpResource *resource,
gboolean dialog_closing, gboolean dialog_closing,
gpointer user_data); gpointer user_data);
static void gimp_resource_select_drag_data_received (GimpResourceSelectButton *self, static void gimp_resource_select_drag_data_received (GimpResourceSelectButton *self,
GdkDragContext *context, GdkDragContext *context,
gint x, gint x,
gint y, gint y,
GtkSelectionData *selection, GtkSelectionData *selection,
guint info, guint info,
guint time); guint time);
static void gimp_resource_select_button_set_remote_dialog (GimpResourceSelectButton *self, static void gimp_resource_select_button_set_remote_dialog (GimpResourceSelectButton *self,
GimpResource *resource); GimpResource *resource);
static void gimp_resource_select_button_draw_interior (GimpResourceSelectButton *self,
GimpResource *resource);
static guint resource_button_signals[LAST_SIGNAL] = { 0 }; static guint resource_button_signals[LAST_SIGNAL] = { 0 };
static GParamSpec *resource_button_props[N_PROPS] = { NULL, }; static GParamSpec *resource_button_props[N_PROPS] = { NULL, };
@ -157,7 +155,7 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
* *
* The title to be used for the resource selection popup dialog. * The title to be used for the resource selection popup dialog.
* *
* Since: 2.4 * Since: 3.0
*/ */
resource_button_props[PROP_TITLE] = resource_button_props[PROP_TITLE] =
g_param_spec_string ("title", g_param_spec_string ("title",
@ -172,7 +170,7 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
* *
* The currently selected resource. * The currently selected resource.
* *
* Since: 2.4 * Since: 3.0
*/ */
resource_button_props[PROP_RESOURCE] = resource_button_props[PROP_RESOURCE] =
gimp_param_spec_resource ("resource", gimp_param_spec_resource ("resource",
@ -192,7 +190,7 @@ gimp_resource_select_button_class_init (GimpResourceSelectButtonClass *klass)
* *
* The ::resource-set signal is emitted when the user selects a resource. * The ::resource-set signal is emitted when the user selects a resource.
* *
* Since: 2.4 * Since: 3.0
*/ */
resource_button_signals[RESOURCE_SET] = resource_button_signals[RESOURCE_SET] =
g_signal_new ("resource-set", g_signal_new ("resource-set",
@ -217,7 +215,32 @@ gimp_resource_select_button_init (GimpResourceSelectButton *self)
static void static void
gimp_resource_select_button_dispose (GObject *self) gimp_resource_select_button_dispose (GObject *self)
{ {
gimp_resource_select_button_close_popup (GIMP_RESOURCE_SELECT_BUTTON (self)); GimpResourceSelectButtonPrivate *priv;
GimpResourceSelectButtonClass *klass;
priv = gimp_resource_select_button_get_instance_private (GIMP_RESOURCE_SELECT_BUTTON (self));
klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self);
if (priv->callback)
{
GType resource_type = klass->resource_type;
if (resource_type == GIMP_TYPE_FONT)
gimp_fonts_close_popup (priv->callback);
else if (resource_type == GIMP_TYPE_GRADIENT)
gimp_gradients_close_popup (priv->callback);
else if (resource_type == GIMP_TYPE_BRUSH)
gimp_brushes_close_popup (priv->callback);
else if (resource_type == GIMP_TYPE_PALETTE)
gimp_palettes_close_popup (priv->callback);
else if (resource_type == GIMP_TYPE_PATTERN)
gimp_patterns_close_popup (priv->callback);
else
g_warning ("%s: unhandled resource type", G_STRFUNC);
gimp_plug_in_remove_temp_procedure (gimp_get_plug_in (), priv->callback);
g_clear_pointer (&priv->callback, g_free);
}
G_OBJECT_CLASS (gimp_resource_select_button_parent_class)->dispose (self); G_OBJECT_CLASS (gimp_resource_select_button_parent_class)->dispose (self);
} }
@ -235,10 +258,10 @@ gimp_resource_select_button_finalize (GObject *object)
/** /**
* gimp_resource_select_button_set_drag_target: * gimp_resource_select_button_set_drag_target:
* @self: A #GimpResourceSelectButton * @self: A [class@ResourceSelectButton]
* @drag_region_widget: An interior widget to be a droppable region * @drag_region_widget: An interior widget to be a droppable region
* and emit "drag-data-received" signal * and emit "drag-data-received" signal
* @drag_target: The drag target to accept * @drag_target: The drag target to accept
* *
* Called by a subclass init to specialize the instance. * Called by a subclass init to specialize the instance.
* *
@ -272,7 +295,7 @@ gimp_resource_select_button_set_drag_target (GimpResourceSelectButton *self,
/** /**
* gimp_resource_select_button_set_clickable: * gimp_resource_select_button_set_clickable:
* @self: A #GimpResourceSelectButton * @self: A [class@ResourceSelectButton]
* @widget: An interior widget that emits "clicked" signal * @widget: An interior widget that emits "clicked" signal
* *
* Called by a subclass init to specialize the instance. * Called by a subclass init to specialize the instance.
@ -304,9 +327,8 @@ gimp_resource_select_button_set_clickable (GimpResourceSelectButton *self,
* Gets the currently selected resource. * Gets the currently selected resource.
* *
* Returns: (transfer none): an internal copy of the resource which must not be freed. * Returns: (transfer none): an internal copy of the resource which must not be freed.
* You should ref and unref it when you want to own the resource.
* *
* Since: 2.4 * Since: 3.0
*/ */
GimpResource * GimpResource *
gimp_resource_select_button_get_resource (GimpResourceSelectButton *self) gimp_resource_select_button_get_resource (GimpResourceSelectButton *self)
@ -328,7 +350,7 @@ gimp_resource_select_button_get_resource (GimpResourceSelectButton *self)
* Sets the currently selected resource. * Sets the currently selected resource.
* This will select the resource in both the button and any chooser popup. * This will select the resource in both the button and any chooser popup.
* *
* Since: 2.4 * Since: 3.0
*/ */
void void
gimp_resource_select_button_set_resource (GimpResourceSelectButton *self, gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
@ -341,7 +363,7 @@ gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
priv = gimp_resource_select_button_get_instance_private (self); priv = gimp_resource_select_button_get_instance_private (self);
if (priv->temp_callback_from_remote_dialog) if (priv->callback)
{ {
/* A popup chooser dialog is already shown. /* A popup chooser dialog is already shown.
* Call its setter to change the selection there * Call its setter to change the selection there
@ -358,31 +380,6 @@ gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
} }
/* Calls the virtual method of a similar name, which subclasses must override.
*
* resource: The instance to be drawn.
*
* A subclass knows how to draw its interior.
* Called by super when the view is invalidated (needs to be redrawn.)
* Not public.
*/
static void
gimp_resource_select_button_draw_interior (GimpResourceSelectButton *self,
GimpResource *resource)
{
GimpResourceSelectButtonClass *klass;
g_return_if_fail (GIMP_IS_RESOURCE_SELECT_BUTTON (self));
g_return_if_fail (GIMP_IS_RESOURCE (resource));
klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self);
g_return_if_fail (klass->draw_interior != NULL);
klass->draw_interior (self);
}
/* private functions */ /* private functions */
static void static void
@ -395,19 +392,13 @@ gimp_resource_select_button_set_remote_dialog (GimpResourceSelectButton *self,
g_return_if_fail (GIMP_IS_RESOURCE_SELECT_BUTTON (self)); g_return_if_fail (GIMP_IS_RESOURCE_SELECT_BUTTON (self));
g_return_if_fail (resource != NULL); g_return_if_fail (resource != NULL);
priv = gimp_resource_select_button_get_instance_private (self); priv = gimp_resource_select_button_get_instance_private (self);
klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self); klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self);
g_return_if_fail (klass->resource_type != G_TYPE_INVALID); g_return_if_fail (klass->resource_type != G_TYPE_INVALID);
g_return_if_fail (klass->resource_type == G_TYPE_FROM_INSTANCE (resource));
/* The ultimate remote setter is e.g. gimp_fonts_set_popup, a PDB procedure. gimp_resource_select_set (priv->callback, resource);
*
* !!! Use the passed resource, not priv->resource.
* Expect a callback which will change priv->resource.
*/
gimp_resource_select_set (priv->temp_callback_from_remote_dialog,
resource,
klass->resource_type);
} }
static void static void
@ -479,18 +470,13 @@ gimp_resource_select_button_callback (GimpResource *resource,
priv->resource = resource; priv->resource = resource;
/* Feedback user choice of resource into the look of the widget interior. GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self)->draw_interior (self);
* Call virtual method overridden by subclass.
*/
gimp_resource_select_button_draw_interior (self, priv->resource);
if (dialog_closing) if (dialog_closing)
priv->temp_callback_from_remote_dialog = NULL; g_clear_pointer (&priv->callback, g_free);
g_signal_emit (self, resource_button_signals[RESOURCE_SET], 0, g_signal_emit (self, resource_button_signals[RESOURCE_SET], 0, resource, dialog_closing);
resource, dialog_closing); g_object_notify_by_pspec (G_OBJECT (self), resource_button_props[PROP_RESOURCE]);
g_object_notify_by_pspec (G_OBJECT (self),
resource_button_props[PROP_RESOURCE]);
} }
static void static void
@ -499,7 +485,7 @@ gimp_resource_select_button_clicked (GimpResourceSelectButton *self)
GimpResourceSelectButtonPrivate *priv = gimp_resource_select_button_get_instance_private (self); GimpResourceSelectButtonPrivate *priv = gimp_resource_select_button_get_instance_private (self);
GimpResourceSelectButtonClass *klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self); GimpResourceSelectButtonClass *klass = GIMP_RESOURCE_SELECT_BUTTON_GET_CLASS (self);
if (priv->temp_callback_from_remote_dialog) if (priv->callback)
{ {
/* Popup already created. Calling setter raises the popup. */ /* Popup already created. Calling setter raises the popup. */
gimp_resource_select_button_set_remote_dialog (self, priv->resource); gimp_resource_select_button_set_remote_dialog (self, priv->resource);
@ -512,15 +498,14 @@ gimp_resource_select_button_clicked (GimpResourceSelectButton *self)
if (GIMP_IS_DIALOG (toplevel)) if (GIMP_IS_DIALOG (toplevel))
handle = gimp_dialog_get_native_handle (GIMP_DIALOG (toplevel)); handle = gimp_dialog_get_native_handle (GIMP_DIALOG (toplevel));
/* Call GimpResourceSelect which dispatches on resource_type. */ priv->callback = g_strdup (gimp_resource_select_new (priv->title,
priv->temp_callback_from_remote_dialog = handle,
gimp_resource_select_new (priv->title, priv->resource,
handle, klass->resource_type,
priv->resource, gimp_resource_select_button_callback,
klass->resource_type, self,
gimp_resource_select_button_callback, NULL));
self, gimp_resource_select_button_set_remote_dialog (self, priv->resource);
NULL); /* No func to free data. */
} }
} }
@ -575,33 +560,3 @@ gimp_resource_select_drag_data_received (GimpResourceSelectButton *self,
g_free (str); g_free (str);
} }
/**
* gimp_resource_select_button_close_popup:
* @self: A #GimpResourceSelectButton
*
* Closes the popup resource chooser dialog associated with @self.
*
* FUTURE: Possibly obsolete this by making it private,
* since only called by script-fu-interface.c.
* Might be needed if we allow plugins to implement their own dialogs.
*
* Since: 2.4
*/
void
gimp_resource_select_button_close_popup (GimpResourceSelectButton *self)
{
GimpResourceSelectButtonPrivate *priv;
g_return_if_fail (GIMP_IS_RESOURCE_SELECT_BUTTON (self));
priv = gimp_resource_select_button_get_instance_private (self);
if (priv->temp_callback_from_remote_dialog)
{
gimp_resource_select_destroy (priv->temp_callback_from_remote_dialog);
priv->temp_callback_from_remote_dialog = NULL;
}
/* Else already closed. */
}

View file

@ -26,9 +26,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GIMP_TYPE_RESOURCE_SELECT_BUTTON (gimp_resource_select_button_get_type ()) #define GIMP_TYPE_RESOURCE_SELECT_BUTTON (gimp_resource_select_button_get_type ())
G_DECLARE_DERIVABLE_TYPE (GimpResourceSelectButton, G_DECLARE_DERIVABLE_TYPE (GimpResourceSelectButton, gimp_resource_select_button, GIMP, RESOURCE_SELECT_BUTTON, GtkBox)
gimp_resource_select_button,
GIMP, RESOURCE_SELECT_BUTTON, GtkBox)
struct _GimpResourceSelectButtonClass struct _GimpResourceSelectButtonClass
{ {
@ -46,18 +44,17 @@ struct _GimpResourceSelectButtonClass
gpointer padding[8]; gpointer padding[8];
}; };
GimpResource *gimp_resource_select_button_get_resource (GimpResourceSelectButton *self); GimpResource * gimp_resource_select_button_get_resource (GimpResourceSelectButton *self);
void gimp_resource_select_button_set_resource (GimpResourceSelectButton *self, void gimp_resource_select_button_set_resource (GimpResourceSelectButton *self,
GimpResource *resource); GimpResource *resource);
/* API from below, used by subclasses e.g. GimpBrushSelectButton */ /* API from below, used by subclasses e.g. GimpBrushSelectButton */
void gimp_resource_select_button_set_drag_target (GimpResourceSelectButton *self, void gimp_resource_select_button_set_drag_target (GimpResourceSelectButton *self,
GtkWidget *drag_region_widget, GtkWidget *drag_region_widget,
const GtkTargetEntry *drag_target); const GtkTargetEntry *drag_target);
void gimp_resource_select_button_set_clickable (GimpResourceSelectButton *self, void gimp_resource_select_button_set_clickable (GimpResourceSelectButton *self,
GtkWidget *widget); GtkWidget *widget);
void gimp_resource_select_button_close_popup (GimpResourceSelectButton *self);
G_END_DECLS G_END_DECLS

View file

@ -64,7 +64,6 @@ EXPORTS
gimp_prop_chooser_gradient_new gimp_prop_chooser_gradient_new
gimp_prop_chooser_palette_new gimp_prop_chooser_palette_new
gimp_prop_chooser_pattern_new gimp_prop_chooser_pattern_new
gimp_resource_select_button_close_popup
gimp_resource_select_button_get_resource gimp_resource_select_button_get_resource
gimp_resource_select_button_get_type gimp_resource_select_button_get_type
gimp_resource_select_button_set_clickable gimp_resource_select_button_set_clickable

View file

@ -646,29 +646,10 @@ script_fu_resource_widget (const gchar *title,
static void static void
script_fu_interface_quit (SFScript *script) script_fu_interface_quit (SFScript *script)
{ {
gint i;
g_return_if_fail (script != NULL); g_return_if_fail (script != NULL);
g_return_if_fail (sf_interface != NULL); g_return_if_fail (sf_interface != NULL);
g_free (sf_interface->title); g_free (sf_interface->title);
for (i = 0; i < script->n_args; i++)
switch (script->args[i].type)
{
case SF_FONT:
case SF_PALETTE:
case SF_PATTERN:
case SF_GRADIENT:
case SF_BRUSH:
gimp_resource_select_button_close_popup
(GIMP_RESOURCE_SELECT_BUTTON (sf_interface->widgets[i]));
break;
default:
break;
}
g_free (sf_interface->widgets); g_free (sf_interface->widgets);
g_free (sf_interface->last_command); g_free (sf_interface->last_command);