app: globally block editing vector and link layers.
Instead of blocking various drawable-editing tools to work on vector or link layers, per tool (as in commits38c379cd92or36330a271a), let's have a more generic logic in GimpTool. We will now block the tool initialization early when it's destructive and tries to work on link or vector layers. By default, all tools are set as being destructive, but we can override this per-class by setting the class' is_destructive flag. For instance, text and path tools, or the Zoom or Color picker tools, etc. are non-destructive. Filter tools also are non-destructive (they may be destructive, but have their internal code to disable this path on these types of layers). Source tools are special-cased because we may allow them to be initialized on a link/vector layer as sources. For this special-case, I make a second check on gimp_tool_button_press().
This commit is contained in:
parent
759a886e4b
commit
5ddb853964
14 changed files with 133 additions and 73 deletions
|
|
@ -155,6 +155,7 @@ gimp_align_tool_class_init (GimpAlignToolClass *klass)
|
|||
tool_class->cursor_update = gimp_align_tool_cursor_update;
|
||||
tool_class->can_undo = gimp_align_tool_can_undo;
|
||||
tool_class->undo = gimp_align_tool_undo;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
draw_tool_class->draw = gimp_align_tool_draw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -582,7 +582,6 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool,
|
|||
GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
|
||||
GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpItem *locked_item = NULL;
|
||||
GList *drawables = gimp_image_get_selected_drawables (image);
|
||||
GimpDrawable *drawable;
|
||||
|
||||
|
|
@ -623,28 +622,6 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool,
|
|||
return;
|
||||
}
|
||||
|
||||
if (gimp_item_is_link_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Link layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
return;
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
return;
|
||||
}
|
||||
else if (gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("The selected layer's pixels are locked."));
|
||||
gimp_tools_blink_lock_box (display->gimp, locked_item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (options->fill_area == GIMP_BUCKET_FILL_LINE_ART &&
|
||||
! gimp_line_art_get_input (bucket_tool->priv->line_art))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -120,14 +120,15 @@ gimp_color_picker_tool_class_init (GimpColorPickerToolClass *klass)
|
|||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||||
GimpColorToolClass *color_tool_class = GIMP_COLOR_TOOL_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_color_picker_tool_constructed;
|
||||
object_class->dispose = gimp_color_picker_tool_dispose;
|
||||
object_class->constructed = gimp_color_picker_tool_constructed;
|
||||
object_class->dispose = gimp_color_picker_tool_dispose;
|
||||
|
||||
tool_class->control = gimp_color_picker_tool_control;
|
||||
tool_class->modifier_key = gimp_color_picker_tool_modifier_key;
|
||||
tool_class->oper_update = gimp_color_picker_tool_oper_update;
|
||||
tool_class->control = gimp_color_picker_tool_control;
|
||||
tool_class->modifier_key = gimp_color_picker_tool_modifier_key;
|
||||
tool_class->oper_update = gimp_color_picker_tool_oper_update;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
color_tool_class->picked = gimp_color_picker_tool_picked;
|
||||
color_tool_class->picked = gimp_color_picker_tool_picked;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ gimp_filter_tool_class_init (GimpFilterToolClass *klass)
|
|||
tool_class->oper_update = gimp_filter_tool_oper_update;
|
||||
tool_class->cursor_update = gimp_filter_tool_cursor_update;
|
||||
tool_class->options_notify = gimp_filter_tool_options_notify;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
color_tool_class->can_pick = gimp_filter_tool_can_pick_color;
|
||||
color_tool_class->pick = gimp_filter_tool_pick_color;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ gimp_magnify_tool_class_init (GimpMagnifyToolClass *klass)
|
|||
tool_class->motion = gimp_magnify_tool_motion;
|
||||
tool_class->modifier_key = gimp_magnify_tool_modifier_key;
|
||||
tool_class->cursor_update = gimp_magnify_tool_cursor_update;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
draw_tool_class->draw = gimp_magnify_tool_draw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ gimp_measure_tool_class_init (GimpMeasureToolClass *klass)
|
|||
tool_class->button_press = gimp_measure_tool_button_press;
|
||||
tool_class->button_release = gimp_measure_tool_button_release;
|
||||
tool_class->motion = gimp_measure_tool_motion;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
tr_class->recalc_matrix = gimp_measure_tool_recalc_matrix;
|
||||
tr_class->get_undo_desc = gimp_measure_tool_get_undo_desc;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ gimp_move_tool_class_init (GimpMoveToolClass *klass)
|
|||
tool_class->modifier_key = gimp_move_tool_modifier_key;
|
||||
tool_class->oper_update = gimp_move_tool_oper_update;
|
||||
tool_class->cursor_update = gimp_move_tool_cursor_update;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
draw_tool_class->draw = gimp_move_tool_draw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,8 +315,7 @@ gimp_paint_tool_button_press (GimpTool *tool,
|
|||
|
||||
for (iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
GimpDrawable *drawable = iter->data;
|
||||
GimpItem *locked_item = NULL;
|
||||
GimpDrawable *drawable = iter->data;
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
|
||||
{
|
||||
|
|
@ -327,41 +326,6 @@ gimp_paint_tool_button_press (GimpTool *tool,
|
|||
return;
|
||||
}
|
||||
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_link_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item))
|
||||
{
|
||||
gboolean constrain_only;
|
||||
|
||||
/* Allow vector/link or pixel-locaked layers to be set as sources */
|
||||
constrain_only = (state & gimp_get_constrain_behavior_mask () &&
|
||||
! (state & gimp_get_extend_selection_mask ()));
|
||||
if (! (GIMP_IS_SOURCE_TOOL (tool) && constrain_only))
|
||||
{
|
||||
if (gimp_item_is_link_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Link layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("The selected item's pixels are locked."));
|
||||
gimp_tools_blink_lock_box (display->gimp, locked_item);
|
||||
}
|
||||
g_list_free (drawables);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (! gimp_paint_tool_check_alpha (paint_tool, drawable, display, &error))
|
||||
{
|
||||
GtkWidget *options_gui;
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ gimp_path_tool_class_init (GimpPathToolClass *klass)
|
|||
tool_class->motion = gimp_path_tool_motion;
|
||||
tool_class->modifier_key = gimp_path_tool_modifier_key;
|
||||
tool_class->cursor_update = gimp_path_tool_cursor_update;
|
||||
tool_class->is_destructive = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -89,13 +89,14 @@ gimp_selection_tool_class_init (GimpSelectionToolClass *klass)
|
|||
{
|
||||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||||
|
||||
tool_class->control = gimp_selection_tool_control;
|
||||
tool_class->modifier_key = gimp_selection_tool_modifier_key;
|
||||
tool_class->key_press = gimp_edit_selection_tool_key_press;
|
||||
tool_class->oper_update = gimp_selection_tool_oper_update;
|
||||
tool_class->cursor_update = gimp_selection_tool_cursor_update;
|
||||
tool_class->control = gimp_selection_tool_control;
|
||||
tool_class->modifier_key = gimp_selection_tool_modifier_key;
|
||||
tool_class->key_press = gimp_edit_selection_tool_key_press;
|
||||
tool_class->oper_update = gimp_selection_tool_oper_update;
|
||||
tool_class->cursor_update = gimp_selection_tool_cursor_update;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
klass->have_selection = gimp_selection_tool_real_have_selection;
|
||||
klass->have_selection = gimp_selection_tool_real_have_selection;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ gimp_text_tool_class_init (GimpTextToolClass *klass)
|
|||
tool_class->oper_update = gimp_text_tool_oper_update;
|
||||
tool_class->cursor_update = gimp_text_tool_cursor_update;
|
||||
tool_class->get_popup = gimp_text_tool_get_popup;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
draw_tool_class->draw = gimp_text_tool_draw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "core/gimp.h"
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimplinklayer.h"
|
||||
#include "core/gimpprogress.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
|
||||
|
|
@ -36,9 +37,15 @@
|
|||
#include "display/gimpdisplayshell-cursor.h"
|
||||
#include "display/gimpstatusbar.h"
|
||||
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "widgets/gimpwidgets-utils.h"
|
||||
|
||||
#include "gimpsourcetool.h"
|
||||
#include "gimptool.h"
|
||||
#include "gimptool-progress.h"
|
||||
#include "gimptoolcontrol.h"
|
||||
#include "gimptools-utils.h"
|
||||
|
||||
#include "gimp-log.h"
|
||||
#include "gimp-intl.h"
|
||||
|
|
@ -188,6 +195,8 @@ gimp_tool_class_init (GimpToolClass *klass)
|
|||
GIMP_TYPE_TOOL_INFO,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
klass->is_destructive = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -632,6 +641,54 @@ gimp_tool_initialize (GimpTool *tool,
|
|||
g_return_val_if_fail (GIMP_IS_TOOL (tool), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE);
|
||||
|
||||
/* Source tools are special-cased as we want to allow vector/link or
|
||||
* pixel-locked layers to be set as sources. So we still let these be
|
||||
* initialized but will further verify the button state in
|
||||
* gimp_tool_button_press().
|
||||
*/
|
||||
if (GIMP_TOOL_GET_CLASS (tool)->is_destructive && !
|
||||
GIMP_IS_SOURCE_TOOL (tool))
|
||||
{
|
||||
GimpImage *image;
|
||||
GList *drawables;
|
||||
|
||||
image = gimp_display_get_image (display);
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
for (GList *iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
GimpDrawable *drawable = iter->data;
|
||||
GimpItem *locked_item = NULL;
|
||||
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_link_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item))
|
||||
{
|
||||
if (gimp_item_is_link_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Link layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("The selected item's pixels are locked."));
|
||||
gimp_tools_blink_lock_box (display->gimp, locked_item);
|
||||
}
|
||||
|
||||
g_list_free (drawables);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
g_list_free (drawables);
|
||||
}
|
||||
|
||||
if (! GIMP_TOOL_GET_CLASS (tool)->initialize (tool, display, &error))
|
||||
{
|
||||
if (error)
|
||||
|
|
@ -719,6 +776,56 @@ gimp_tool_button_press (GimpTool *tool,
|
|||
g_return_if_fail (coords != NULL);
|
||||
g_return_if_fail (GIMP_IS_DISPLAY (display));
|
||||
|
||||
if (GIMP_IS_SOURCE_TOOL (tool))
|
||||
{
|
||||
GimpImage *image;
|
||||
GList *drawables;
|
||||
|
||||
image = gimp_display_get_image (display);
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
for (GList *iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
GimpDrawable *drawable = iter->data;
|
||||
GimpItem *locked_item = NULL;
|
||||
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_link_layer (GIMP_ITEM (drawable)) ||
|
||||
gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item))
|
||||
{
|
||||
gboolean constrain_only;
|
||||
|
||||
/* Allow vector/link or pixel-locked layers to be set as sources */
|
||||
constrain_only = (state & gimp_get_constrain_behavior_mask () &&
|
||||
! (state & gimp_get_extend_selection_mask ()));
|
||||
if (! constrain_only)
|
||||
{
|
||||
if (gimp_item_is_link_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Link layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("The selected item's pixels are locked."));
|
||||
gimp_tools_blink_lock_box (display->gimp, locked_item);
|
||||
}
|
||||
|
||||
g_list_free (drawables);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_list_free (drawables);
|
||||
}
|
||||
|
||||
GIMP_TOOL_GET_CLASS (tool)->button_press (tool, coords, time, state,
|
||||
press_type, display);
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ struct _GimpToolClass
|
|||
void (* options_notify) (GimpTool *tool,
|
||||
GimpToolOptions *options,
|
||||
const GParamSpec *pspec);
|
||||
|
||||
gboolean is_destructive;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ gimp_transform_tool_class_init (GimpTransformToolClass *klass)
|
|||
{
|
||||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||||
|
||||
tool_class->control = gimp_transform_tool_control;
|
||||
tool_class->control = gimp_transform_tool_control;
|
||||
tool_class->is_destructive = FALSE;
|
||||
|
||||
klass->recalc_matrix = NULL;
|
||||
klass->get_undo_desc = gimp_transform_tool_real_get_undo_desc;
|
||||
|
|
|
|||
Loading…
Reference in a new issue