From bbd79f9d62a5b4ce1066358b2077742113d09e18 Mon Sep 17 00:00:00 2001 From: Ell Date: Sat, 31 Mar 2018 21:26:01 -0400 Subject: [PATCH] app: fix Wilber's eyes Commit fd6d4931c8184825d642bfebe69d045ce36f89e7 accidentally introduced a bug that caused Wilber's eyes to misbehave. This commit is an attempt to fix this issue. Unfortunately, it seems like the bug can still be triggered through a certain sequence of actions... --- app/tools/tool_manager.c | 65 ++++++++++++++++++++++++++++++++++ app/widgets/gimpcairo-wilber.c | 34 +++++++++++++++++- app/widgets/gimpcairo-wilber.h | 25 +++++++------ 3 files changed, 112 insertions(+), 12 deletions(-) diff --git a/app/tools/tool_manager.c b/app/tools/tool_manager.c index ccc1560cbf..8fcf258712 100644 --- a/app/tools/tool_manager.c +++ b/app/tools/tool_manager.c @@ -39,6 +39,8 @@ #include "display/gimpdisplay.h" +#include "widgets/gimpcairo-wilber.h" + #include "gimptool.h" #include "gimptoolcontrol.h" #include "tool_manager.h" @@ -81,6 +83,8 @@ static void tool_manager_disconnect_options (GimpToolManager *tool_manager, GimpContext *user_context, GimpToolInfo *tool_info); +static void tool_manager_cast_spell (GimpToolInfo *tool_info); + /* public functions */ @@ -714,6 +718,9 @@ tool_manager_tool_changed (GimpContext *user_context, tool_manager_select_tool (user_context->gimp, new_tool); g_object_unref (new_tool); + + /* ??? */ + tool_manager_cast_spell (tool_info); } static void @@ -872,3 +879,61 @@ tool_manager_disconnect_options (GimpToolManager *tool_manager, gimp_context_set_parent (GIMP_CONTEXT (tool_info->tool_options), NULL); } } + +static void +tool_manager_cast_spell (GimpToolInfo *tool_info) +{ + typedef struct + { + const gchar *sequence; + GCallback func; + } Spell; + + static const Spell spells[] = + { + { .sequence = "gimp-warp-tool\0" + "gimp-iscissors-tool\0" + "gimp-blend-tool\0" + "gimp-vector-tool\0" + "gimp-ellipse-select-tool\0" + "gimp-rect-select-tool\0", + .func = gimp_cairo_wilber_toggle_pointer_eyes + } + }; + + static const gchar *spell_progress[G_N_ELEMENTS (spells)]; + const gchar *tool_name; + gint i; + + tool_name = gimp_object_get_name (GIMP_OBJECT (tool_info)); + + for (i = 0; i < G_N_ELEMENTS (spells); i++) + { + if (! spell_progress[i]) + spell_progress[i] = spells[i].sequence; + + while (spell_progress[i]) + { + if (! strcmp (tool_name, spell_progress[i])) + { + spell_progress[i] += strlen (spell_progress[i]) + 1; + + if (! *spell_progress[i]) + { + spell_progress[i] = NULL; + + spells[i].func (); + } + + break; + } + else + { + if (spell_progress[i] == spells[i].sequence) + spell_progress[i] = NULL; + else + spell_progress[i] = spells[i].sequence; + } + } + } +} diff --git a/app/widgets/gimpcairo-wilber.c b/app/widgets/gimpcairo-wilber.c index 30fcf7eed5..74d8b0957f 100644 --- a/app/widgets/gimpcairo-wilber.c +++ b/app/widgets/gimpcairo-wilber.c @@ -48,9 +48,26 @@ static void gimp_cairo_eyes (GtkWidget *widget, gdouble max_eye_angle); -static gboolean pointer_eyes = TRUE; +static gboolean pointer_eyes = FALSE; +static GSList *cairo_wilber_widgets = NULL; +void +gimp_cairo_wilber_toggle_pointer_eyes (void) +{ + GSList *iter; + + pointer_eyes = ! pointer_eyes; + + for (iter = cairo_wilber_widgets; iter; iter = g_slist_next (iter)) + { + if (pointer_eyes) + g_object_set_data (G_OBJECT (iter->data), "wilber-eyes-state", NULL); + + gtk_widget_queue_draw (GTK_WIDGET (iter->data)); + } +} + void gimp_cairo_draw_toolbox_wilber (GtkWidget *widget, cairo_t *cr) @@ -206,6 +223,13 @@ gimp_cairo_wilber (cairo_t *cr, gimp_cairo_wilber_internal (NULL, cr, x, y, 1.0, 0.0); } +static void +gimp_cairo_wilber_weak_notify (gpointer data, + GObject *widget) +{ + cairo_wilber_widgets = g_slist_remove (cairo_wilber_widgets, widget); +} + static void gimp_cairo_wilber_internal (GtkWidget *widget, cairo_t *cr, @@ -224,6 +248,14 @@ gimp_cairo_wilber_internal (GtkWidget *widget, cairo_restore (cr); gimp_cairo_eyes (widget, cr, x, y, factor, max_eye_angle); + + if (widget && ! g_slist_find (cairo_wilber_widgets, widget)) + { + cairo_wilber_widgets = g_slist_prepend (cairo_wilber_widgets, widget); + + g_object_weak_ref (G_OBJECT (widget), + gimp_cairo_wilber_weak_notify, NULL); + } } typedef struct diff --git a/app/widgets/gimpcairo-wilber.h b/app/widgets/gimpcairo-wilber.h index 72dd5923f9..f4804e1823 100644 --- a/app/widgets/gimpcairo-wilber.h +++ b/app/widgets/gimpcairo-wilber.h @@ -25,18 +25,21 @@ #define __GIMP_CAIRO_WILBER_H__ -void gimp_cairo_draw_toolbox_wilber (GtkWidget *widget, - cairo_t *cr); -void gimp_cairo_draw_drop_wilber (GtkWidget *widget, - cairo_t *cr, - gboolean blink); +void gimp_cairo_wilber_toggle_pointer_eyes (void); -void gimp_cairo_wilber (cairo_t *cr, - gdouble x, - gdouble y); -void gimp_cairo_wilber_get_size (cairo_t *cr, - gdouble *width, - gdouble *height); + +void gimp_cairo_draw_toolbox_wilber (GtkWidget *widget, + cairo_t *cr); +void gimp_cairo_draw_drop_wilber (GtkWidget *widget, + cairo_t *cr, + gboolean blink); + +void gimp_cairo_wilber (cairo_t *cr, + gdouble x, + gdouble y); +void gimp_cairo_wilber_get_size (cairo_t *cr, + gdouble *width, + gdouble *height); #endif /* __GIMP_CAIRO_WILBER_H__ */