Commit ed7ea51f authored by Ell's avatar Ell

app: remove "Edit -> Fade..."

This commit completely removes the "Edit -> Fade..." feature,
because...

- The main reason is that "fade" requires us to keep two buffers,
  instead of one, for each fadeable undo step, doubling (or worse,
  since the extra buffer might have higher precision than the
  drawable) the space consumed by these steps.  This has notable
  impact when editing large images.  This overhead is incurred even
  when not actually using "fade", and since it seems to be very
  rarely used, this is too wasteful.

- "Fade" is broken in 2.10: when comitting a filter, we copy the
  cached parts of the result into the apply buffer.  However, the
  result cache sits after the mode node, while the apply buffer
  should contain the result of the filter *before* the mode node,
  which can lead to wrong results in the general case.

- The same behavior can be trivially achieved "manually", by
  duplicating the layer, editing the duplicate, and changing its
  opacity/mode.

- If we really want this feature, now that most filters are GEGL
  ops, it makes more sense to just add opacity/mode options to the
  filter tool, instead of having this be a separate step.
parent 10cdef9a
......@@ -27,7 +27,6 @@
#include "core/gimp.h"
#include "core/gimpchannel.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawableundo.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimplayer.h"
......@@ -101,13 +100,6 @@ static const GimpActionEntry edit_actions[] =
G_CALLBACK (edit_undo_clear_cmd_callback),
GIMP_HELP_EDIT_UNDO_CLEAR },
{ "edit-fade", GIMP_ICON_EDIT_UNDO,
NC_("edit-action", "_Fade..."), NULL,
NC_("edit-action",
"Modify paint mode and opacity of the last pixel manipulation"),
G_CALLBACK (edit_fade_cmd_callback),
GIMP_HELP_EDIT_FADE },
{ "edit-cut", GIMP_ICON_EDIT_CUT,
NC_("edit-action", "Cu_t"), "<primary>X",
NC_("edit-action", "Move the selected pixels to the clipboard"),
......@@ -296,11 +288,9 @@ edit_actions_update (GimpActionGroup *group,
GimpDrawable *drawable = NULL;
gchar *undo_name = NULL;
gchar *redo_name = NULL;
gchar *fade_name = NULL;
gboolean writable = FALSE;
gboolean children = FALSE;
gboolean undo_enabled = FALSE;
gboolean fade_enabled = FALSE;
if (image)
{
......@@ -342,21 +332,6 @@ edit_actions_update (GimpActionGroup *group,
else if (redo)
redo_name = g_strdup_printf (_("_Redo %s"),
gimp_object_get_name (redo));
undo = gimp_image_undo_get_fadeable (image);
if (GIMP_IS_DRAWABLE_UNDO (undo) &&
GIMP_DRAWABLE_UNDO (undo)->applied_buffer)
{
fade_enabled = TRUE;
}
if (fade_enabled)
{
fade_name =
g_strdup_printf (_("_Fade %s..."),
gimp_object_get_name (undo));
}
}
}
......@@ -368,18 +343,15 @@ edit_actions_update (GimpActionGroup *group,
SET_LABEL ("edit-undo", undo_name ? undo_name : _("_Undo"));
SET_LABEL ("edit-redo", redo_name ? redo_name : _("_Redo"));
SET_LABEL ("edit-fade", fade_name ? fade_name : _("_Fade..."));
SET_SENSITIVE ("edit-undo", undo_enabled && undo_name);
SET_SENSITIVE ("edit-redo", undo_enabled && redo_name);
SET_SENSITIVE ("edit-strong-undo", undo_enabled && undo_name);
SET_SENSITIVE ("edit-strong-redo", undo_enabled && redo_name);
SET_SENSITIVE ("edit-undo-clear", undo_enabled && (undo_name || redo_name));
SET_SENSITIVE ("edit-fade", fade_enabled && fade_name);
g_free (undo_name);
g_free (redo_name);
g_free (fade_name);
SET_SENSITIVE ("edit-cut", writable && !children);
SET_SENSITIVE ("edit-copy", drawable);
......
......@@ -55,8 +55,6 @@
#include "tools/tool_manager.h"
#include "dialogs/fade-dialog.h"
#include "actions.h"
#include "edit-commands.h"
......@@ -204,27 +202,6 @@ edit_undo_clear_cmd_callback (GtkAction *action,
gtk_widget_destroy (dialog);
}
void
edit_fade_cmd_callback (GtkAction *action,
gpointer data)
{
GimpImage *image;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
dialog = fade_dialog_new (image, widget);
if (dialog)
{
g_signal_connect_object (image, "disconnect",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
gtk_widget_show (dialog);
}
}
void
edit_cut_cmd_callback (GtkAction *action,
gpointer data)
......
......@@ -30,9 +30,6 @@ void edit_strong_redo_cmd_callback (GtkAction *action,
void edit_undo_clear_cmd_callback (GtkAction *action,
gpointer data);
void edit_fade_cmd_callback (GtkAction *action,
gpointer data);
void edit_cut_cmd_callback (GtkAction *action,
gpointer data);
void edit_copy_cmd_callback (GtkAction *action,
......
......@@ -286,8 +286,6 @@ libappcore_a_sources = \
gimpimage-crop.h \
gimpimage-duplicate.c \
gimpimage-duplicate.h \
gimpimage-fade.c \
gimpimage-fade.h \
gimpimage-flip.c \
gimpimage-flip.h \
gimpimage-grid.h \
......
......@@ -33,9 +33,7 @@
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpdrawable-combine.h"
#include "gimpdrawableundo.h"
#include "gimpimage.h"
#include "gimpimage-undo.h"
#include "gimptempbuf.h"
......@@ -102,34 +100,8 @@ gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
if (push_undo)
{
GimpDrawableUndo *undo;
gimp_drawable_push_undo (drawable, undo_desc,
NULL, x, y, width, height);
undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
if (undo)
{
undo->paint_mode = mode;
undo->blend_space = blend_space;
undo->composite_space = composite_space;
undo->composite_mode = composite_mode;
undo->opacity = opacity;
undo->applied_buffer =
gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
gegl_buffer_get_format (buffer));
gimp_gegl_buffer_copy (
buffer,
GEGL_RECTANGLE (buffer_region->x + (x - base_x),
buffer_region->y + (y - base_y),
width, height),
GEGL_ABYSS_NONE,
undo->applied_buffer,
GEGL_RECTANGLE (0, 0, width, height));
}
}
applicator = gimp_applicator_new (NULL, FALSE, FALSE);
......
......@@ -29,11 +29,9 @@
#include "gimpchannel.h"
#include "gimpdrawable.h"
#include "gimpdrawable-edit.h"
#include "gimpdrawableundo.h"
#include "gimpcontext.h"
#include "gimpfilloptions.h"
#include "gimpimage.h"
#include "gimpimage-undo.h"
#include "gimppattern.h"
#include "gimptempbuf.h"
......@@ -106,24 +104,17 @@ gimp_drawable_edit_fill_direct (GimpDrawable *drawable,
GimpFillOptions *options,
const gchar *undo_desc)
{
GeglBuffer *buffer;
GimpImage *image;
GimpContext *context;
GimpDrawableUndo *undo;
gdouble opacity;
GimpLayerMode mode;
GimpLayerMode composite_mode;
gint width;
gint height;
buffer = gimp_drawable_get_buffer (drawable);
image = gimp_item_get_image (GIMP_ITEM (drawable));
context = GIMP_CONTEXT (options);
opacity = gimp_context_get_opacity (context);
mode = gimp_context_get_paint_mode (context);
composite_mode = gimp_layer_mode_get_paint_composite_mode (mode);
width = gimp_item_get_width (GIMP_ITEM (drawable));
height = gimp_item_get_height (GIMP_ITEM (drawable));
GeglBuffer *buffer;
GimpContext *context;
GimpLayerMode mode;
gint width;
gint height;
buffer = gimp_drawable_get_buffer (drawable);
context = GIMP_CONTEXT (options);
mode = gimp_context_get_paint_mode (context);
width = gimp_item_get_width (GIMP_ITEM (drawable));
height = gimp_item_get_height (GIMP_ITEM (drawable));
gimp_drawable_push_undo (drawable, undo_desc,
NULL, 0, 0, width, height);
......@@ -132,27 +123,6 @@ gimp_drawable_edit_fill_direct (GimpDrawable *drawable,
gimp_fill_options_fill_buffer (options, drawable, buffer, 0, 0);
else
gimp_gegl_clear (buffer, NULL);
undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
if (undo)
{
undo->paint_mode = mode;
undo->blend_space = GIMP_LAYER_COLOR_SPACE_AUTO;
undo->composite_space = GIMP_LAYER_COLOR_SPACE_AUTO;
undo->composite_mode = composite_mode;
undo->opacity = opacity;
if (! gimp_layer_mode_is_subtractive (mode))
{
undo->applied_buffer = gegl_buffer_dup (buffer);
}
else
{
undo->applied_buffer = gimp_fill_options_create_buffer (
options, drawable, GEGL_RECTANGLE (0, 0, width, height), 0, 0);
}
}
}
......
......@@ -33,11 +33,9 @@
#include "gimpdrawable.h"
#include "gimpdrawable-filters.h"
#include "gimpdrawable-private.h"
#include "gimpdrawableundo.h"
#include "gimpfilter.h"
#include "gimpfilterstack.h"
#include "gimpimage.h"
#include "gimpimage-undo.h"
#include "gimpprogress.h"
#include "gimpprojection.h"
......@@ -126,7 +124,6 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GeglBuffer *undo_buffer;
GimpApplicator *applicator;
GeglBuffer *apply_buffer = NULL;
GeglBuffer *cache = NULL;
GeglRectangle *rects = NULL;
gint n_rects = 0;
......@@ -153,41 +150,11 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
gimp_applicator_set_preview (applicator, FALSE,
GEGL_RECTANGLE (0, 0, 0, 0));
/* the apply_buffer will make a copy of the region that is
* actually processed in gimp_gegl_apply_cached_operation()
* below.
*/
apply_buffer = gimp_applicator_dup_apply_buffer (applicator, &rect);
/* the cache and its valid rectangles are the region that
* has already been processed by this applicator.
*/
cache = gimp_applicator_get_cache_buffer (applicator,
&rects, &n_rects);
if (cache)
{
gint i;
for (i = 0; i < n_rects; i++)
{
g_printerr ("valid: %d %d %d %d\n",
rects[i].x, rects[i].y,
rects[i].width, rects[i].height);
/* we have to copy the cached region to the apply_buffer,
* because this region is not going to be processed.
*/
gimp_gegl_buffer_copy (cache,
&rects[i],
GEGL_ABYSS_NONE,
apply_buffer,
GEGL_RECTANGLE (rects[i].x - rect.x,
rects[i].y - rect.y,
0, 0));
}
}
}
gimp_projection_stop_rendering (gimp_image_get_projection (image));
......@@ -205,22 +172,6 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
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 = apply_buffer;
apply_buffer = NULL;
}
}
}
else
{
......@@ -237,9 +188,6 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
g_object_unref (undo_buffer);
if (apply_buffer)
g_object_unref (apply_buffer);
if (cache)
{
g_object_unref (cache);
......
......@@ -43,11 +43,9 @@
#include "gimpdrawable-private.h"
#include "gimpdrawable-shadow.h"
#include "gimpdrawable-transform.h"
#include "gimpdrawableundo.h"
#include "gimpfilterstack.h"
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
#include "gimpmarshal.h"
#include "gimppickable.h"
......@@ -900,10 +898,7 @@ gimp_drawable_real_push_undo (GimpDrawable *drawable,
gint width,
gint height)
{
GimpImage *image;
GimpDrawableUndo *undo;
gint applied_x = x;
gint applied_y = y;
GimpImage *image;
if (! buffer)
{
......@@ -940,14 +935,6 @@ gimp_drawable_real_push_undo (GimpDrawable *drawable,
undo_desc, drawable,
buffer, x, y);
undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
if (undo)
{
undo->applied_x = applied_x;
undo->applied_y = applied_y;
}
g_object_unref (buffer);
}
......
......@@ -202,7 +202,6 @@ gimp_drawable_undo_free (GimpUndo *undo,
GimpDrawableUndo *drawable_undo = GIMP_DRAWABLE_UNDO (undo);
g_clear_object (&drawable_undo->buffer);
g_clear_object (&drawable_undo->applied_buffer);
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
}
......@@ -40,16 +40,6 @@ struct _GimpDrawableUndo
GeglBuffer *buffer;
gint x;
gint y;
/* stuff for "Fade" */
GeglBuffer *applied_buffer;
gint applied_x;
gint applied_y;
GimpLayerMode paint_mode;
GimpLayerColorSpace blend_space;
GimpLayerColorSpace composite_space;
GimpLayerCompositeMode composite_mode;
gdouble opacity;
};
struct _GimpDrawableUndoClass
......
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "core-types.h"
#include "operations/layer-modes/gimp-layer-modes.h"
#include "gimpcontext.h"
#include "gimpdrawable.h"
#include "gimpdrawableundo.h"
#include "gimpimage.h"
#include "gimpimage-fade.h"
#include "gimpimage-undo.h"
/* public functions */
gboolean
gimp_image_fade (GimpImage *image,
GimpContext *context)
{
GimpDrawableUndo *undo;
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
if (undo && undo->applied_buffer)
{
GimpDrawable *drawable;
GeglBuffer *buffer;
drawable = GIMP_DRAWABLE (GIMP_ITEM_UNDO (undo)->item);
g_object_ref (undo);
buffer = g_object_ref (undo->applied_buffer);
gimp_image_undo (image);
gimp_drawable_apply_buffer (drawable, buffer,
gegl_buffer_get_extent (buffer),
TRUE,
gimp_object_get_name (undo),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
GIMP_LAYER_COLOR_SPACE_AUTO,
GIMP_LAYER_COLOR_SPACE_AUTO,
gimp_layer_mode_get_paint_composite_mode (
gimp_context_get_paint_mode (context)),
NULL, undo->applied_x, undo->applied_y);
g_object_unref (buffer);
g_object_unref (undo);
return TRUE;
}
return FALSE;
}
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_IMAGE_FADE_H__
#define __GIMP_IMAGE_FADE_H__
gboolean gimp_image_fade (GimpImage *image,
GimpContext *context);
#endif /* __GIMP_IMAGE_FADE_H__ */
......@@ -26,7 +26,6 @@
#include "gimp.h"
#include "gimp-utils.h"
#include "gimpdrawableundo.h"
#include "gimpimage.h"
#include "gimpimage-private.h"
#include "gimpimage-undo.h"
......@@ -461,34 +460,6 @@ gimp_image_undo_can_compress (GimpImage *image,
return NULL;
}
GimpUndo *
gimp_image_undo_get_fadeable (GimpImage *image)
{
GimpImagePrivate *private;
GimpUndo *undo;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image);
undo = gimp_undo_stack_peek (private->undo_stack);
if (GIMP_IS_UNDO_STACK (undo) && undo->undo_type == GIMP_UNDO_GROUP_PAINT)
{
GimpUndoStack *stack = GIMP_UNDO_STACK (undo);
if (gimp_undo_stack_get_depth (stack) == 2)
{
undo = gimp_undo_stack_peek (stack);
}
}
if (GIMP_IS_DRAWABLE_UNDO (undo))
return undo;
return NULL;
}
/* private functions */
......
......@@ -53,7 +53,5 @@ GimpUndo * gimp_image_undo_can_compress (GimpImage *image,
GType object_type,
GimpUndoType undo_type);
GimpUndo * gimp_image_undo_get_fadeable (GimpImage *image);
#endif /* __GIMP_IMAGE__UNDO_H__ */
......@@ -37,8 +37,6 @@ libappdialogs_a_sources = \
data-delete-dialog.h \
extensions-dialog.c \
extensions-dialog.h \
fade-dialog.c \
fade-dialog.h \
file-open-dialog.c \
file-open-dialog.h \
file-open-location-dialog.c \
......
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "dialogs-types.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-fade.h"
#include "core/gimpimage-undo.h"
#include "core/gimpdrawable.h"
#include "core/gimpdrawableundo.h"
#include "core/gimpundostack.h"
#include "widgets/gimplayermodebox.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpviewabledialog.h"
#include "fade-dialog.h"
#include "gimp-intl.h"
typedef struct
{
GimpImage *image;
GimpDrawable *drawable;
GimpContext *context;
gboolean applied;
GimpLayerMode orig_paint_mode;
gdouble orig_opacity;
} FadeDialog;
/* local function prototypes */
static void fade_dialog_free (FadeDialog *private);
static void fade_dialog_response (GtkWidget *dialog,
gint response_id,
FadeDialog *private);
static void fade_dialog_context_changed (FadeDialog *private);
/* public functions */
GtkWidget *
fade_dialog_new (GimpImage *image,
GtkWidget *parent)
{
FadeDialog *private;
GimpDrawableUndo *undo;
GimpDrawable *drawable;
GimpItem *item;
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *menu;
GtkWidget *scale;
gchar *title;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL);
undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));
if (! (undo && undo->applied_buffer))
return NULL;
item = GIMP_ITEM_UNDO (undo)->item;
drawable = GIMP_DRAWABLE (item);
private = g_slice_new0 (FadeDialog);
private->image = image;
private->drawable = drawable;
private->context = gimp_context_new (image->gimp,
"fade-dialog", NULL);
private->applied = FALSE;
private->orig_paint_mode = undo->paint_mode;
private->orig_opacity = undo->opacity;
g_object_set (private->context,
"paint-mode", undo->paint_mode,
"opacity", undo->opacity,
NULL);
title = g_strdup_printf (_("Fade %s"), gimp_object_get_name (undo));
dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (drawable),
private->context,
title, "gimp-edit-fade",
"edit-undo", title,
parent,
gimp_standard_help_func,
GIMP_HELP_EDIT_FADE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Fade"), GTK_RESPONSE_OK,
NULL);
g_free (title);
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
g_object_weak_ref (G_OBJECT (dialog),
(GWeakNotify) fade_dialog_free, private);
g_signal_connect (dialog, "response",
G_CALLBACK (fade_dialog_response),
private);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
/* the paint mode menu */
menu = gimp_prop_layer_mode_box_new (G_OBJECT (private->context),
"paint-mode",
GIMP_LAYER_MODE_CONTEXT_FADE);
gimp_layer_mode_box_set_label (GIMP_LAYER_MODE_BOX (menu), _("Mode"));
gtk_box_pack_start (GTK_BOX (main_vbox), menu, FALSE, FALSE, 0);
gtk_widget_show (menu);
/* the opacity scale */
scale = gimp_prop_spin_scale_new (G_OBJECT (private->context),
"opacity",