Commit 1910ff8b authored by Ell's avatar Ell

app: warn when alpha-only painting has no effect

Add a GimpPaintTool::is_alpha_only() virtual function, which
subclasses can override to indicate whether painting only affects
the alpha channel (assuming FALSE by default).  Override the
function in Gimp{PaintBrush,Ink,Clone}Tool, returning TRUE when the
current paint mode only affects the alpha (as per
gimp_layer_mode_is_alpha_only(); see the previous commit,) and in
GimpEraserTool, returning TRUE when the target drawable has an
alpha channel.

When the function returns TRUE, and the target drawable doesn't
have an alpha channel, or the alpha channel is locked, show a BAD
cursor modifier, and raise an appropriate warning when attempting
to paint.
parent 2c585981
......@@ -24,6 +24,8 @@
#include "tools-types.h"
#include "operations/layer-modes/gimp-layer-modes.h"
#include "paint/gimpclone.h"
#include "paint/gimpcloneoptions.h"
......@@ -38,6 +40,10 @@
#include "gimp-intl.h"
static gboolean gimp_clone_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
G_DEFINE_TYPE (GimpCloneTool, gimp_clone_tool, GIMP_TYPE_SOURCE_TOOL)
#define parent_class gimp_clone_tool_parent_class
......@@ -64,6 +70,9 @@ gimp_clone_tool_register (GimpToolRegisterCallback callback,
static void
gimp_clone_tool_class_init (GimpCloneToolClass *klass)
{
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_tool_class->is_alpha_only = gimp_clone_tool_is_alpha_only;
}
static void
......@@ -86,3 +95,14 @@ gimp_clone_tool_init (GimpCloneTool *clone)
source_tool->status_set_source = _("Click to set a new clone source");
source_tool->status_set_source_ctrl = _("%s to set a new clone source");
}
static gboolean
gimp_clone_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
GimpContext *context = GIMP_CONTEXT (paint_options);
GimpLayerMode paint_mode = gimp_context_get_paint_mode (context);
return gimp_layer_mode_is_alpha_only (paint_mode);
}
......@@ -36,17 +36,20 @@
#include "gimp-intl.h"
static void gimp_eraser_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display);
static void gimp_eraser_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static void gimp_eraser_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display);
static void gimp_eraser_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static GtkWidget * gimp_eraser_options_gui (GimpToolOptions *tool_options);
static gboolean gimp_eraser_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
static GtkWidget * gimp_eraser_options_gui (GimpToolOptions *tool_options);
G_DEFINE_TYPE (GimpEraserTool, gimp_eraser_tool, GIMP_TYPE_BRUSH_TOOL)
......@@ -74,10 +77,13 @@ gimp_eraser_tool_register (GimpToolRegisterCallback callback,
static void
gimp_eraser_tool_class_init (GimpEraserToolClass *klass)
{
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class->modifier_key = gimp_eraser_tool_modifier_key;
tool_class->cursor_update = gimp_eraser_tool_cursor_update;
tool_class->modifier_key = gimp_eraser_tool_modifier_key;
tool_class->cursor_update = gimp_eraser_tool_cursor_update;
paint_tool_class->is_alpha_only = gimp_eraser_tool_is_alpha_only;
}
static void
......@@ -131,6 +137,13 @@ gimp_eraser_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
static gboolean
gimp_eraser_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
return gimp_drawable_has_alpha (drawable);
}
/* tool options stuff */
......
......@@ -24,6 +24,10 @@
#include "tools-types.h"
#include "core/gimpdrawable.h"
#include "operations/layer-modes/gimp-layer-modes.h"
#include "paint/gimpinkoptions.h"
#include "widgets/gimphelp-ids.h"
......@@ -35,15 +39,17 @@
#include "gimp-intl.h"
G_DEFINE_TYPE (GimpInkTool, gimp_ink_tool, GIMP_TYPE_PAINT_TOOL)
static GimpCanvasItem * gimp_ink_tool_get_outline (GimpPaintTool *paint_tool,
GimpDisplay *display,
gdouble x,
gdouble y);
static gboolean gimp_ink_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
#define parent_class gimp_ink_tool_parent_class
G_DEFINE_TYPE (GimpInkTool, gimp_ink_tool, GIMP_TYPE_PAINT_TOOL)
static GimpCanvasItem * gimp_ink_tool_get_outline (GimpPaintTool *paint_tool,
GimpDisplay *display,
gdouble x,
gdouble y);
#define parent_class gimp_ink_tool_parent_class
void
......@@ -71,7 +77,8 @@ gimp_ink_tool_class_init (GimpInkToolClass *klass)
{
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_tool_class->get_outline = gimp_ink_tool_get_outline;
paint_tool_class->get_outline = gimp_ink_tool_get_outline;
paint_tool_class->is_alpha_only = gimp_ink_tool_is_alpha_only;
}
static void
......@@ -104,3 +111,14 @@ gimp_ink_tool_get_outline (GimpPaintTool *paint_tool,
return NULL;
}
static gboolean
gimp_ink_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
GimpContext *context = GIMP_CONTEXT (paint_options);
GimpLayerMode paint_mode = gimp_context_get_paint_mode (context);
return gimp_layer_mode_is_alpha_only (paint_mode);
}
......@@ -24,6 +24,8 @@
#include "tools-types.h"
#include "operations/layer-modes/gimp-layer-modes.h"
#include "paint/gimppaintoptions.h"
#include "widgets/gimphelp-ids.h"
......@@ -35,6 +37,10 @@
#include "gimp-intl.h"
static gboolean gimp_paintbrush_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
G_DEFINE_TYPE (GimpPaintbrushTool, gimp_paintbrush_tool, GIMP_TYPE_BRUSH_TOOL)
......@@ -59,6 +65,9 @@ gimp_paintbrush_tool_register (GimpToolRegisterCallback callback,
static void
gimp_paintbrush_tool_class_init (GimpPaintbrushToolClass *klass)
{
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_tool_class->is_alpha_only = gimp_paintbrush_tool_is_alpha_only;
}
static void
......@@ -72,3 +81,14 @@ gimp_paintbrush_tool_init (GimpPaintbrushTool *paintbrush)
gimp_paint_tool_enable_color_picker (GIMP_PAINT_TOOL (paintbrush),
GIMP_COLOR_PICK_MODE_FOREGROUND);
}
static gboolean
gimp_paintbrush_tool_is_alpha_only (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
GimpContext *context = GIMP_CONTEXT (paint_options);
GimpLayerMode paint_mode = gimp_context_get_paint_mode (context);
return gimp_layer_mode_is_alpha_only (paint_mode);
}
......@@ -32,6 +32,7 @@
#include "core/gimpdrawable.h"
#include "core/gimperror.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimppaintinfo.h"
#include "core/gimpprojection.h"
#include "core/gimptoolinfo.h"
......@@ -101,6 +102,10 @@ static GimpCanvasItem *
gdouble x,
gdouble y);
static gboolean gimp_paint_tool_check_alpha (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GError **error);
static void gimp_paint_tool_hard_notify (GimpPaintOptions *options,
const GParamSpec *pspec,
GimpTool *tool);
......@@ -278,6 +283,13 @@ gimp_paint_tool_button_press (GimpTool *tool,
return;
}
if (! gimp_paint_tool_check_alpha (paint_tool, drawable, &error))
{
gimp_tool_message_literal (tool, display, error->message);
g_clear_error (&error);
return;
}
if (! gimp_item_is_visible (GIMP_ITEM (drawable)))
{
gimp_tool_message_literal (tool, display,
......@@ -459,8 +471,9 @@ gimp_paint_tool_cursor_update (GimpTool *tool,
GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
gimp_item_is_content_locked (GIMP_ITEM (drawable)) ||
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
gimp_item_is_content_locked (GIMP_ITEM (drawable)) ||
! gimp_paint_tool_check_alpha (paint_tool, drawable, NULL) ||
! gimp_item_is_visible (GIMP_ITEM (drawable)))
{
modifier = GIMP_CURSOR_MODIFIER_BAD;
......@@ -777,6 +790,38 @@ gimp_paint_tool_get_outline (GimpPaintTool *paint_tool,
return NULL;
}
static gboolean
gimp_paint_tool_check_alpha (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GError **error)
{
GimpPaintToolClass *klass = GIMP_PAINT_TOOL_GET_CLASS (paint_tool);
if (klass->is_alpha_only && klass->is_alpha_only (paint_tool, drawable))
{
if (! gimp_drawable_has_alpha (drawable))
{
g_set_error_literal (
error, GIMP_ERROR, GIMP_FAILED,
_("The active layer does not have an alpha channel."));
return FALSE;
}
if (GIMP_IS_LAYER (drawable) &&
gimp_layer_get_lock_alpha (GIMP_LAYER (drawable)))
{
g_set_error_literal (
error, GIMP_ERROR, GIMP_FAILED,
_("The active layer's alpha channel is locked."));
return FALSE;
}
}
return TRUE;
}
static void
gimp_paint_tool_hard_notify (GimpPaintOptions *options,
const GParamSpec *pspec,
......
......@@ -65,14 +65,17 @@ struct _GimpPaintToolClass
{
GimpColorToolClass parent_class;
void (* paint_start) (GimpPaintTool *paint_tool);
void (* paint_end) (GimpPaintTool *paint_tool);
void (* paint_flush) (GimpPaintTool *paint_tool);
GimpCanvasItem * (* get_outline) (GimpPaintTool *paint_tool,
GimpDisplay *display,
gdouble x,
gdouble y);
void (* paint_start) (GimpPaintTool *paint_tool);
void (* paint_end) (GimpPaintTool *paint_tool);
void (* paint_flush) (GimpPaintTool *paint_tool);
GimpCanvasItem * (* get_outline) (GimpPaintTool *paint_tool,
GimpDisplay *display,
gdouble x,
gdouble y);
gboolean (* is_alpha_only) (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment