diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index 262d67ea5c..8b93c4eaac 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -68,6 +68,7 @@ enum { UPDATE, + PAINTED, ALPHA_CHANGED, LAST_SIGNAL }; @@ -220,6 +221,16 @@ gimp_drawable_class_init (GimpDrawableClass *klass) GimpFilterClass *filter_class = GIMP_FILTER_CLASS (klass); GimpItemClass *item_class = GIMP_ITEM_CLASS (klass); + /** + * GimpDrawable::update: + * @drawable: the object which received the signal. + * @x: + * @y: + * @width: + * @height: + * + * This signal is emitted when a region of the drawable is updated. + **/ gimp_drawable_signals[UPDATE] = g_signal_new ("update", G_TYPE_FROM_CLASS (klass), @@ -233,6 +244,24 @@ gimp_drawable_class_init (GimpDrawableClass *klass) G_TYPE_INT, G_TYPE_INT); + /** + * GimpDrawable::painted: + * @drawable: the object which received the signal. + * + * This signal is emitted when the drawable has been painted. Unlike + * the "update" signal, it will be emitted once for a single paint + * event (whereas several "update" signals could be emitted + * sequentially for various regions of the drawable). + **/ + gimp_drawable_signals[PAINTED] = + g_signal_new ("painted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpDrawableClass, painted), + NULL, NULL, + gimp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gimp_drawable_signals[ALPHA_CHANGED] = g_signal_new ("alpha-changed", G_TYPE_FROM_CLASS (klass), @@ -1018,6 +1047,7 @@ gimp_drawable_update (GimpDrawable *drawable, { g_signal_emit (drawable, gimp_drawable_signals[UPDATE], 0, x, y, width, height); + g_signal_emit (drawable, gimp_drawable_signals[PAINTED], 0); } else { diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h index a36f001c17..0239ab0880 100644 --- a/app/core/gimpdrawable.h +++ b/app/core/gimpdrawable.h @@ -50,6 +50,7 @@ struct _GimpDrawableClass gint y, gint width, gint height); + void (* painted) (GimpDrawable *drawable); void (* alpha_changed) (GimpDrawable *drawable); /* virtual functions */ diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c index b7b2c26a3d..9d9765e3bb 100644 --- a/app/core/gimpprojection.c +++ b/app/core/gimpprojection.c @@ -81,6 +81,7 @@ static gdouble GIMP_PROJECTION_CHUNK_TIME = 0.0666; enum { UPDATE, + RENDERED, LAST_SIGNAL }; @@ -258,6 +259,15 @@ gimp_projection_class_init (GimpProjectionClass *klass) G_TYPE_INT, G_TYPE_INT); + projection_signals[RENDERED] = + g_signal_new ("rendered", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GimpProjectionClass, rendered), + NULL, NULL, + gimp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + object_class->finalize = gimp_projection_finalize; object_class->set_property = gimp_projection_set_property; object_class->get_property = gimp_projection_get_property; @@ -842,6 +852,7 @@ gimp_projection_chunk_render_stop (GimpProjection *proj) g_source_remove (proj->priv->chunk_render.idle_id); proj->priv->chunk_render.idle_id = 0; + g_signal_emit (proj, projection_signals[RENDERED], 0); } static gboolean diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h index 8c9baf69e6..36d76d076c 100644 --- a/app/core/gimpprojection.h +++ b/app/core/gimpprojection.h @@ -44,12 +44,13 @@ struct _GimpProjectionClass { GimpObjectClass parent_class; - void (* update) (GimpProjection *proj, - gboolean now, - gint x, - gint y, - gint width, - gint height); + void (* update) (GimpProjection *proj, + gboolean now, + gint x, + gint y, + gint width, + gint height); + void (* rendered) (GimpProjection *proj); }; diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c index 60d05accf0..a4f6639e53 100644 --- a/app/tools/gimpbucketfilltool.c +++ b/app/tools/gimpbucketfilltool.c @@ -138,11 +138,9 @@ static void gimp_bucket_fill_tool_image_changed (GimpContext *c GimpBucketFillTool *tool); static void gimp_bucket_fill_tool_drawable_changed (GimpImage *image, GimpBucketFillTool *tool); -static void gimp_bucket_fill_tool_drawable_update (GimpDrawable *drawable, - gint x, - gint y, - gint width, - gint height, +static void gimp_bucket_fill_tool_projection_rendered (GimpProjection *proj, + GimpBucketFillTool *tool); +static void gimp_bucket_fill_tool_drawable_painted (GimpDrawable *drawable, GimpBucketFillTool *tool); @@ -240,6 +238,8 @@ gimp_bucket_fill_tool_finalize (GObject *object) if (image) { g_signal_handlers_disconnect_by_data (image, tool); + g_signal_handlers_disconnect_by_data (gimp_image_get_projection (image), + tool); g_object_unref (image); } if (drawable) @@ -406,10 +406,14 @@ gimp_bucket_fill_tool_preview (GimpBucketFillTool *tool, static void gimp_bucket_fill_tool_commit (GimpBucketFillTool *tool) { - tool->priv->fill_in_progress = FALSE; - if (tool->priv->filter) { + GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); + + /* Make sure the drawable will signal being painted. */ + if (! options->sample_merged) + tool->priv->fill_in_progress = FALSE; + gimp_drawable_filter_commit (tool->priv->filter, GIMP_PROGRESS (tool), FALSE); gimp_image_flush (gimp_display_get_image (GIMP_TOOL (tool)->display)); @@ -849,7 +853,11 @@ gimp_bucket_fill_tool_image_changed (GimpContext *context, g_clear_object (&tool->priv->line_art); if (prev_image) - g_signal_handlers_disconnect_by_data (prev_image, tool); + { + g_signal_handlers_disconnect_by_data (prev_image, tool); + g_signal_handlers_disconnect_by_data (gimp_image_get_projection (prev_image), + tool); + } if (prev_drawable) { g_signal_handlers_disconnect_by_data (prev_drawable, tool); @@ -866,6 +874,9 @@ gimp_bucket_fill_tool_image_changed (GimpContext *context, g_signal_connect (image, "active-channel-changed", G_CALLBACK (gimp_bucket_fill_tool_drawable_changed), tool); + g_signal_connect (gimp_image_get_projection (image), "rendered", + G_CALLBACK (gimp_bucket_fill_tool_projection_rendered), + tool); gimp_bucket_fill_tool_drawable_changed (image, tool); } } @@ -887,8 +898,8 @@ gimp_bucket_fill_tool_drawable_changed (GimpImage *image, g_weak_ref_set (&tool->priv->cached_drawable, drawable ? drawable : NULL); if (drawable) - g_signal_connect (drawable, "update", - G_CALLBACK (gimp_bucket_fill_tool_drawable_update), + g_signal_connect (drawable, "painted", + G_CALLBACK (gimp_bucket_fill_tool_drawable_painted), tool); gimp_bucket_fill_compute_line_art (tool); @@ -898,12 +909,21 @@ gimp_bucket_fill_tool_drawable_changed (GimpImage *image, } static void -gimp_bucket_fill_tool_drawable_update (GimpDrawable *drawable, - gint x, - gint y, - gint width, - gint height, - GimpBucketFillTool *tool) +gimp_bucket_fill_tool_projection_rendered (GimpProjection *proj, + GimpBucketFillTool *tool) { - gimp_bucket_fill_compute_line_art (tool); + GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); + + if (options->sample_merged) + gimp_bucket_fill_compute_line_art (tool); +} + +static void +gimp_bucket_fill_tool_drawable_painted (GimpDrawable *drawable, + GimpBucketFillTool *tool) +{ + GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); + + if (! options->sample_merged) + gimp_bucket_fill_compute_line_art (tool); }