[gimp] app, libgimpwidgets: allowing changing a dockable settings value while…
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app, libgimpwidgets: allowing changing a dockable settings value while…
- Date: Sun, 6 Mar 2022 18:37:36 +0000 (UTC)
commit 622d0da43ee19ac993a87b8d36f85382aa858f9d
Author: Jehan <jehan girinstud io>
Date: Sun Mar 6 14:31:27 2022 +0100
app, libgimpwidgets: allowing changing a dockable settings value while…
… blinking it.
This will be necessary to demo new features available only in some
situations. E.g. a new option in line art detection mode of bucket fill
would require said mode to be enabled.
app/dialogs/welcome-dialog.c | 27 +++-
app/tools/gimpbucketfilltool.c | 2 +-
app/widgets/gimppropwidgets.c | 28 ++--
app/widgets/gimpwidgets-utils.c | 274 ++++++++++++++++++++++++++++-------
app/widgets/gimpwidgets-utils.h | 2 +
libgimpwidgets/gimppropwidgets.c | 66 ++++-----
libgimpwidgets/gimpwidgets-private.c | 42 ++++++
libgimpwidgets/gimpwidgets-private.h | 19 ++-
8 files changed, 343 insertions(+), 117 deletions(-)
---
diff --git a/app/dialogs/welcome-dialog.c b/app/dialogs/welcome-dialog.c
index 642e9b3e31..302d33bf41 100644
--- a/app/dialogs/welcome-dialog.c
+++ b/app/dialogs/welcome-dialog.c
@@ -525,8 +525,10 @@ welcome_dialog_release_item_activated (GtkListBox *listbox,
for (i = 0; script_steps[i]; i++)
{
gchar **ids;
- gchar *dockable_id = NULL;
- gchar *widget_id = NULL;
+ gchar *dockable_id = NULL;
+ gchar *widget_id = NULL;
+ gchar **settings = NULL;
+ gchar *settings_value = NULL;
ids = g_strsplit (script_steps[i], ":", 2);
/* Even if the string doesn't contain a second part, it is
@@ -536,6 +538,14 @@ welcome_dialog_release_item_activated (GtkListBox *listbox,
dockable_id = ids[0];
widget_id = ids[1];
+ if (widget_id != NULL)
+ {
+ settings = g_strsplit (widget_id, "=", 2);
+
+ widget_id = settings[0];
+ settings_value = settings[1];
+ }
+
/* Allowing white spaces so that the demo in XML metadata can be
* spaced-out or even on multiple lines for clarity.
*/
@@ -559,27 +569,30 @@ welcome_dialog_release_item_activated (GtkListBox *listbox,
/* All tool button IDs start with "tools-". This allows to
* write shorter tool names in the demo script.
*/
- if (! g_str_has_prefix (widget_id, "tools-"))
+ if (widget_id != NULL && ! g_str_has_prefix (widget_id, "tools-"))
{
gchar *tmp = g_strdup_printf ("tools-%s", widget_id);
- g_free (ids[1]);
- widget_id = ids[1] = tmp;
+ g_free (settings[0]);
+ widget_id = settings[0] = tmp;
}
gimp_blink_toolbox (gimp, widget_id, &blink_script);
}
else
{
- gimp_blink_dockable (gimp, dockable_id, widget_id, &blink_script);
+ gimp_blink_dockable (gimp, dockable_id,
+ widget_id, settings_value,
+ &blink_script);
}
g_strfreev (ids);
+ if (settings)
+ g_strfreev (settings);
}
if (blink_script != NULL)
gimp_blink_play_script (blink_script);
- g_list_free (blink_script);
g_strfreev (script_steps);
}
diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c
index aaffba4724..e44206c617 100644
--- a/app/tools/gimpbucketfilltool.c
+++ b/app/tools/gimpbucketfilltool.c
@@ -632,7 +632,7 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool,
{
gimp_tool_message_literal (tool, display,
_("No valid line art source selected."));
- gimp_blink_dockable (display->gimp, "gimp-tool-options", "line-art-source", NULL);
+ gimp_blink_dockable (display->gimp, "gimp-tool-options", "line-art-source", NULL, NULL);
return;
}
diff --git a/app/widgets/gimppropwidgets.c b/app/widgets/gimppropwidgets.c
index 9f02e5d3c6..6975b660f0 100644
--- a/app/widgets/gimppropwidgets.c
+++ b/app/widgets/gimppropwidgets.c
@@ -140,7 +140,7 @@ gimp_prop_expanding_frame_new (GObject *config,
if (button)
*button = toggle;
- gimp_widget_set_identifier (frame, property_name);
+ gimp_widget_set_bound_property (frame, config, property_name);
gtk_widget_show (frame);
return frame;
@@ -243,7 +243,7 @@ gimp_prop_boolean_icon_box_new (GObject *config,
G_CALLBACK (gimp_prop_radio_button_notify),
button);
- gimp_widget_set_identifier (box, property_name);
+ gimp_widget_set_bound_property (box, config, property_name);
gtk_widget_show (box);
return box;
@@ -326,7 +326,7 @@ gimp_prop_layer_mode_box_new (GObject *config,
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (box, property_name);
+ gimp_widget_set_bound_property (box, config, property_name);
gtk_widget_show (box);
return box;
@@ -398,7 +398,7 @@ gimp_prop_color_button_new (GObject *config,
G_CALLBACK (gimp_prop_color_button_notify),
button);
- gimp_widget_set_identifier (button, property_name);
+ gimp_widget_set_bound_property (button, config, property_name);
gtk_widget_show (button);
return button;
@@ -566,7 +566,7 @@ gimp_prop_angle_dial_new (GObject *config,
l, (GDestroyNotify) g_free);
}
- gimp_widget_set_identifier (dial, property_name);
+ gimp_widget_set_bound_property (dial, config, property_name);
gtk_widget_show (dial);
return dial;
@@ -624,7 +624,7 @@ gimp_prop_angle_range_dial_new (GObject *config,
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (dial, alpha_property_name);
+ gimp_widget_set_bound_property (dial, config, alpha_property_name);
gtk_widget_show (dial);
return dial;
@@ -668,7 +668,7 @@ gimp_prop_polar_new (GObject *config,
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (polar, angle_property_name);
+ gimp_widget_set_bound_property (polar, config, angle_property_name);
gtk_widget_show (polar);
return polar;
@@ -742,7 +742,7 @@ gimp_prop_range_new (GObject *config,
if (sorted)
gimp_gtk_adjustment_chain (adjustment1, adjustment2);
- gimp_widget_set_identifier (vbox, lower_property_name);
+ gimp_widget_set_bound_property (vbox, config, lower_property_name);
gtk_widget_show (vbox);
return vbox;
@@ -844,7 +844,7 @@ gimp_prop_view_new (GObject *config,
G_CALLBACK (gimp_prop_view_notify),
view);
- gimp_widget_set_identifier (view, property_name);
+ gimp_widget_set_bound_property (view, config, property_name);
gtk_widget_show (view);
return view;
@@ -1045,7 +1045,7 @@ gimp_prop_number_pair_entry_new (GObject *config,
G_CALLBACK (gimp_prop_number_pair_entry_config_notify),
number_pair_entry);
- gimp_widget_set_identifier (number_pair_entry, left_number_property);
+ gimp_widget_set_bound_property (number_pair_entry, config, left_number_property);
gtk_widget_show (number_pair_entry);
return number_pair_entry;
@@ -1188,7 +1188,7 @@ gimp_prop_language_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_language_combo_box_notify),
combo);
- gimp_widget_set_identifier (combo, property_name);
+ gimp_widget_set_bound_property (combo, config, property_name);
gtk_widget_show (combo);
return combo;
@@ -1289,7 +1289,7 @@ gimp_prop_language_entry_new (GObject *config,
G_CALLBACK (gimp_prop_language_entry_notify),
entry);
- gimp_widget_set_identifier (entry, property_name);
+ gimp_widget_set_bound_property (entry, config, property_name);
gtk_widget_show (entry);
return entry;
@@ -1444,7 +1444,7 @@ gimp_prop_profile_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_profile_combo_notify),
combo);
- gimp_widget_set_identifier (combo, property_name);
+ gimp_widget_set_bound_property (combo, config, property_name);
gtk_widget_show (combo);
return combo;
@@ -1584,7 +1584,7 @@ gimp_prop_compression_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_compression_combo_box_notify),
combo);
- gimp_widget_set_identifier (combo, property_name);
+ gimp_widget_set_bound_property (combo, config, property_name);
gtk_widget_show (combo);
return combo;
diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c
index 2aed53ab82..cbd62b647f 100644
--- a/app/widgets/gimpwidgets-utils.c
+++ b/app/widgets/gimpwidgets-utils.c
@@ -76,11 +76,20 @@ typedef struct
{
GList **blink_script;
const gchar *widget_identifier;
-} BlinkData;
+ const gchar *settings_value;
+} BlinkSearch;
+typedef struct
+{
+ GtkWidget *widget;
+ gchar *settings_value;
+} BlinkStep;
-static void gimp_search_widget_rec (GtkWidget *widget,
- BlinkData *data);
+static void gimp_widget_blink_after (GtkWidget *widget,
+ gint ms_timeout);
+static void gimp_search_widget_rec (GtkWidget *widget,
+ BlinkSearch *data);
+static void gimp_blink_free_script (GList *blink_scenario);
GtkWidget *
@@ -1404,6 +1413,28 @@ widget_blink_free (WidgetBlink *blink)
g_slice_free (WidgetBlink, blink);
}
+static gboolean
+gimp_widget_blink_start_timeout (GtkWidget *widget)
+{
+ WidgetBlink *blink;
+
+ blink = g_object_get_data (G_OBJECT (widget), "gimp-widget-blink");
+ if (blink)
+ {
+ blink->timeout_id = 0;
+ gimp_widget_blink (widget);
+ }
+ else
+ {
+ /* If the data is not here anymore, our blink has been canceled
+ * already. Also delete the script, if any.
+ */
+ g_object_set_data (G_OBJECT (widget), "gimp-widget-blink-script", NULL);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
static gboolean
gimp_widget_blink_timeout (GtkWidget *widget)
{
@@ -1416,7 +1447,75 @@ gimp_widget_blink_timeout (GtkWidget *widget)
gimp_highlight_widget (widget, blink->counter % 2 == 1, blink->rect);
blink->counter++;
- if (blink->counter == 3)
+ if (blink->counter == 1)
+ {
+ if (script)
+ {
+ BlinkStep *step = script->data;
+
+ if (step->settings_value)
+ {
+ const gchar *prop_name;
+ GObject *config;
+ GParamSpec *param_spec;
+
+ prop_name = g_object_get_data (G_OBJECT (widget),
+ "gimp-widget-property-name");
+ config = g_object_get_data (G_OBJECT (widget),
+ "gimp-widget-property-config");
+
+ if (config && G_IS_OBJECT (config) && prop_name)
+ {
+ param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
+ prop_name);
+ if (! param_spec)
+ {
+ g_printerr ("%s: %s has no property named '%s'.\n",
+ G_STRFUNC,
+ g_type_name (G_TYPE_FROM_INSTANCE (config)),
+ prop_name);
+ return G_SOURCE_CONTINUE;
+ }
+ if (! (param_spec->flags & G_PARAM_WRITABLE))
+ {
+ g_printerr ("%s: property '%s' of %s is not writable.\n",
+ G_STRFUNC,
+ param_spec->name,
+ g_type_name (param_spec->owner_type));
+ return G_SOURCE_CONTINUE;
+ }
+ if (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_ENUM) ||
+ g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_INT) ||
+ g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_BOOLEAN))
+ {
+ gchar *endptr;
+ gint64 enum_value;
+
+ enum_value = g_ascii_strtoll (step->settings_value, &endptr, 10);
+ if (enum_value == 0 && endptr == step->settings_value)
+ {
+ g_printerr ("%s: settings value '%s' cannot properly be converted to int.\n",
+ G_STRFUNC, step->settings_value);
+ return G_SOURCE_CONTINUE;
+ }
+
+ g_object_set (config,
+ prop_name, enum_value,
+ NULL);
+ }
+ else
+ {
+ g_printerr ("%s: currently unsupported type '%s' for property %s of %s.\n",
+ G_STRFUNC,
+ g_type_name (G_TYPE_FROM_INSTANCE (param_spec)),
+ param_spec->name,
+ g_type_name (param_spec->owner_type));
+ }
+ }
+ }
+ }
+ }
+ else if (blink->counter == 3)
{
blink->timeout_id = 0;
@@ -1424,14 +1523,19 @@ gimp_widget_blink_timeout (GtkWidget *widget)
if (script)
{
- GtkWidget *next_widget = script->data;
-
if (script->next)
- g_object_set_data_full (G_OBJECT (next_widget), "gimp-widget-blink-script",
- g_list_copy (script->next),
- (GDestroyNotify) g_list_free);
+ {
+ BlinkStep *next_step = script->next->data;
+ GtkWidget *next_widget = next_step->widget;
- gimp_widget_blink (next_widget);
+ g_object_set_data_full (G_OBJECT (next_widget), "gimp-widget-blink-script",
+ script->next,
+ (GDestroyNotify) gimp_blink_free_script);
+ script->next->prev = NULL;
+ script->next = NULL;
+
+ gimp_widget_blink_after (next_widget, 500);
+ }
g_object_set_data (G_OBJECT (widget), "gimp-widget-blink-script", NULL);
}
@@ -1467,25 +1571,42 @@ gimp_widget_blink (GtkWidget *widget)
}
void
-gimp_widget_script_blink (GtkWidget *widget,
- GList **blink_scenario)
+gimp_widget_script_blink (GtkWidget *widget,
+ const gchar *settings_value,
+ GList **blink_scenario)
{
- *blink_scenario = g_list_append (*blink_scenario, widget);
+ BlinkStep *step;
+
+ step = g_slice_new (BlinkStep);
+ step->widget = widget;
+ step->settings_value = g_strdup (settings_value);
+
+ *blink_scenario = g_list_append (*blink_scenario, step);
while ((widget = gtk_widget_get_parent (widget)))
gimp_widget_blink_cancel (widget);
}
+/* gimp_blink_play_script:
+ * @blink_scenario:
+ *
+ * This function will play the @blink_scenario and free the associated
+ * data once done.
+ */
void
gimp_blink_play_script (GList *blink_scenario)
{
+ BlinkStep *step;
+
g_return_if_fail (g_list_length (blink_scenario) > 0);
- g_object_set_data_full (G_OBJECT (blink_scenario->data),
+ step = blink_scenario->data;
+
+ g_object_set_data_full (G_OBJECT (step->widget),
"gimp-widget-blink-script",
- g_list_copy (blink_scenario->next),
- (GDestroyNotify) g_list_free);
- gimp_widget_blink (blink_scenario->data);
+ blink_scenario,
+ (GDestroyNotify) gimp_blink_free_script);
+ gimp_widget_blink (step->widget);
}
void
@@ -1565,7 +1686,7 @@ gimp_blink_toolbox (Gimp *gimp,
action = gimp_ui_manager_find_action (ui_manager, "tools", action_name);
gimp_action_activate (GIMP_ACTION (action));
}
- gimp_blink_dockable (gimp, "gimp-toolbox", action_name, blink_scenario);
+ gimp_blink_dockable (gimp, "gimp-toolbox", action_name, NULL, blink_scenario);
}
/**
@@ -1573,6 +1694,7 @@ gimp_blink_toolbox (Gimp *gimp,
* @gimp:
* @dockable_identifier:
* @widget_identifier:
+ * @settings_value:
* @blink_scenario:
*
* This function will raise the dockable identified by
@@ -1582,20 +1704,28 @@ gimp_blink_toolbox (Gimp *gimp,
* Then it will find the widget identified by @widget_identifier. Note
* that for propwidgets, this is usually the associated property name.
*
+ * If @settings_value is set, then it will try to change the widget
+ * value, depending the type of widgets. Note that for now, only
+ * property widgets of enum, int or boolean types can be set (so the
+ * @settings_value string must represent an int value).
+ *
* Finally it will either blink this widget immediately to raise
* attention, or add it to the @blink_scenario if not %NULL. The blink
* scenario must be explicitly started with gimp_blink_play_script()
- * when ready.
+ * when ready. @blink_scenario should be considered as opaque data, so
+ * you should not free it directly and let gimp_blink_play_script() do
+ * so for you.
*/
void
gimp_blink_dockable (Gimp *gimp,
const gchar *dockable_identifier,
const gchar *widget_identifier,
+ const gchar *settings_value,
GList **blink_scenario)
{
- GtkWidget *dockable;
- GdkMonitor *monitor;
- BlinkData *data;
+ GtkWidget *dockable;
+ GdkMonitor *monitor;
+ BlinkSearch *data;
g_return_if_fail (GIMP_IS_GIMP (gimp));
@@ -1613,13 +1743,14 @@ gimp_blink_dockable (Gimp *gimp,
if (widget_identifier)
{
- data = g_slice_new (BlinkData);
+ data = g_slice_new (BlinkSearch);
data->blink_script = blink_scenario;
data->widget_identifier = widget_identifier;
+ data->settings_value = settings_value;
gtk_container_foreach (GTK_CONTAINER (dockable),
(GtkCallback) gimp_search_widget_rec,
(gpointer) data);
- g_slice_free (BlinkData, data);
+ g_slice_free (BlinkSearch, data);
}
}
@@ -2135,40 +2266,75 @@ gimp_widget_flush_expose (void)
/* private functions */
static void
-gimp_search_widget_rec (GtkWidget *widget,
- BlinkData *data)
+gimp_widget_blink_after (GtkWidget *widget,
+ gint ms_timeout)
+{
+ WidgetBlink *blink;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ blink = widget_blink_new ();
+
+ g_object_set_data_full (G_OBJECT (widget), "gimp-widget-blink", blink,
+ (GDestroyNotify) widget_blink_free);
+
+ blink->timeout_id = g_timeout_add (ms_timeout,
+ (GSourceFunc) gimp_widget_blink_start_timeout,
+ widget);
+}
+
+static void
+gimp_search_widget_rec (GtkWidget *widget,
+ BlinkSearch *data)
{
- GList **blink_script = data->blink_script;
- const gchar *searched_id = data->widget_identifier;
+ GList **blink_script = data->blink_script;
+ const gchar *searched_id = data->widget_identifier;
+ const gchar *settings_value = data->settings_value;
+ const gchar *id;
- if (gtk_widget_is_visible (widget))
+ id = g_object_get_data (G_OBJECT (widget),
+ "gimp-widget-identifier");
+
+ if (id == NULL)
+ /* Using propwidgets identifiers as fallback. */
+ id = g_object_get_data (G_OBJECT (widget),
+ "gimp-widget-property-name");
+
+ if (id && g_strcmp0 (id, searched_id) == 0)
+ {
+ /* Giving focus to help scrolling the dockable so that the
+ * widget is visible. Note that it seems to work fine if the
+ * dockable was already present, not if it was just created.
+ *
+ * TODO: this should be fixed so that we always make the
+ * widget visible before blinking, otherwise it's a bit
+ * useless when this happens.
+ */
+ gtk_widget_grab_focus (widget);
+ if (blink_script)
+ gimp_widget_script_blink (widget, settings_value, blink_script);
+ else if (gtk_widget_is_visible (widget))
+ gimp_widget_blink (widget);
+ }
+ else if (GTK_IS_CONTAINER (widget))
{
- const gchar *id;
+ gtk_container_foreach (GTK_CONTAINER (widget),
+ (GtkCallback) gimp_search_widget_rec,
+ (gpointer) data);
+ }
+}
- id = g_object_get_data (G_OBJECT (widget),
- "gimp-widget-identifier");
+static void
+gimp_blink_free_script (GList *blink_scenario)
+{
+ GList *iter;
- if (id && g_strcmp0 (id, searched_id) == 0)
- {
- /* Giving focus to help scrolling the dockable so that the
- * widget is visible. Note that it seems to work fine if the
- * dockable was already present, not if it was just created.
- *
- * TODO: this should be fixed so that we always make the
- * widget visible before blinking, otherwise it's a bit
- * useless when this happens.
- */
- gtk_widget_grab_focus (widget);
- if (blink_script)
- gimp_widget_script_blink (widget, blink_script);
- else
- gimp_widget_blink (widget);
- }
- else if (GTK_IS_CONTAINER (widget))
- {
- gtk_container_foreach (GTK_CONTAINER (widget),
- (GtkCallback) gimp_search_widget_rec,
- (gpointer) data);
- }
+ for (iter = blink_scenario; iter; iter = iter->next)
+ {
+ BlinkStep *step = iter->data;
+
+ g_free (step->settings_value);
+ g_slice_free (BlinkStep, step);
}
+ g_list_free (blink_scenario);
}
diff --git a/app/widgets/gimpwidgets-utils.h b/app/widgets/gimpwidgets-utils.h
index f60cdb9551..c0b53f435e 100644
--- a/app/widgets/gimpwidgets-utils.h
+++ b/app/widgets/gimpwidgets-utils.h
@@ -100,9 +100,11 @@ void gimp_blink_toolbox (Gimp *gimp,
void gimp_blink_dockable (Gimp *gimp,
const gchar *dockable_identifier,
const gchar *widget_identifier,
+ const gchar *settings_value,
GList **blink_script);
void gimp_widget_script_blink (GtkWidget *widget,
+ const gchar *widget_identifier,
GList **blink_script);
void gimp_blink_play_script (GList *blink_script);
diff --git a/libgimpwidgets/gimppropwidgets.c b/libgimpwidgets/gimppropwidgets.c
index b353e1250b..d6469ae4d4 100644
--- a/libgimpwidgets/gimppropwidgets.c
+++ b/libgimpwidgets/gimppropwidgets.c
@@ -135,7 +135,7 @@ gimp_prop_check_button_new (GObject *config,
button, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (button, property_name);
+ gimp_widget_set_bound_property (button, config, property_name);
return button;
}
@@ -216,7 +216,7 @@ gimp_prop_enum_check_button_new (GObject *config,
gtk_widget_show (button);
- gimp_widget_set_identifier (button, property_name);
+ gimp_widget_set_bound_property (button, config, property_name);
return button;
}
@@ -365,7 +365,7 @@ gimp_prop_switch_new (GObject *config,
if (switch_out)
*switch_out = pswitch;
- gimp_widget_set_identifier (hbox, property_name);
+ gimp_widget_set_bound_property (hbox, config, property_name);
return hbox;
}
@@ -431,7 +431,7 @@ gimp_prop_int_combo_box_new (GObject *config,
combo_box, "value",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (combo_box, property_name);
+ gimp_widget_set_bound_property (combo_box, config, property_name);
return combo_box;
}
@@ -499,7 +499,7 @@ gimp_prop_pointer_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_pointer_combo_box_notify),
combo_box);
- gimp_widget_set_identifier (combo_box, property_name);
+ gimp_widget_set_bound_property (combo_box, config, property_name);
gtk_widget_show (combo_box);
@@ -591,7 +591,7 @@ gimp_prop_enum_combo_box_new (GObject *config,
gtk_widget_show (combo_box);
- gimp_widget_set_identifier (combo_box, property_name);
+ gimp_widget_set_bound_property (combo_box, config, property_name);
return combo_box;
}
@@ -751,7 +751,7 @@ gimp_prop_boolean_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_boolean_combo_box_notify),
combo);
- gimp_widget_set_identifier (combo, property_name);
+ gimp_widget_set_bound_property (combo, config, property_name);
gtk_widget_show (combo);
@@ -890,7 +890,7 @@ gimp_prop_enum_radio_frame_new (GObject *config,
gtk_widget_show (frame);
- gimp_widget_set_identifier (frame, property_name);
+ gimp_widget_set_bound_property (frame, config, property_name);
return frame;
}
@@ -962,7 +962,7 @@ gimp_prop_enum_radio_box_new (GObject *config,
g_object_set_data (G_OBJECT (vbox), "radio-button", button);
- gimp_widget_set_identifier (vbox, property_name);
+ gimp_widget_set_bound_property (vbox, config, property_name);
gtk_widget_show (vbox);
@@ -1012,7 +1012,7 @@ gimp_prop_int_radio_frame_new (GObject *config,
gtk_container_add (GTK_CONTAINER (frame), box);
gtk_widget_show (box);
- gimp_widget_set_identifier (frame, property_name);
+ gimp_widget_set_bound_property (frame, config, property_name);
gtk_widget_show (frame);
@@ -1102,7 +1102,7 @@ gimp_prop_int_radio_box_new (GObject *config,
g_object_set_data (G_OBJECT (vbox), "radio-button", button);
- gimp_widget_set_identifier (vbox, property_name);
+ gimp_widget_set_bound_property (vbox, config, property_name);
gtk_widget_show (vbox);
@@ -1156,7 +1156,7 @@ gimp_prop_enum_label_new (GObject *config,
G_CALLBACK (gimp_prop_enum_label_notify),
label);
- gimp_widget_set_identifier (label, property_name);
+ gimp_widget_set_bound_property (label, config, property_name);
gtk_widget_show (label);
@@ -1240,7 +1240,7 @@ gimp_prop_boolean_radio_frame_new (GObject *config,
g_object_set_data (G_OBJECT (frame), "radio-button", button);
- gimp_widget_set_identifier (frame, property_name);
+ gimp_widget_set_bound_property (frame, config, property_name);
gtk_widget_show (frame);
@@ -1317,7 +1317,7 @@ gimp_prop_enum_icon_box_new (GObject *config,
G_CALLBACK (gimp_prop_radio_button_notify),
button);
- gimp_widget_set_identifier (box, property_name);
+ gimp_widget_set_bound_property (box, config, property_name);
gtk_widget_show (box);
@@ -1432,7 +1432,7 @@ gimp_prop_spin_button_new (GObject *config,
"gimp-prop-adjustment-binding",
binding);
- gimp_widget_set_identifier (spinbutton, property_name);
+ gimp_widget_set_bound_property (spinbutton, config, property_name);
gtk_widget_show (spinbutton);
@@ -1481,7 +1481,7 @@ gimp_prop_label_spin_new (GObject *config,
widget, "value",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (widget, property_name);
+ gimp_widget_set_bound_property (widget, config, property_name);
return widget;
}
@@ -1559,7 +1559,7 @@ gimp_prop_spin_scale_new (GObject *config,
gtk_widget_show (spinscale);
- gimp_widget_set_identifier (spinscale, property_name);
+ gimp_widget_set_bound_property (spinscale, config, property_name);
return spinscale;
}
@@ -1756,7 +1756,7 @@ gimp_prop_hscale_new (GObject *config,
G_CALLBACK (gimp_prop_adjustment_notify),
adjustment);
- gimp_widget_set_identifier (scale, property_name);
+ gimp_widget_set_bound_property (scale, config, property_name);
gtk_widget_show (scale);
@@ -1867,7 +1867,7 @@ gimp_prop_scale_entry_new (GObject *config,
}
- gimp_widget_set_identifier (widget, property_name);
+ gimp_widget_set_bound_property (widget, config, property_name);
return widget;
}
@@ -2113,7 +2113,7 @@ gimp_prop_memsize_entry_new (GObject *config,
G_CALLBACK (gimp_prop_memsize_notify),
entry);
- gimp_widget_set_identifier (entry, property_name);
+ gimp_widget_set_bound_property (entry, config, property_name);
gtk_widget_show (entry);
@@ -2223,7 +2223,7 @@ gimp_prop_label_new (GObject *config,
g_object_bind_property (config, property_name,
label, "label", flags);
- gimp_widget_set_identifier (label, property_name);
+ gimp_widget_set_bound_property (label, config, property_name);
return label;
}
@@ -2294,7 +2294,7 @@ gimp_prop_entry_new (GObject *config,
G_CALLBACK (gimp_prop_entry_notify),
entry);
- gimp_widget_set_identifier (entry, property_name);
+ gimp_widget_set_bound_property (entry, config, property_name);
gtk_widget_show (entry);
@@ -2409,7 +2409,7 @@ gimp_prop_label_entry_new (GObject *config,
label_entry, "value",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (label_entry, property_name);
+ gimp_widget_set_bound_property (label_entry, config, property_name);
gtk_widget_show (label_entry);
@@ -2637,7 +2637,7 @@ gimp_prop_string_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_string_combo_box_notify),
combo_box);
- gimp_widget_set_identifier (combo_box, property_name);
+ gimp_widget_set_bound_property (combo_box, config, property_name);
gtk_widget_show (combo_box);
@@ -3013,7 +3013,7 @@ gimp_prop_path_editor_new (GObject *config,
editor);
}
- gimp_widget_set_identifier (editor, path_property_name);
+ gimp_widget_set_bound_property (editor, config, path_property_name);
gtk_widget_show (editor);
@@ -3324,7 +3324,7 @@ gimp_prop_size_entry_new (GObject *config,
entry);
}
- gimp_widget_set_identifier (entry, property_name);
+ gimp_widget_set_bound_property (entry, config, property_name);
gtk_widget_show (entry);
@@ -3562,7 +3562,7 @@ gimp_prop_coordinates_new (GObject *config,
return NULL;
}
- gimp_widget_set_identifier (entry, x_property_name);
+ gimp_widget_set_bound_property (entry, config, x_property_name);
gtk_widget_show (entry);
@@ -4019,7 +4019,7 @@ gimp_prop_color_area_new (GObject *config,
G_CALLBACK (gimp_prop_color_area_notify),
area);
- gimp_widget_set_identifier (area, property_name);
+ gimp_widget_set_bound_property (area, config, property_name);
gtk_widget_show (area);
@@ -4120,7 +4120,7 @@ gimp_prop_color_select_new (GObject *config,
button, "color",
G_BINDING_BIDIRECTIONAL);
- gimp_widget_set_identifier (button, property_name);
+ gimp_widget_set_bound_property (button, config, property_name);
gtk_widget_show (button);
@@ -4168,7 +4168,7 @@ gimp_prop_label_color_new (GObject *config,
prop_widget, "value",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- gimp_widget_set_identifier (prop_widget, property_name);
+ gimp_widget_set_bound_property (prop_widget, config, property_name);
gtk_widget_show (prop_widget);
@@ -4245,7 +4245,7 @@ gimp_prop_unit_combo_box_new (GObject *config,
G_CALLBACK (gimp_prop_unit_combo_box_notify),
combo);
- gimp_widget_set_identifier (combo, property_name);
+ gimp_widget_set_bound_property (combo, config, property_name);
gtk_widget_show (combo);
@@ -4357,7 +4357,7 @@ gimp_prop_icon_image_new (GObject *config,
image, "icon-name",
G_BINDING_BIDIRECTIONAL);
- gimp_widget_set_identifier (image, property_name);
+ gimp_widget_set_bound_property (image, config, property_name);
g_free (icon_name);
@@ -4429,7 +4429,7 @@ gimp_prop_expander_new (GObject *config,
G_CALLBACK (gimp_prop_expander_notify),
expander);
- gimp_widget_set_identifier (expander, property_name);
+ gimp_widget_set_bound_property (expander, config, property_name);
gtk_widget_show (expander);
diff --git a/libgimpwidgets/gimpwidgets-private.c b/libgimpwidgets/gimpwidgets-private.c
index 567779a95a..96dbf07b5f 100644
--- a/libgimpwidgets/gimpwidgets-private.c
+++ b/libgimpwidgets/gimpwidgets-private.c
@@ -205,6 +205,13 @@ gimp_widgets_init (GimpHelpFunc standard_help_func,
* as widget identifier. You can always use this function to override a
* given widget identifier with a more specific name.
*
+ * Note that when a widget is bound to a property, in other words when
+ * in one of our propwidgets API, you should rather use
+ * gimp_widget_set_bound_property() because it allows more easily to
+ * tweak values.
+ * gimp_widget_set_identifier() is more destined to random widgets which
+ * you just want to be able to blink.
+ *
* It's doesn't need to be in public API because it is only used for
* internal blinking ability in core GIMP GUI.
*/
@@ -220,6 +227,41 @@ gimp_widget_set_identifier (GtkWidget *widget,
(GDestroyNotify) g_free);
}
+/**
+ * gimp_widget_set_bound_property:
+ * @widget:
+ * @config:
+ * @property_name:
+ *
+ * This is similar to gimp_widget_set_identifier() because the
+ * property_name can be used as identifier by our blink API.
+ * You can still set explicitly (and additionally)
+ * gimp_widget_set_identifier() for rare cases where 2 widgets in a same
+ * container would bind the same property (or 2 properties named the
+ * same way for 2 different config objects). The identifier will be used
+ * in priority to the property name (which can still be used for
+ * changing the widget value, so it remains important to also set it).
+ *
+ * It's doesn't need to be in public API because it is only used for
+ * internal blinking ability in core GIMP GUI.
+ */
+void
+gimp_widget_set_bound_property (GtkWidget *widget,
+ GObject *config,
+ const gchar *property_name)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ g_object_set_data_full (G_OBJECT (widget),
+ "gimp-widget-property-name",
+ g_strdup (property_name),
+ (GDestroyNotify) g_free);
+ g_object_set_data_full (G_OBJECT (widget),
+ "gimp-widget-property-config",
+ g_object_ref (config),
+ (GDestroyNotify) g_object_unref);
+}
+
/* clean up babl (in particular, so that the fish cache is constructed) if the
* compiler supports destructors
*/
diff --git a/libgimpwidgets/gimpwidgets-private.h b/libgimpwidgets/gimpwidgets-private.h
index 62edfcff8d..dea6e8ccab 100644
--- a/libgimpwidgets/gimpwidgets-private.h
+++ b/libgimpwidgets/gimpwidgets-private.h
@@ -39,14 +39,17 @@ extern GimpEnsureModulesFunc _gimp_ensure_modules_func;
G_BEGIN_DECLS
-void gimp_widgets_init (GimpHelpFunc standard_help_func,
- GimpGetColorFunc get_foreground_func,
- GimpGetColorFunc get_background_func,
- GimpEnsureModulesFunc ensure_modules_func,
- const gchar *test_base_dir);
-
-void gimp_widget_set_identifier (GtkWidget *widget,
- const gchar *identifier);
+void gimp_widgets_init (GimpHelpFunc standard_help_func,
+ GimpGetColorFunc get_foreground_func,
+ GimpGetColorFunc get_background_func,
+ GimpEnsureModulesFunc ensure_modules_func,
+ const gchar *test_base_dir);
+
+void gimp_widget_set_identifier (GtkWidget *widget,
+ const gchar *identifier);
+void gimp_widget_set_bound_property (GtkWidget *widget,
+ GObject *config,
+ const gchar *property_name);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]