[gimp] app: warn when alpha-only painting has no effect



commit 1910ff8b1ab6f19b57a8f2ab86b2c977576995f3
Author: Ell <ell_se yahoo com>
Date:   Mon May 7 16:40:27 2018 -0400

    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.

 app/tools/gimpclonetool.c      |   20 ++++++++++++++++
 app/tools/gimperasertool.c     |   39 +++++++++++++++++++++----------
 app/tools/gimpinktool.c        |   32 ++++++++++++++++++++-----
 app/tools/gimppaintbrushtool.c |   20 ++++++++++++++++
 app/tools/gimppainttool.c      |   49 ++++++++++++++++++++++++++++++++++++++-
 app/tools/gimppainttool.h      |   19 +++++++++------
 6 files changed, 149 insertions(+), 30 deletions(-)
---
diff --git a/app/tools/gimpclonetool.c b/app/tools/gimpclonetool.c
index 06152be..dfac7c9 100644
--- a/app/tools/gimpclonetool.c
+++ b/app/tools/gimpclonetool.c
@@ -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);
+}
diff --git a/app/tools/gimperasertool.c b/app/tools/gimperasertool.c
index d070a89..32b5873 100644
--- a/app/tools/gimperasertool.c
+++ b/app/tools/gimperasertool.c
@@ -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  */
 
diff --git a/app/tools/gimpinktool.c b/app/tools/gimpinktool.c
index 71b9dbd..fa4ee3f 100644
--- a/app/tools/gimpinktool.c
+++ b/app/tools/gimpinktool.c
@@ -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);
+}
diff --git a/app/tools/gimppaintbrushtool.c b/app/tools/gimppaintbrushtool.c
index 218fb33..70131ed 100644
--- a/app/tools/gimppaintbrushtool.c
+++ b/app/tools/gimppaintbrushtool.c
@@ -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);
+}
diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c
index 77ef265..757d113 100644
--- a/app/tools/gimppainttool.c
+++ b/app/tools/gimppainttool.c
@@ -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,
diff --git a/app/tools/gimppainttool.h b/app/tools/gimppainttool.h
index cd4d7b4..d38d504 100644
--- a/app/tools/gimppainttool.h
+++ b/app/tools/gimppainttool.h
@@ -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);
 };
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]