mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
3f4995d3d7
commit
e02a339e01
|
@ -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;
|
||||
|
|
|
@ -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_interpolate (core,
|
||||
drawable, paint_options, &curr_coords, time);
|
||||
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, coords, time);
|
||||
|
||||
gimp_projection_flush_now (gimp_image_get_projection (image));
|
||||
gimp_display_flush_now (display);
|
||||
|
|
|
@ -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);
|
||||
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_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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue