[gimp] app: reorganize gimppainttool-paint, to allow use by subclasses



commit e02a339e01df51f96ed4d017ce4ae7b7c0a9f83d
Author: Ell <ell_se yahoo com>
Date:   Mon Apr 16 09:36:35 2018 -0400

    app: reorganize gimppainttool-paint, to allow use by subclasses
    
    We'd like subclasses of GimpPaintTool to be able to issue paint
    commands to the tool's paint-core (in particular, see the next
    commit.)  Since paint commands should be executed on the paint
    thread, the subclasses must not call the paint-core functions
    directly, but should rather let gimppainttool-paint issue the
    commands on their behalf.
    
    Reorgainze gimppainttool-paint to make it usable for this purpose
    by subclasses.  In particular, add
    gimp_paint_tool_paint_core_paint() and
    gimp_paint_tool_paint_core_interpolate(), which call the
    corresponding paint-core functions on the paint thread.
    
    Additionally, rename the {start,end,flush}_paint() virtual
    functions of GimpPaintTool to paint_{start,end,flush}(), and rename
    gimp_paint_tool_is_painting() to gimp_paint_tool_paint_is_active(),
    so that all the gimppainttool-paint-related stuff are grouped under
    the same namespace.

 app/tools/gimpbrushtool.c       |   33 +++++-----
 app/tools/gimppainttool-paint.c |  140 +++++++++++++++++++++++++++++++++-----
 app/tools/gimppainttool-paint.h |   35 ++++++----
 app/tools/gimppainttool.c       |    6 --
 app/tools/gimppainttool.h       |    8 +--
 5 files changed, 163 insertions(+), 59 deletions(-)
---
diff --git a/app/tools/gimpbrushtool.c b/app/tools/gimpbrushtool.c
index 47bf26e..9972f5d 100644
--- a/app/tools/gimpbrushtool.c
+++ b/app/tools/gimpbrushtool.c
@@ -43,6 +43,7 @@
 #include "display/gimpdisplayshell.h"
 
 #include "gimpbrushtool.h"
+#include "gimppainttool-paint.h"
 #include "gimptoolcontrol.h"
 
 
@@ -61,9 +62,9 @@ static void   gimp_brush_tool_options_notify  (GimpTool          *tool,
                                                GimpToolOptions   *options,
                                                const GParamSpec  *pspec);
 
-static void   gimp_brush_tool_start_paint     (GimpPaintTool     *paint_tool);
-static void   gimp_brush_tool_end_paint       (GimpPaintTool     *paint_tool);
-static void   gimp_brush_tool_flush_paint     (GimpPaintTool     *paint_tool);
+static void   gimp_brush_tool_paint_start     (GimpPaintTool     *paint_tool);
+static void   gimp_brush_tool_paint_end       (GimpPaintTool     *paint_tool);
+static void   gimp_brush_tool_paint_flush     (GimpPaintTool     *paint_tool);
 static GimpCanvasItem *
               gimp_brush_tool_get_outline     (GimpPaintTool     *paint_tool,
                                                GimpDisplay       *display,
@@ -101,9 +102,9 @@ gimp_brush_tool_class_init (GimpBrushToolClass *klass)
   tool_class->cursor_update     = gimp_brush_tool_cursor_update;
   tool_class->options_notify    = gimp_brush_tool_options_notify;
 
-  paint_tool_class->start_paint = gimp_brush_tool_start_paint;
-  paint_tool_class->end_paint   = gimp_brush_tool_end_paint;
-  paint_tool_class->flush_paint = gimp_brush_tool_flush_paint;
+  paint_tool_class->paint_start = gimp_brush_tool_paint_start;
+  paint_tool_class->paint_end   = gimp_brush_tool_paint_end;
+  paint_tool_class->paint_flush = gimp_brush_tool_paint_flush;
   paint_tool_class->get_outline = gimp_brush_tool_get_outline;
 }
 
@@ -233,14 +234,14 @@ gimp_brush_tool_options_notify (GimpTool         *tool,
 }
 
 static void
-gimp_brush_tool_start_paint (GimpPaintTool *paint_tool)
+gimp_brush_tool_paint_start (GimpPaintTool *paint_tool)
 {
   GimpBrushTool        *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
   GimpBrushCore        *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
   const GimpBezierDesc *boundary;
 
-  if (GIMP_PAINT_TOOL_CLASS (parent_class)->start_paint)
-    GIMP_PAINT_TOOL_CLASS (parent_class)->start_paint (paint_tool);
+  if (GIMP_PAINT_TOOL_CLASS (parent_class)->paint_start)
+    GIMP_PAINT_TOOL_CLASS (parent_class)->paint_start (paint_tool);
 
   boundary = gimp_brush_tool_get_boundary (brush_tool,
                                            &brush_tool->boundary_width,
@@ -257,25 +258,25 @@ gimp_brush_tool_start_paint (GimpPaintTool *paint_tool)
 }
 
 static void
-gimp_brush_tool_end_paint (GimpPaintTool *paint_tool)
+gimp_brush_tool_paint_end (GimpPaintTool *paint_tool)
 {
   GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
 
   g_clear_pointer (&brush_tool->boundary, gimp_bezier_desc_free);
 
-  if (GIMP_PAINT_TOOL_CLASS (parent_class)->end_paint)
-    GIMP_PAINT_TOOL_CLASS (parent_class)->end_paint (paint_tool);
+  if (GIMP_PAINT_TOOL_CLASS (parent_class)->paint_end)
+    GIMP_PAINT_TOOL_CLASS (parent_class)->paint_end (paint_tool);
 }
 
 static void
-gimp_brush_tool_flush_paint (GimpPaintTool *paint_tool)
+gimp_brush_tool_paint_flush (GimpPaintTool *paint_tool)
 {
   GimpBrushTool        *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
   GimpBrushCore        *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
   const GimpBezierDesc *boundary;
 
-  if (GIMP_PAINT_TOOL_CLASS (parent_class)->flush_paint)
-    GIMP_PAINT_TOOL_CLASS (parent_class)->flush_paint (paint_tool);
+  if (GIMP_PAINT_TOOL_CLASS (parent_class)->paint_flush)
+    GIMP_PAINT_TOOL_CLASS (parent_class)->paint_flush (paint_tool);
 
   if (brush_tool->boundary_scale        != brush_core->scale        ||
       brush_tool->boundary_aspect_ratio != brush_core->aspect_ratio ||
@@ -347,7 +348,7 @@ gimp_brush_tool_create_outline (GimpBrushTool *brush_tool,
   g_return_val_if_fail (GIMP_IS_BRUSH_TOOL (brush_tool), NULL);
   g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL);
 
-  if (gimp_paint_tool_is_painting (GIMP_PAINT_TOOL (brush_tool)))
+  if (gimp_paint_tool_paint_is_active (GIMP_PAINT_TOOL (brush_tool)))
     {
       boundary = brush_tool->boundary;
       width    = brush_tool->boundary_width;
diff --git a/app/tools/gimppainttool-paint.c b/app/tools/gimppainttool-paint.c
index 1a4e513..869c2d6 100644
--- a/app/tools/gimppainttool-paint.c
+++ b/app/tools/gimppainttool-paint.c
@@ -43,25 +43,32 @@
 
 typedef enum
 {
-  PAINT_ITEM_TYPE_INTERPOLATE,
+  PAINT_ITEM_TYPE_CORE_PAINT,
+  PAINT_ITEM_TYPE_CORE_INTERPOLATE,
   PAINT_ITEM_TYPE_FINISH
 } PaintItemType;
 
 
 typedef struct
 {
-  PaintItemType      type;
+  PaintItemType         type;
 
   union
   {
     struct
     {
-      GimpPaintTool *paint_tool;
-      GimpCoords     coords;
-      guint32        time;
+      GimpPaintTool    *paint_tool;
+
+      union
+      {
+        GimpPaintState  state;
+        GimpCoords      coords;
+      };
+
+      guint32           time;
     };
 
-    gboolean        *finished;
+    gboolean           *finished;
   };
 } PaintItem;
 
@@ -131,7 +138,28 @@ gimp_paint_tool_paint_thread (gpointer data)
 
       switch (item->type)
         {
-        case PAINT_ITEM_TYPE_INTERPOLATE:
+        case PAINT_ITEM_TYPE_CORE_PAINT:
+          {
+            GimpPaintTool    *paint_tool    = item->paint_tool;
+            GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
+            GimpPaintCore    *core          = paint_tool->core;
+            GimpDrawable     *drawable      = paint_tool->drawable;
+
+            g_mutex_unlock (&paint_queue_mutex);
+            g_mutex_lock (&paint_mutex);
+
+            while (paint_timeout_pending)
+              g_cond_wait (&paint_cond, &paint_mutex);
+
+            gimp_paint_core_paint (core, drawable, paint_options,
+                                   item->state, item->time);
+
+            g_mutex_unlock (&paint_mutex);
+            g_mutex_lock (&paint_queue_mutex);
+          }
+          break;
+
+        case PAINT_ITEM_TYPE_CORE_INTERPOLATE:
           {
             GimpPaintTool    *paint_tool    = item->paint_tool;
             GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
@@ -180,8 +208,8 @@ gimp_paint_tool_paint_timeout (GimpPaintTool *paint_tool)
 
   update = gimp_drawable_flush_paint (drawable);
 
-  if (update && GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->flush_paint)
-    GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->flush_paint (paint_tool);
+  if (update && GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_flush)
+    GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_flush (paint_tool);
 
   paint_timeout_pending = FALSE;
   g_cond_signal (&paint_cond);
@@ -292,9 +320,9 @@ gimp_paint_tool_paint_start (GimpPaintTool     *paint_tool,
 
   /*  Notify subclasses  */
   if (gimp_paint_tool_paint_use_thread (paint_tool) &&
-      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->start_paint)
+      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_start)
     {
-      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->start_paint (paint_tool);
+      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_start (paint_tool);
     }
 
   /*  Let the specific painting function initialize itself  */
@@ -396,9 +424,9 @@ gimp_paint_tool_paint_end (GimpPaintTool *paint_tool,
 
   /*  Notify subclasses  */
   if (gimp_paint_tool_paint_use_thread (paint_tool) &&
-      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->end_paint)
+      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_end)
     {
-      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->end_paint (paint_tool);
+      GIMP_PAINT_TOOL_GET_CLASS (paint_tool)->paint_end (paint_tool);
     }
 
   /*  Exit paint mode  */
@@ -409,6 +437,16 @@ gimp_paint_tool_paint_end (GimpPaintTool *paint_tool,
   paint_tool->drawable = NULL;
 }
 
+gboolean
+gimp_paint_tool_paint_is_active (GimpPaintTool *paint_tool)
+{
+  g_return_val_if_fail (GIMP_IS_PAINT_TOOL (paint_tool), FALSE);
+
+  return paint_tool->drawable != NULL &&
+         gimp_drawable_is_painting (paint_tool->drawable);
+}
+
+
 void
 gimp_paint_tool_paint_motion (GimpPaintTool    *paint_tool,
                               const GimpCoords *coords,
@@ -445,6 +483,16 @@ gimp_paint_tool_paint_motion (GimpPaintTool    *paint_tool,
       return;
     }
 
+  gimp_paint_tool_paint_core_interpolate (paint_tool, &curr_coords, time);
+}
+
+void
+gimp_paint_tool_paint_core_paint (GimpPaintTool  *paint_tool,
+                                  GimpPaintState  state,
+                                  guint32         time)
+{
+  g_return_if_fail (GIMP_IS_PAINT_TOOL (paint_tool));
+
   if (gimp_paint_tool_paint_use_thread (paint_tool))
     {
       PaintItem *item;
@@ -453,9 +501,9 @@ gimp_paint_tool_paint_motion (GimpPaintTool    *paint_tool,
 
       item = g_slice_new (PaintItem);
 
-      item->type       = PAINT_ITEM_TYPE_INTERPOLATE;
+      item->type       = PAINT_ITEM_TYPE_CORE_PAINT;
       item->paint_tool = paint_tool;
-      item->coords     = curr_coords;
+      item->state      = state;
       item->time       = time;
 
       g_mutex_lock (&paint_queue_mutex);
@@ -467,16 +515,70 @@ gimp_paint_tool_paint_motion (GimpPaintTool    *paint_tool,
     }
   else
     {
-      GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (paint_tool);
-      GimpDisplay  *display   = paint_tool->display;
-      GimpImage    *image     = gimp_display_get_image (display);
+      GimpDrawTool     *draw_tool     = GIMP_DRAW_TOOL (paint_tool);
+      GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
+      GimpPaintCore    *core          = paint_tool->core;
+      GimpDisplay      *display       = paint_tool->display;
+      GimpImage        *image         = gimp_display_get_image (display);
+      GimpDrawable     *drawable      = paint_tool->drawable;
+
+      /*  Paint directly  */
+
+      gimp_draw_tool_pause (draw_tool);
+
+      gimp_paint_core_paint (core,
+                             drawable, paint_options, state, time);
+
+      gimp_projection_flush_now (gimp_image_get_projection (image));
+      gimp_display_flush_now (display);
+
+      gimp_draw_tool_resume (draw_tool);
+    }
+}
+
+void
+gimp_paint_tool_paint_core_interpolate (GimpPaintTool    *paint_tool,
+                                        const GimpCoords *coords,
+                                        guint32           time)
+{
+  g_return_if_fail (GIMP_IS_PAINT_TOOL (paint_tool));
+  g_return_if_fail (coords != NULL);
+
+  if (gimp_paint_tool_paint_use_thread (paint_tool))
+    {
+      PaintItem *item;
+
+      /*  Push an item to the queue, to be processed by the paint thread  */
+
+      item = g_slice_new (PaintItem);
+
+      item->type       = PAINT_ITEM_TYPE_CORE_INTERPOLATE;
+      item->paint_tool = paint_tool;
+      item->coords     = *coords;
+      item->time       = time;
+
+      g_mutex_lock (&paint_queue_mutex);
+
+      g_queue_push_tail (&paint_queue, item);
+      g_cond_signal (&paint_queue_cond);
+
+      g_mutex_unlock (&paint_queue_mutex);
+    }
+  else
+    {
+      GimpDrawTool     *draw_tool     = GIMP_DRAW_TOOL (paint_tool);
+      GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
+      GimpPaintCore    *core          = paint_tool->core;
+      GimpDisplay      *display       = paint_tool->display;
+      GimpImage        *image         = gimp_display_get_image (display);
+      GimpDrawable     *drawable      = paint_tool->drawable;
 
       /*  Paint directly  */
 
       gimp_draw_tool_pause (draw_tool);
 
       gimp_paint_core_interpolate (core,
-                                   drawable, paint_options, &curr_coords, time);
+                                   drawable, paint_options, coords, time);
 
       gimp_projection_flush_now (gimp_image_get_projection (image));
       gimp_display_flush_now (display);
diff --git a/app/tools/gimppainttool-paint.h b/app/tools/gimppainttool-paint.h
index 51d3080..8dcc056 100644
--- a/app/tools/gimppainttool-paint.h
+++ b/app/tools/gimppainttool-paint.h
@@ -19,19 +19,28 @@
 #define __GIMP_PAINT_TOOL_PAINT_H__
 
 
-gboolean   gimp_paint_tool_paint_start  (GimpPaintTool     *tool,
-                                         GimpDisplay       *display,
-                                         const GimpCoords  *coords,
-                                         guint32            time,
-                                         gboolean           constrain,
-                                         GError           **error);
-void       gimp_paint_tool_paint_end    (GimpPaintTool     *tool,
-                                         guint32            time,
-                                         gboolean           cancel);
-
-void       gimp_paint_tool_paint_motion (GimpPaintTool    *tool,
-                                         const GimpCoords *coords,
-                                         guint32           time);
+gboolean   gimp_paint_tool_paint_start            (GimpPaintTool     *tool,
+                                                   GimpDisplay       *display,
+                                                   const GimpCoords  *coords,
+                                                   guint32            time,
+                                                   gboolean           constrain,
+                                                   GError           **error);
+void       gimp_paint_tool_paint_end              (GimpPaintTool     *tool,
+                                                   guint32            time,
+                                                   gboolean           cancel);
+
+gboolean   gimp_paint_tool_paint_is_active        (GimpPaintTool     *tool);
+
+void       gimp_paint_tool_paint_motion           (GimpPaintTool    *tool,
+                                                   const GimpCoords *coords,
+                                                   guint32           time);
+
+void       gimp_paint_tool_paint_core_paint       (GimpPaintTool     *tool,
+                                                   GimpPaintState     state,
+                                                   guint32            time);
+void       gimp_paint_tool_paint_core_interpolate (GimpPaintTool     *tool,
+                                                   const GimpCoords  *coords,
+                                                   guint32            time);
 
 
 #endif  /*  __GIMP_PAINT_TOOL_PAINT_H__  */
diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c
index ebc25f6..77ef265 100644
--- a/app/tools/gimppainttool.c
+++ b/app/tools/gimppainttool.c
@@ -843,9 +843,3 @@ gimp_paint_tool_set_draw_circle (GimpPaintTool *tool,
   tool->draw_circle = draw_circle;
   tool->circle_size = circle_size;
 }
-
-gboolean
-gimp_paint_tool_is_painting (GimpPaintTool *tool)
-{
-  return tool->drawable != NULL && gimp_drawable_is_painting (tool->drawable);
-}
diff --git a/app/tools/gimppainttool.h b/app/tools/gimppainttool.h
index 6153335..cd4d7b4 100644
--- a/app/tools/gimppainttool.h
+++ b/app/tools/gimppainttool.h
@@ -65,9 +65,9 @@ struct _GimpPaintToolClass
 {
   GimpColorToolClass  parent_class;
 
-  void             (* start_paint) (GimpPaintTool *paint_tool);
-  void             (* end_paint)   (GimpPaintTool *paint_tool);
-  void             (* flush_paint) (GimpPaintTool *paint_tool);
+  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,
@@ -89,7 +89,5 @@ void       gimp_paint_tool_set_draw_circle     (GimpPaintTool     *tool,
                                                 gboolean           draw_circle,
                                                 gint               circle_size);
 
-gboolean   gimp_paint_tool_is_painting         (GimpPaintTool     *tool);
-
 
 #endif  /*  __GIMP_PAINT_TOOL_H__  */


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