diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c index 3da4e79ddf..a664b8be86 100644 --- a/app/core/gimpdrawablefilter.c +++ b/app/core/gimpdrawablefilter.c @@ -43,6 +43,7 @@ #include "gimpchannel.h" #include "gimpdrawable-filters.h" #include "gimpdrawablefilter.h" +#include "gimpfilterstack.h" #include "gimpimage.h" #include "gimplayer.h" #include "gimpprogress.h" @@ -1021,14 +1022,28 @@ gimp_drawable_filter_sync_region (GimpDrawableFilter *filter) { if (filter->has_input) { + GeglRectangle rect; + GimpContainer *filters; + + rect.x = filter->filter_area.x; + rect.y = filter->filter_area.y; + rect.width = filter->filter_area.width; + rect.height = filter->filter_area.height; + + filters = gimp_drawable_get_filters (filter->drawable); + gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters), + &rect); + gegl_node_set (filter->translate, "x", (gdouble) -filter->filter_area.x, "y", (gdouble) -filter->filter_area.y, NULL); gegl_node_set (filter->crop_before, - "width", (gdouble) filter->filter_area.width, - "height", (gdouble) filter->filter_area.height, + "x", (gdouble) rect.x, + "y", (gdouble) rect.y, + "width", (gdouble) rect.width, + "height", (gdouble) rect.height, NULL); } @@ -1061,14 +1076,23 @@ gimp_drawable_filter_sync_region (GimpDrawableFilter *filter) if (filter->has_input) { + GeglRectangle rect = { 0, 0, width, height }; + GimpContainer *filters; + + filters = gimp_drawable_get_filters (filter->drawable); + gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters), + &rect); + gegl_node_set (filter->translate, "x", (gdouble) 0.0, "y", (gdouble) 0.0, NULL); gegl_node_set (filter->crop_before, - "width", width, - "height", height, + "x", (gdouble) rect.x, + "y", (gdouble) rect.y, + "width", (gdouble) rect.width, + "height", (gdouble) rect.height, NULL); } diff --git a/app/core/gimpfilterstack.c b/app/core/gimpfilterstack.c index d470918ea0..f8f78a0400 100644 --- a/app/core/gimpfilterstack.c +++ b/app/core/gimpfilterstack.c @@ -25,6 +25,7 @@ #include "core-types.h" +#include "gimpdrawablefilter.h" #include "gimpfilter.h" #include "gimpfilterstack.h" @@ -223,6 +224,39 @@ gimp_filter_stack_get_graph (GimpFilterStack *stack) return stack->graph; } +void +gimp_filter_stack_get_bounding_box (GimpFilterStack *stack, + GeglRectangle *rect) +{ + GList *list; + GeglRectangle current_rect; + + g_return_if_fail (GIMP_IS_FILTER_STACK (stack)); + + for (list = GIMP_LIST (stack)->queue->tail; + list; list = g_list_previous (list)) + { + if (GIMP_IS_DRAWABLE_FILTER (list->data)) + { + GimpFilter *filter = GIMP_FILTER (list->data); + + current_rect = gegl_node_get_bounding_box (gimp_filter_get_node (filter)); + + if (rect->x > current_rect.x) + rect->x = current_rect.x; + + if (rect->y > current_rect.y) + rect->y = current_rect.y; + + if (rect->width < (current_rect.width - current_rect.x)) + rect->width = (current_rect.width - current_rect.x); + + if (rect->height < (current_rect.height - current_rect.y)) + rect->height = (current_rect.height - current_rect.y); + } + } +} + /* private functions */ diff --git a/app/core/gimpfilterstack.h b/app/core/gimpfilterstack.h index 3567f06e4f..92dce467c9 100644 --- a/app/core/gimpfilterstack.h +++ b/app/core/gimpfilterstack.h @@ -46,10 +46,11 @@ struct _GimpFilterStackClass }; -GType gimp_filter_stack_get_type (void) G_GNUC_CONST; -GimpContainer * gimp_filter_stack_new (GType filter_type); - -GeglNode * gimp_filter_stack_get_graph (GimpFilterStack *stack); +GType gimp_filter_stack_get_type (void) G_GNUC_CONST; +GimpContainer * gimp_filter_stack_new (GType filter_type); +GeglNode * gimp_filter_stack_get_graph (GimpFilterStack *stack); +void gimp_filter_stack_get_bounding_box (GimpFilterStack *stack, + GeglRectangle *rect); #endif /* __GIMP_FILTER_STACK_H__ */ diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 8bd6e281c6..3629e76f62 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -45,6 +45,7 @@ #include "core/gimpdrawable-filters.h" #include "core/gimpdrawablefilter.h" #include "core/gimpdrawablefilterundo.h" +#include "core/gimpfilterstack.h" #include "core/gimpimage.h" #include "core/gimpimage-undo.h" #include "core/gimpimage-undo-push.h" @@ -2683,7 +2684,8 @@ static void gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget, GimpItemTreeView *view) { - GimpImage *image = view->priv->image; + GimpImage *image = view->priv->image; + GimpDrawable *drawable = NULL; if (! view->priv->effects_filter || ! GIMP_IS_DRAWABLE_FILTER (view->priv->effects_filter)) @@ -2696,12 +2698,13 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget, return; } - if (view->priv->effects_drawable) + drawable = gimp_drawable_filter_get_drawable (view->priv->effects_filter); + if (drawable) { GimpContainer *filters; gint index; - filters = gimp_drawable_get_filters (GIMP_DRAWABLE (view->priv->effects_drawable)); + filters = gimp_drawable_get_filters (drawable); index = gimp_container_get_child_index (filters, GIMP_OBJECT (view->priv->effects_filter)); @@ -2709,8 +2712,11 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget, if (index >= 0) { + GimpChannel *mask = NULL; + GeglRectangle rect; + gimp_image_undo_push_filter_reorder (image, _("Reorder filter"), - view->priv->effects_drawable, + drawable, view->priv->effects_filter); gimp_container_reorder (filters, GIMP_OBJECT (view->priv->effects_filter), @@ -2723,10 +2729,18 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget, gtk_widget_set_sensitive (view->priv->effects_raise_button, FALSE); } + mask = gimp_drawable_filter_get_mask (view->priv->effects_filter); + gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters), + &rect); + + if (gimp_channel_is_empty (mask)) + gimp_drawable_filter_refresh_crop (view->priv->effects_filter, + &rect); + /* Hack to make the effects visibly change */ - gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), FALSE, FALSE); + gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE); gimp_image_flush (image); - gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), TRUE, FALSE); + gimp_item_set_visible (GIMP_ITEM (drawable), TRUE, FALSE); gimp_image_flush (image); } } @@ -2736,7 +2750,8 @@ static void gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget, GimpItemTreeView *view) { - GimpImage *image = view->priv->image; + GimpImage *image = view->priv->image; + GimpDrawable *drawable = NULL; if (! view->priv->effects_filter || ! GIMP_IS_DRAWABLE_FILTER (view->priv->effects_filter)) @@ -2749,12 +2764,13 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget, return; } - if (view->priv->effects_drawable) + drawable = gimp_drawable_filter_get_drawable (view->priv->effects_filter); + if (drawable) { GimpContainer *filters; gint index; - filters = gimp_drawable_get_filters (GIMP_DRAWABLE (view->priv->effects_drawable)); + filters = gimp_drawable_get_filters (drawable); index = gimp_container_get_child_index (filters, GIMP_OBJECT (view->priv->effects_filter)); @@ -2762,8 +2778,12 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget, if (index < gimp_container_get_n_children (filters)) { + GimpDrawableFilter *moved_filter = NULL; + GimpChannel *mask = NULL; + GeglRectangle rect; + gimp_image_undo_push_filter_reorder (image, _("Reorder filter"), - view->priv->effects_drawable, + drawable, view->priv->effects_filter); gimp_container_reorder (filters, GIMP_OBJECT (view->priv->effects_filter), @@ -2776,10 +2796,21 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget, gtk_widget_set_sensitive (view->priv->effects_lower_button, FALSE); } + moved_filter = (GimpDrawableFilter *) + gimp_container_get_child_by_index (filters, index - 1); + + mask = gimp_drawable_filter_get_mask (moved_filter); + gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters), + &rect); + + if (gimp_channel_is_empty (mask)) + gimp_drawable_filter_refresh_crop (moved_filter, &rect); + + /* Hack to make the effects visibly change */ - gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), FALSE, FALSE); + gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE); gimp_image_flush (image); - gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), TRUE, FALSE); + gimp_item_set_visible (GIMP_ITEM (drawable), TRUE, FALSE); gimp_image_flush (image); } }