Commit 7e52ed90 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

added signal "set-brush" which is G_SIGNAL_RUN_LAST so we can connect

2004-06-23  Michael Natterer  <mitch@gimp.org>

	* app/paint/gimpbrushcore.[ch]: added signal "set-brush" which is
	G_SIGNAL_RUN_LAST so we can connect before and after the default
	implementation. Moved the brush setting and outline invalidation
	stuff to its default implementation. Also remember the outline's
	width and height. Call gimp_brush_core_set_brush() from
	gimp_brush_core_invalidate_cache() so "set-brush" is emitted
	whenever a generated brush becomes dirty.

	* app/tools/gimppainttool.c (gimp_paint_tool_button_press): don't
	pause/resume but rather stop/start the draw_tool. Fixes straight
	line preview aretefacts.

	(gimp_paint_tool_oper_update): set the brush_core's brush before
	starting the draw_tool.

	(gimp_paint_tool_draw): never free the brush_core's cached brush
	outline because the brush_core does that by itself now.

	(gimp_paint_tool_set_brush)
	(gimp_paint_tool_set_brush_after): new callbacks which pause and
	resume the draw_tool. Fixes brush outline artefacts when modifying
	the current brush e.g. by using the mouse wheel.
parent d88f23dd
2004-06-23 Michael Natterer <mitch@gimp.org>
* app/paint/gimpbrushcore.[ch]: added signal "set-brush" which is
G_SIGNAL_RUN_LAST so we can connect before and after the default
implementation. Moved the brush setting and outline invalidation
stuff to its default implementation. Also remember the outline's
width and height. Call gimp_brush_core_set_brush() from
gimp_brush_core_invalidate_cache() so "set-brush" is emitted
whenever a generated brush becomes dirty.
* app/tools/gimppainttool.c (gimp_paint_tool_button_press): don't
pause/resume but rather stop/start the draw_tool. Fixes straight
line preview aretefacts.
(gimp_paint_tool_oper_update): set the brush_core's brush before
starting the draw_tool.
(gimp_paint_tool_draw): never free the brush_core's cached brush
outline because the brush_core does that by itself now.
(gimp_paint_tool_set_brush)
(gimp_paint_tool_set_brush_after): new callbacks which pause and
resume the draw_tool. Fixes brush outline artefacts when modifying
the current brush e.g. by using the mouse wheel.
2004-06-23 Michael Natterer <mitch@gimp.org>
* app/actions/context-commands.h: removed enum GimpContextSelectType.
......
......@@ -31,6 +31,7 @@
#include "core/gimpbrush.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpmarshal.h"
#include "gimpbrushcore.h"
#include "gimpbrushcore-kernels.h"
......@@ -42,6 +43,13 @@
#define EPSILON 0.00001
enum
{
SET_BRUSH,
LAST_SIGNAL
};
/* local function prototypes */
static void gimp_brush_core_class_init (GimpBrushCoreClass *klass);
......@@ -72,6 +80,9 @@ static TempBuf *gimp_brush_core_get_paint_area (GimpPaintCore *paint_cor
GimpDrawable *drawable,
GimpPaintOptions *paint_options);
static void gimp_brush_core_real_set_brush (GimpBrushCore *core,
GimpBrush *brush);
static void gimp_brush_core_calc_brush_size (GimpBrushCore *core,
MaskBuf *mask,
gdouble scale,
......@@ -121,6 +132,8 @@ static void paint_line_pixmap_mask (GimpImage *dest,
static GimpPaintCoreClass *parent_class = NULL;
static guint core_signals[LAST_SIGNAL] = { 0, };
GType
gimp_brush_core_get_type (void)
......@@ -158,6 +171,16 @@ gimp_brush_core_class_init (GimpBrushCoreClass *klass)
parent_class = g_type_class_peek_parent (klass);
core_signals[SET_BRUSH] =
g_signal_new ("set-brush",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GimpBrushCoreClass, set_brush),
NULL, NULL,
gimp_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GIMP_TYPE_BRUSH);
object_class->finalize = gimp_brush_core_finalize;
paint_core_class->start = gimp_brush_core_start;
......@@ -168,6 +191,7 @@ gimp_brush_core_class_init (GimpBrushCoreClass *klass)
klass->handles_changing_brush = FALSE;
klass->use_scale = TRUE;
klass->set_brush = gimp_brush_core_real_set_brush;
}
static void
......@@ -210,6 +234,8 @@ gimp_brush_core_init (GimpBrushCore *core)
core->brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
core->brush_bound_width = 0;
core->brush_bound_height = 0;
}
static void
......@@ -266,6 +292,8 @@ gimp_brush_core_finalize (GObject *object)
g_free (core->brush_bound_segs);
core->brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
core->brush_bound_width = 0;
core->brush_bound_height = 0;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
......@@ -329,44 +357,17 @@ gimp_brush_core_start (GimpPaintCore *paint_core,
GimpCoords *coords)
{
GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
GimpBrush *brush;
/* Each buffer is the same size as
* the maximum bounds of the active brush...
*/
if (core->main_brush != gimp_context_get_brush (GIMP_CONTEXT (paint_options)))
{
if (core->main_brush)
{
g_signal_handlers_disconnect_by_func (core->main_brush,
gimp_brush_core_invalidate_cache,
core);
g_object_unref (core->main_brush);
core->main_brush = NULL;
}
brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
if (core->brush_bound_segs)
{
g_free (core->brush_bound_segs);
core->brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
}
}
if (core->main_brush != brush)
gimp_brush_core_set_brush (core, brush);
if (! core->main_brush)
{
core->main_brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
if (! core->main_brush)
{
g_message (_("No brushes available for use with this tool."));
return FALSE;
}
g_object_ref (core->main_brush);
g_signal_connect (core->main_brush, "invalidate_preview",
G_CALLBACK (gimp_brush_core_invalidate_cache),
core);
g_message (_("No brushes available for use with this tool."));
return FALSE;
}
core->spacing = (gdouble) gimp_brush_get_spacing (core->main_brush) / 100.0;
......@@ -693,6 +694,46 @@ gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
return paint_core->canvas_buf;
}
static void
gimp_brush_core_real_set_brush (GimpBrushCore *core,
GimpBrush *brush)
{
if (core->main_brush)
{
g_signal_handlers_disconnect_by_func (core->main_brush,
gimp_brush_core_invalidate_cache,
core);
g_object_unref (core->main_brush);
core->main_brush = NULL;
}
if (core->brush_bound_segs)
{
g_free (core->brush_bound_segs);
core->brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
core->brush_bound_width = 0;
core->brush_bound_height = 0;
}
core->main_brush = brush;
if (core->main_brush)
{
g_object_ref (core->main_brush);
g_signal_connect (core->main_brush, "invalidate_preview",
G_CALLBACK (gimp_brush_core_invalidate_cache),
core);
}
}
void
gimp_brush_core_set_brush (GimpBrushCore *core,
GimpBrush *brush)
{
g_signal_emit (core, core_signals[SET_BRUSH], 0, brush);
}
void
gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
......@@ -796,12 +837,9 @@ gimp_brush_core_invalidate_cache (GimpBrush *brush,
core->cache_invalid = TRUE;
core->solid_cache_invalid = TRUE;
if (core->brush_bound_segs)
{
g_free (core->brush_bound_segs);
core->brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
}
/* Set the same brush again so the "set-brush" signal is emitted */
gimp_brush_core_set_brush (core, brush);
}
/************************************************************
......
......@@ -73,6 +73,8 @@ struct _GimpBrushCore
/* don't use these... */
BoundSeg *brush_bound_segs;
gint n_brush_bound_segs;
gint brush_bound_width;
gint brush_bound_height;
};
struct _GimpBrushCoreClass
......@@ -84,11 +86,16 @@ struct _GimpBrushCoreClass
/* Scale the brush mask depending on pressure */
gboolean use_scale;
void (* set_brush) (GimpBrushCore *core,
GimpBrush *brush);
};
GType gimp_brush_core_get_type (void) G_GNUC_CONST;
void gimp_brush_core_set_brush (GimpBrushCore *core,
GimpBrush *brush);
void gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
gdouble brush_opacity,
......
......@@ -110,6 +110,12 @@ static void gimp_paint_tool_color_picked (GimpColorTool *color_tool,
GimpRGB *color,
gint color_index);
static void gimp_paint_tool_set_brush (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool);
static void gimp_paint_tool_set_brush_after(GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool);
static void gimp_paint_tool_notify_brush (GimpDisplayConfig *config,
GParamSpec *pspec,
GimpPaintTool *paint_tool);
......@@ -224,6 +230,16 @@ gimp_paint_tool_constructor (GType type,
paint_tool->core = g_object_new (tool->tool_info->paint_info->paint_type,
NULL);
if (GIMP_IS_BRUSH_CORE (paint_tool->core))
{
g_signal_connect (paint_tool->core, "set-brush",
G_CALLBACK (gimp_paint_tool_set_brush),
paint_tool);
g_signal_connect_after (paint_tool->core, "set-brush",
G_CALLBACK (gimp_paint_tool_set_brush_after),
paint_tool);
}
return object;
}
......@@ -377,6 +393,9 @@ gimp_paint_tool_button_press (GimpTool *tool,
curr_coords.x -= off_x;
curr_coords.y -= off_y;
if (gimp_draw_tool_is_active (draw_tool))
gimp_draw_tool_stop (draw_tool);
if (tool->gdisp &&
tool->gdisp != gdisp &&
tool->gdisp->gimage == gdisp->gimage)
......@@ -432,8 +451,6 @@ gimp_paint_tool_button_press (GimpTool *tool,
/* pause the current selection */
gimp_image_selection_control (gdisp->gimage, GIMP_SELECTION_PAUSE);
gimp_draw_tool_pause (draw_tool);
/* Let the specific painting function initialize itself */
gimp_paint_core_paint (core, drawable, paint_options, INIT_PAINT, time);
......@@ -449,7 +466,7 @@ gimp_paint_tool_button_press (GimpTool *tool,
gimp_display_flush_now (gdisp);
gimp_draw_tool_resume (draw_tool);
gimp_draw_tool_start (draw_tool, gdisp);
}
static void
......@@ -719,6 +736,17 @@ gimp_paint_tool_oper_update (GimpTool *tool,
paint_tool->brush_x = coords->x;
paint_tool->brush_y = coords->y;
if (GIMP_IS_BRUSH_CORE (core))
{
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (core);
GimpBrush *brush;
brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
if (brush_core->main_brush != brush)
gimp_brush_core_set_brush (brush_core, brush);
}
gimp_draw_tool_start (draw_tool, gdisp);
}
......@@ -768,26 +796,13 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
if (paint_tool->draw_brush && GIMP_IS_BRUSH_CORE (core))
{
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (core);
GimpContext *context;
GimpBrush *brush;
TempBuf *mask;
context =
GIMP_CONTEXT (GIMP_TOOL (draw_tool)->tool_info->tool_options);
brush = gimp_context_get_brush (context);
mask = gimp_brush_get_mask (brush);
if (brush != brush_core->main_brush && brush_core->brush_bound_segs)
{
g_free (brush_core->brush_bound_segs);
brush_core->brush_bound_segs = NULL;
brush_core->n_brush_bound_segs = 0;
}
if (! brush_core->brush_bound_segs)
{
PixelRegion PR = { 0, };
TempBuf *mask;
PixelRegion PR = { 0, };
mask = gimp_brush_get_mask (brush_core->main_brush);
PR.data = temp_buf_data (mask);
PR.x = 0;
......@@ -803,17 +818,23 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
0, 0,
PR.w, PR.h,
0);
brush_core->brush_bound_width = mask->width;
brush_core->brush_bound_height = mask->height;
}
if (brush_core->brush_bound_segs)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpPaintOptions *paint_options;
gdouble brush_x, brush_y;
paint_options = GIMP_PAINT_OPTIONS (context);
paint_options = GIMP_PAINT_OPTIONS (tool->tool_info->tool_options);
brush_x = paint_tool->brush_x - ((gdouble) mask->width / 2.0);
brush_y = paint_tool->brush_y - ((gdouble) mask->height / 2.0);
brush_x = (paint_tool->brush_x -
((gdouble) brush_core->brush_bound_width / 2.0));
brush_y = (paint_tool->brush_y -
((gdouble) brush_core->brush_bound_height / 2.0));
if (gimp_paint_options_get_brush_mode (paint_options) == GIMP_BRUSH_HARD)
{
......@@ -892,6 +913,22 @@ gimp_paint_tool_color_picked (GimpColorTool *color_tool,
}
}
static void
gimp_paint_tool_set_brush (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (paint_tool));
}
static void
gimp_paint_tool_set_brush_after (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool)
{
gimp_draw_tool_resume (GIMP_DRAW_TOOL (paint_tool));
}
static void
gimp_paint_tool_notify_brush (GimpDisplayConfig *config,
GParamSpec *pspec,
......
......@@ -110,6 +110,12 @@ static void gimp_paint_tool_color_picked (GimpColorTool *color_tool,
GimpRGB *color,
gint color_index);
static void gimp_paint_tool_set_brush (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool);
static void gimp_paint_tool_set_brush_after(GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool);
static void gimp_paint_tool_notify_brush (GimpDisplayConfig *config,
GParamSpec *pspec,
GimpPaintTool *paint_tool);
......@@ -224,6 +230,16 @@ gimp_paint_tool_constructor (GType type,
paint_tool->core = g_object_new (tool->tool_info->paint_info->paint_type,
NULL);
if (GIMP_IS_BRUSH_CORE (paint_tool->core))
{
g_signal_connect (paint_tool->core, "set-brush",
G_CALLBACK (gimp_paint_tool_set_brush),
paint_tool);
g_signal_connect_after (paint_tool->core, "set-brush",
G_CALLBACK (gimp_paint_tool_set_brush_after),
paint_tool);
}
return object;
}
......@@ -377,6 +393,9 @@ gimp_paint_tool_button_press (GimpTool *tool,
curr_coords.x -= off_x;
curr_coords.y -= off_y;
if (gimp_draw_tool_is_active (draw_tool))
gimp_draw_tool_stop (draw_tool);
if (tool->gdisp &&
tool->gdisp != gdisp &&
tool->gdisp->gimage == gdisp->gimage)
......@@ -432,8 +451,6 @@ gimp_paint_tool_button_press (GimpTool *tool,
/* pause the current selection */
gimp_image_selection_control (gdisp->gimage, GIMP_SELECTION_PAUSE);
gimp_draw_tool_pause (draw_tool);
/* Let the specific painting function initialize itself */
gimp_paint_core_paint (core, drawable, paint_options, INIT_PAINT, time);
......@@ -449,7 +466,7 @@ gimp_paint_tool_button_press (GimpTool *tool,
gimp_display_flush_now (gdisp);
gimp_draw_tool_resume (draw_tool);
gimp_draw_tool_start (draw_tool, gdisp);
}
static void
......@@ -719,6 +736,17 @@ gimp_paint_tool_oper_update (GimpTool *tool,
paint_tool->brush_x = coords->x;
paint_tool->brush_y = coords->y;
if (GIMP_IS_BRUSH_CORE (core))
{
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (core);
GimpBrush *brush;
brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
if (brush_core->main_brush != brush)
gimp_brush_core_set_brush (brush_core, brush);
}
gimp_draw_tool_start (draw_tool, gdisp);
}
......@@ -768,26 +796,13 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
if (paint_tool->draw_brush && GIMP_IS_BRUSH_CORE (core))
{
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (core);
GimpContext *context;
GimpBrush *brush;
TempBuf *mask;
context =
GIMP_CONTEXT (GIMP_TOOL (draw_tool)->tool_info->tool_options);
brush = gimp_context_get_brush (context);
mask = gimp_brush_get_mask (brush);
if (brush != brush_core->main_brush && brush_core->brush_bound_segs)
{
g_free (brush_core->brush_bound_segs);
brush_core->brush_bound_segs = NULL;
brush_core->n_brush_bound_segs = 0;
}
if (! brush_core->brush_bound_segs)
{
PixelRegion PR = { 0, };
TempBuf *mask;
PixelRegion PR = { 0, };
mask = gimp_brush_get_mask (brush_core->main_brush);
PR.data = temp_buf_data (mask);
PR.x = 0;
......@@ -803,17 +818,23 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
0, 0,
PR.w, PR.h,
0);
brush_core->brush_bound_width = mask->width;
brush_core->brush_bound_height = mask->height;
}
if (brush_core->brush_bound_segs)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpPaintOptions *paint_options;
gdouble brush_x, brush_y;
paint_options = GIMP_PAINT_OPTIONS (context);
paint_options = GIMP_PAINT_OPTIONS (tool->tool_info->tool_options);
brush_x = paint_tool->brush_x - ((gdouble) mask->width / 2.0);
brush_y = paint_tool->brush_y - ((gdouble) mask->height / 2.0);
brush_x = (paint_tool->brush_x -
((gdouble) brush_core->brush_bound_width / 2.0));
brush_y = (paint_tool->brush_y -
((gdouble) brush_core->brush_bound_height / 2.0));
if (gimp_paint_options_get_brush_mode (paint_options) == GIMP_BRUSH_HARD)
{
......@@ -892,6 +913,22 @@ gimp_paint_tool_color_picked (GimpColorTool *color_tool,
}
}
static void
gimp_paint_tool_set_brush (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (paint_tool));
}
static void
gimp_paint_tool_set_brush_after (GimpBrushCore *brush_core,
GimpBrush *brush,
GimpPaintTool *paint_tool)
{
gimp_draw_tool_resume (GIMP_DRAW_TOOL (paint_tool));
}
static void
gimp_paint_tool_notify_brush (GimpDisplayConfig *config,
GParamSpec *pspec,
......
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