[gimp] app: make gimp_gegl_apply_cached_operation() cancelable via GimpProgress
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: make gimp_gegl_apply_cached_operation() cancelable via GimpProgress
- Date: Sun, 29 Jun 2014 22:16:50 +0000 (UTC)
commit 16381c9bf9ecfcd7d99b08672a38c1559a42eb52
Author: Michael Natterer <mitch gimp org>
Date: Mon Jun 30 00:10:25 2014 +0200
app: make gimp_gegl_apply_cached_operation() cancelable via GimpProgress
In gimp_drawable_merge_filter(), use that feature to make filter
applying cancelable. Stop projection rendering first, because we have
to run the event loop manually in order to receive input for
canceling, but we don't want the projection to be constructed from
that manual loop running.
app/core/gimpdrawable-filter.c | 75 +++++++++++++++++++++++----------
app/gegl/gimp-gegl-apply-operation.c | 63 ++++++++++++++++++++++------
app/gegl/gimp-gegl-apply-operation.h | 33 ++++++++-------
3 files changed, 118 insertions(+), 53 deletions(-)
---
diff --git a/app/core/gimpdrawable-filter.c b/app/core/gimpdrawable-filter.c
index 82a091e..4e1a0a6 100644
--- a/app/core/gimpdrawable-filter.c
+++ b/app/core/gimpdrawable-filter.c
@@ -33,8 +33,10 @@
#include "gimpdrawableundo.h"
#include "gimpfilter.h"
#include "gimpfilterstack.h"
+#include "gimpimage.h"
#include "gimpimage-undo.h"
#include "gimpprogress.h"
+#include "gimpprojection.h"
GimpContainer *
@@ -96,33 +98,27 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
&rect.x, &rect.y,
&rect.width, &rect.height))
{
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
+ GeglBuffer *undo_buffer;
GimpApplicator *applicator;
GeglBuffer *cache = NULL;
GeglRectangle *rects = NULL;
gint n_rects = 0;
- gimp_drawable_push_undo (drawable, undo_desc, NULL,
- rect.x, rect.y,
- rect.width, rect.height);
+ undo_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ rect.width, rect.height),
+ gimp_drawable_get_format (drawable));
+
+ gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (rect.x, rect.y,
+ rect.width, rect.height),
+ undo_buffer,
+ GEGL_RECTANGLE (0, 0, 0, 0));
applicator = gimp_filter_get_applicator (filter);
if (applicator)
{
- GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
- GimpDrawableUndo *undo;
-
- undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
-
- if (undo)
- {
- undo->paint_mode = applicator->paint_mode;
- undo->opacity = applicator->opacity;
-
- undo->applied_buffer =
- gimp_applicator_dup_apply_buffer (applicator, &rect);
- }
-
cache = gimp_applicator_get_cache_buffer (applicator,
&rects, &n_rects);
@@ -137,12 +133,45 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
}
}
- gimp_gegl_apply_cached_operation (gimp_drawable_get_buffer (drawable),
- progress, undo_desc,
- gimp_filter_get_node (filter),
- gimp_drawable_get_buffer (drawable),
- &rect,
- cache, rects, n_rects);
+ gimp_projection_stop_rendering (gimp_image_get_projection (image));
+
+ if (gimp_gegl_apply_cached_operation (gimp_drawable_get_buffer (drawable),
+ progress, undo_desc,
+ gimp_filter_get_node (filter),
+ gimp_drawable_get_buffer (drawable),
+ &rect,
+ cache, rects, n_rects,
+ TRUE))
+ {
+ gimp_drawable_push_undo (drawable, undo_desc, undo_buffer,
+ rect.x, rect.y,
+ rect.width, rect.height);
+
+ if (applicator)
+ {
+ GimpDrawableUndo *undo;
+
+ undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
+
+ if (undo)
+ {
+ undo->paint_mode = applicator->paint_mode;
+ undo->opacity = applicator->opacity;
+
+ undo->applied_buffer =
+ gimp_applicator_dup_apply_buffer (applicator, &rect);
+ }
+ }
+ }
+ else
+ {
+ gegl_buffer_copy (undo_buffer,
+ GEGL_RECTANGLE (0, 0, rect.width, rect.height),
+ gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (rect.x, rect.y, 0, 0));
+ }
+
+ g_object_unref (undo_buffer);
if (cache)
{
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index b31326a..310f464 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -48,10 +48,18 @@ gimp_gegl_apply_operation (GeglBuffer *src_buffer,
operation,
dest_buffer,
dest_rect,
- NULL, NULL, 0);
+ NULL, NULL, 0,
+ FALSE);
}
-void
+static void
+gimp_gegl_apply_operation_cancel (GimpProgress *progress,
+ gboolean *cancel)
+{
+ *cancel = TRUE;
+}
+
+gboolean
gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
GimpProgress *progress,
const gchar *undo_desc,
@@ -60,14 +68,16 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
const GeglRectangle *dest_rect,
GeglBuffer *cache,
const GeglRectangle *valid_rects,
- gint n_valid_rects)
+ gint n_valid_rects,
+ gboolean cancelable)
{
GeglNode *gegl;
GeglNode *dest_node;
GeglRectangle rect = { 0, };
- GeglProcessor *processor = NULL;
- gboolean progress_active = FALSE;
+ GeglProcessor *processor = NULL;
+ gboolean progress_started = FALSE;
gdouble value;
+ gboolean cancel = FALSE;
g_return_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
@@ -127,16 +137,24 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
{
processor = gegl_node_new_processor (dest_node, &rect);
- progress_active = gimp_progress_is_active (progress);
-
- if (progress_active)
+ if (gimp_progress_is_active (progress))
{
if (undo_desc)
gimp_progress_set_text (progress, undo_desc);
+
+ progress_started = FALSE;
+ cancelable = FALSE;
}
else
{
- gimp_progress_start (progress, undo_desc, FALSE);
+ gimp_progress_start (progress, undo_desc, cancelable);
+
+ if (cancelable)
+ g_signal_connect (progress, "cancel",
+ G_CALLBACK (gimp_gegl_apply_operation_cancel),
+ &cancel);
+
+ progress_started = TRUE;
}
}
@@ -171,7 +189,7 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
n_rects = cairo_region_num_rectangles (region);
- for (i = 0; i < n_rects; i++)
+ for (i = 0; ! cancel && (i < n_rects); i++)
{
cairo_rectangle_int_t render_rect;
@@ -190,12 +208,16 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
(GeglRectangle *) &render_rect);
#endif
- while (gegl_processor_work (processor, &value))
+ while (! cancel && gegl_processor_work (processor, &value))
{
gimp_progress_set_value (progress,
((gdouble) done_pixels +
value * rect_pixels) /
(gdouble) all_pixels);
+
+ if (cancelable)
+ while (! cancel && g_main_context_pending (NULL))
+ g_main_context_iteration (NULL, FALSE);
}
done_pixels += rect_pixels;
@@ -213,9 +235,13 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
{
if (progress)
{
- while (gegl_processor_work (processor, &value))
+ while (! cancel && gegl_processor_work (processor, &value))
{
gimp_progress_set_value (progress, value);
+
+ if (cancelable)
+ while (! cancel && g_main_context_pending (NULL))
+ g_main_context_iteration (NULL, FALSE);
}
}
else
@@ -230,8 +256,17 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
g_object_unref (gegl);
- if (progress && ! progress_active)
- gimp_progress_end (progress);
+ if (progress_started)
+ {
+ gimp_progress_end (progress);
+
+ if (cancelable)
+ g_signal_handlers_disconnect_by_func (progress,
+ gimp_gegl_apply_operation_cancel,
+ &cancel);
+ }
+
+ return ! cancel;
}
void
diff --git a/app/gegl/gimp-gegl-apply-operation.h b/app/gegl/gimp-gegl-apply-operation.h
index b67e9c6..fa29068 100644
--- a/app/gegl/gimp-gegl-apply-operation.h
+++ b/app/gegl/gimp-gegl-apply-operation.h
@@ -26,22 +26,23 @@
/* generic functions, also used by the specific ones below */
-void gimp_gegl_apply_operation (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglNode *operation,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect);
-
-void gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglNode *operation,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- GeglBuffer *cache,
- const GeglRectangle *valid_rects,
- gint n_valid_rects);
+void gimp_gegl_apply_operation (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglNode *operation,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect);
+
+gboolean gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglNode *operation,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ GeglBuffer *cache,
+ const GeglRectangle *valid_rects,
+ gint n_valid_rects,
+ gboolean cancelable);
/* apply specific operations */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]