mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-04 01:43:24 +00:00
Merge branch 'wip/estecka/filter_undo_visibility' into 'master'
core,widgets: Undo actions for filter visibility. See merge request GNOME/gimp!2290
This commit is contained in:
commit
f0460816c9
9 changed files with 185 additions and 6 deletions
|
@ -1229,6 +1229,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_GROUP_PARASITE_ATTACH, "GIMP_UNDO_GROUP_PARASITE_ATTACH", "group-parasite-attach" },
|
||||
{ GIMP_UNDO_GROUP_PARASITE_REMOVE, "GIMP_UNDO_GROUP_PARASITE_REMOVE", "group-parasite-remove" },
|
||||
{ GIMP_UNDO_GROUP_PATHS_IMPORT, "GIMP_UNDO_GROUP_PATHS_IMPORT", "group-paths-import" },
|
||||
{ GIMP_UNDO_GROUP_FILTER_VISIBILITY, "GIMP_UNDO_GROUP_FILTER_VISIBILITY", "group-filter-visibility" },
|
||||
{ GIMP_UNDO_GROUP_MISC, "GIMP_UNDO_GROUP_MISC", "group-misc" },
|
||||
{ GIMP_UNDO_IMAGE_TYPE, "GIMP_UNDO_IMAGE_TYPE", "image-type" },
|
||||
{ GIMP_UNDO_IMAGE_PRECISION, "GIMP_UNDO_IMAGE_PRECISION", "image-precision" },
|
||||
|
@ -1288,6 +1289,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_FILTER_REMOVE, "GIMP_UNDO_FILTER_REMOVE", "filter-remove" },
|
||||
{ GIMP_UNDO_FILTER_REORDER, "GIMP_UNDO_FILTER_REORDER", "filter-reorder" },
|
||||
{ GIMP_UNDO_FILTER_MODIFIED, "GIMP_UNDO_FILTER_MODIFIED", "filter-modified" },
|
||||
{ GIMP_UNDO_FILTER_VISIBILITY, "GIMP_UNDO_FILTER_VISIBILITY", "filter-visibility" },
|
||||
{ GIMP_UNDO_CANT, "GIMP_UNDO_CANT", "cant" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
@ -1342,6 +1344,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_GROUP_PARASITE_ATTACH, NC_("undo-type", "Attach parasite"), NULL },
|
||||
{ GIMP_UNDO_GROUP_PARASITE_REMOVE, NC_("undo-type", "Remove parasite"), NULL },
|
||||
{ GIMP_UNDO_GROUP_PATHS_IMPORT, NC_("undo-type", "Import paths"), NULL },
|
||||
{ GIMP_UNDO_GROUP_FILTER_VISIBILITY, NC_("undo-type", "Effects visibility"), NULL },
|
||||
{ GIMP_UNDO_GROUP_MISC, NC_("undo-type", "Plug-In"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_TYPE, NC_("undo-type", "Image type"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_PRECISION, NC_("undo-type", "Image precision"), NULL },
|
||||
|
@ -1401,6 +1404,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_FILTER_REMOVE, NC_("undo-type", "Remove effect"), NULL },
|
||||
{ GIMP_UNDO_FILTER_REORDER, NC_("undo-type", "Reorder effect"), NULL },
|
||||
{ GIMP_UNDO_FILTER_MODIFIED, NC_("undo-type", "Effect modification"), NULL },
|
||||
{ GIMP_UNDO_FILTER_VISIBILITY, NC_("undo-type", "Effect visibility"), NULL },
|
||||
{ GIMP_UNDO_CANT, NC_("undo-type", "Not undoable"), NULL },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -578,6 +578,7 @@ typedef enum /*< pdb-skip >*/
|
|||
GIMP_UNDO_GROUP_PARASITE_ATTACH, /*< desc="Attach parasite" >*/
|
||||
GIMP_UNDO_GROUP_PARASITE_REMOVE, /*< desc="Remove parasite" >*/
|
||||
GIMP_UNDO_GROUP_PATHS_IMPORT, /*< desc="Import paths" >*/
|
||||
GIMP_UNDO_GROUP_FILTER_VISIBILITY, /*< desc="Effects visibility" >*/
|
||||
GIMP_UNDO_GROUP_MISC, /*< desc="Plug-In" >*/
|
||||
|
||||
GIMP_UNDO_GROUP_LAST = GIMP_UNDO_GROUP_MISC, /*< skip >*/
|
||||
|
@ -642,6 +643,7 @@ typedef enum /*< pdb-skip >*/
|
|||
GIMP_UNDO_FILTER_REMOVE, /*< desc="Remove effect" >*/
|
||||
GIMP_UNDO_FILTER_REORDER, /*< desc="Reorder effect" >*/
|
||||
GIMP_UNDO_FILTER_MODIFIED, /*< desc="Effect modification" >*/
|
||||
GIMP_UNDO_FILTER_VISIBILITY, /*< desc="Effect visibility" >*/
|
||||
|
||||
GIMP_UNDO_CANT /*< desc="Not undoable" >*/
|
||||
} GimpUndoType;
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
#include "gimpdrawablefilter.h"
|
||||
#include "gimpdrawablefilterundo.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpitem.h"
|
||||
#include "gimpundostack.h"
|
||||
|
||||
|
||||
enum
|
||||
|
@ -140,6 +142,7 @@ gimp_drawable_filter_undo_constructed (GObject *object)
|
|||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
df_undo->active = gimp_filter_get_active (GIMP_FILTER (df_undo->filter));
|
||||
df_undo->opacity = gimp_drawable_filter_get_opacity (df_undo->filter);
|
||||
df_undo->paint_mode = gimp_drawable_filter_get_paint_mode (df_undo->filter);
|
||||
df_undo->blend_space = gimp_drawable_filter_get_blend_space (df_undo->filter);
|
||||
|
@ -267,6 +270,19 @@ gimp_drawable_filter_undo_pop (GimpUndo *undo,
|
|||
df_undo->row_index);
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
}
|
||||
else if (undo->undo_type == GIMP_UNDO_FILTER_VISIBILITY)
|
||||
{
|
||||
GimpFilter *gfilter;
|
||||
gboolean active;
|
||||
|
||||
gfilter = GIMP_FILTER (filter);
|
||||
active = gimp_filter_get_active (gfilter);
|
||||
|
||||
gimp_filter_set_active (gfilter, df_undo->active);
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
|
||||
df_undo->active = active;
|
||||
}
|
||||
else if (undo->undo_type == GIMP_UNDO_FILTER_MODIFIED)
|
||||
{
|
||||
GeglNode *op;
|
||||
|
@ -357,3 +373,52 @@ gimp_drawable_filter_undo_free (GimpUndo *undo,
|
|||
|
||||
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the undo step of toggling all filters in @filter_list can be
|
||||
* compressed. It will be compressed if:
|
||||
* - The previous undo is a group of filter visibility changes
|
||||
* - The group has changes for every filters in the list
|
||||
* - The group only has changes for filters from the list
|
||||
*/
|
||||
GimpUndo *
|
||||
gimp_drawable_filter_undo_can_compress_visibility (GimpImage *image,
|
||||
GList *filter_list)
|
||||
{
|
||||
GimpUndo *undo;
|
||||
GimpUndoStack *undo_stack;
|
||||
gint n_items;
|
||||
|
||||
g_return_val_if_fail (image != NULL, NULL);
|
||||
g_return_val_if_fail (filter_list != NULL, NULL);
|
||||
|
||||
undo = gimp_image_undo_can_compress (image,
|
||||
GIMP_TYPE_UNDO_STACK,
|
||||
GIMP_UNDO_GROUP_FILTER_VISIBILITY);
|
||||
if (undo == NULL)
|
||||
return NULL;
|
||||
|
||||
undo_stack = GIMP_UNDO_STACK (undo);
|
||||
n_items = gimp_container_get_n_children (undo_stack->undos);
|
||||
|
||||
if (n_items != g_list_length (filter_list))
|
||||
return NULL;
|
||||
|
||||
for (int i = 0; i < n_items; i++)
|
||||
{
|
||||
const GimpObject *sub_undo;
|
||||
const GimpDrawableFilterUndo *sub_filter_undo;
|
||||
|
||||
sub_undo = gimp_container_get_child_by_index (undo_stack->undos, i);
|
||||
sub_filter_undo = GIMP_DRAWABLE_FILTER_UNDO (sub_undo);
|
||||
|
||||
if (sub_filter_undo == NULL ||
|
||||
GIMP_UNDO (sub_undo)->undo_type != GIMP_UNDO_FILTER_VISIBILITY ||
|
||||
! g_list_find (filter_list, sub_filter_undo->filter))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return undo;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ struct _GimpDrawableFilterUndo
|
|||
|
||||
GimpDrawableFilter *filter;
|
||||
gint row_index;
|
||||
gboolean active;
|
||||
|
||||
GeglNode *node;
|
||||
gdouble opacity;
|
||||
|
@ -57,5 +58,8 @@ struct _GimpDrawableFilterUndoClass
|
|||
|
||||
GType gimp_drawable_filter_undo_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpUndo * gimp_drawable_filter_undo_can_compress_visibility (GimpImage *image,
|
||||
GList *filter_list);
|
||||
|
||||
|
||||
#endif /* __GIMP_DRAWABLE_FILTER_UNDO_H__ */
|
||||
|
|
|
@ -384,6 +384,22 @@ gimp_image_undo_push_filter_modified (GimpImage *image,
|
|||
NULL);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_filter_visibility (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpDrawable *drawable,
|
||||
GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), NULL);
|
||||
|
||||
return gimp_image_undo_push (image, GIMP_TYPE_DRAWABLE_FILTER_UNDO,
|
||||
GIMP_UNDO_FILTER_VISIBILITY, undo_desc,
|
||||
GIMP_DIRTY_DRAWABLE,
|
||||
"filter", filter,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/****************/
|
||||
/* Mask Undos */
|
||||
|
|
|
@ -101,6 +101,11 @@ GimpUndo * gimp_image_undo_push_filter_modified (GimpImage *image,
|
|||
GimpDrawable *drawable,
|
||||
GimpDrawableFilter
|
||||
*filter);
|
||||
GimpUndo * gimp_image_undo_push_filter_visibility (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpDrawable *drawable,
|
||||
GimpDrawableFilter
|
||||
*filter);
|
||||
|
||||
/* mask undos */
|
||||
|
||||
|
|
|
@ -686,6 +686,9 @@ gimp_image_undo_dirty_from_type (GimpUndoType undo_type)
|
|||
case GIMP_UNDO_GROUP_PATHS_IMPORT:
|
||||
return GIMP_DIRTY_IMAGE_STRUCTURE | GIMP_DIRTY_PATH;
|
||||
|
||||
case GIMP_UNDO_GROUP_FILTER_VISIBILITY:
|
||||
return GIMP_DIRTY_DRAWABLE;
|
||||
|
||||
case GIMP_UNDO_GROUP_MISC:
|
||||
return GIMP_DIRTY_ALL;
|
||||
|
||||
|
|
|
@ -539,11 +539,13 @@ gimp_undo_is_weak (GimpUndo *undo)
|
|||
case GIMP_UNDO_GROUP_ITEM_VISIBILITY:
|
||||
case GIMP_UNDO_GROUP_ITEM_PROPERTIES:
|
||||
case GIMP_UNDO_GROUP_LAYER_APPLY_MASK:
|
||||
case GIMP_UNDO_GROUP_FILTER_VISIBILITY:
|
||||
case GIMP_UNDO_ITEM_VISIBILITY:
|
||||
case GIMP_UNDO_LAYER_MODE:
|
||||
case GIMP_UNDO_LAYER_OPACITY:
|
||||
case GIMP_UNDO_LAYER_MASK_APPLY:
|
||||
case GIMP_UNDO_LAYER_MASK_SHOW:
|
||||
case GIMP_UNDO_FILTER_VISIBILITY:
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpdrawable-filters.h"
|
||||
#include "core/gimpdrawablefilter.h"
|
||||
#include "core/gimpdrawablefilterundo.h"
|
||||
#include "core/gimplist.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
|
@ -593,15 +594,41 @@ gimp_drawable_filters_editor_view_visible_cell_toggled (GtkCellRendererToggle *t
|
|||
if (GIMP_IS_DRAWABLE_FILTER (filter))
|
||||
{
|
||||
GimpDrawable *drawable;
|
||||
GimpImage *image;
|
||||
GimpContext *context;
|
||||
gboolean active;
|
||||
GimpUndo *undo;
|
||||
gboolean push_undo = TRUE;
|
||||
|
||||
g_object_get (toggle,
|
||||
"active", &active,
|
||||
NULL);
|
||||
|
||||
drawable = gimp_drawable_filter_get_drawable (filter);
|
||||
image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (view));
|
||||
|
||||
|
||||
undo = gimp_image_undo_can_compress(image,
|
||||
GIMP_TYPE_DRAWABLE_FILTER_UNDO,
|
||||
GIMP_UNDO_FILTER_VISIBILITY);
|
||||
|
||||
if (undo != NULL && GIMP_DRAWABLE_FILTER_UNDO (undo)->filter == filter)
|
||||
{
|
||||
push_undo = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_image_undo_push_filter_visibility (image,
|
||||
_("Effect visibility"),
|
||||
drawable,
|
||||
filter);
|
||||
}
|
||||
gimp_filter_set_active (GIMP_FILTER (filter), ! active);
|
||||
|
||||
if (! push_undo)
|
||||
gimp_undo_refresh_preview (undo, context);
|
||||
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (drawable)));
|
||||
}
|
||||
|
@ -657,26 +684,77 @@ gimp_drawable_filters_editor_visible_all_toggled (GtkWidget *widget,
|
|||
GimpDrawableTreeView *view)
|
||||
{
|
||||
GimpDrawableTreeViewFiltersEditor *editor = view->editor;
|
||||
GimpImage *image;
|
||||
GimpContainer *filters;
|
||||
GList *list;
|
||||
GList *iter;
|
||||
gint n_filters = 0;
|
||||
gboolean visible;
|
||||
GimpUndo *undo;
|
||||
|
||||
visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
|
||||
|
||||
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
||||
filters = gimp_drawable_get_filters (editor->drawable);
|
||||
list = GIMP_LIST (filters)->queue->head;
|
||||
|
||||
for (list = GIMP_LIST (filters)->queue->head;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
undo = gimp_drawable_filter_undo_can_compress_visibility (image, list);
|
||||
|
||||
for (iter = list; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
if (GIMP_IS_DRAWABLE_FILTER (iter->data) &&
|
||||
visible != gimp_filter_get_active (GIMP_FILTER (iter->data)))
|
||||
{
|
||||
GimpFilter *filter = list->data;
|
||||
n_filters++;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_filters <= 0)
|
||||
return;
|
||||
|
||||
if (undo == NULL)
|
||||
{
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_FILTER_VISIBILITY,
|
||||
"Effects visibility");
|
||||
}
|
||||
|
||||
for (iter = list; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (iter->data))
|
||||
{
|
||||
GimpFilter *filter = iter->data;
|
||||
GimpDrawableFilter *dfilter = iter->data;
|
||||
|
||||
/**
|
||||
* Undos are pushed for every filters, even if they weren't
|
||||
* actually toggled, so that the undo group can be compressed with
|
||||
* subsequent toggles.
|
||||
*/
|
||||
if (undo == NULL)
|
||||
{
|
||||
gimp_image_undo_push_filter_visibility (image,
|
||||
_("Effect visibility"),
|
||||
editor->drawable,
|
||||
dfilter);
|
||||
}
|
||||
|
||||
gimp_filter_set_active (filter, visible);
|
||||
}
|
||||
}
|
||||
|
||||
if (undo == NULL)
|
||||
{
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpContext *context;
|
||||
|
||||
context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (view));
|
||||
gimp_undo_refresh_preview (undo, context);
|
||||
}
|
||||
|
||||
gimp_drawable_update (editor->drawable, 0, 0, -1, -1);
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (editor->drawable)));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue