Commit 72284d38 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

added back the handler which invalidates the display_title on dirty/clean.

2002-02-15  Michael Natterer  <mitch@gimp.org>

	* app/display/gimpdisplayshell-handlers.c: added back the handler
	which invalidates the display_title on dirty/clean. Removing it
	was simply wrong.

	* app/display/gimpdisplayshell-scale.c: don't call
	gimp_display_shell_update_title() directly but set
	shell->title_dirty to TRUE before calling gdisplays_flush().

	* app/paint/gimppaintcore.[ch]: added gimp_paint_core_constrain()
	which does the "snap to 15 degrees" stuff formerly done in
	GimpPaintTool. Call gimp_brush_select_brush() in
	gimp_paint_core_paint() if paint_state == MOTION, not in several
	other places.  Reordered functions, added some comments and
	documentation.

	* app/paint/gimpairbrush.c
	* app/paint/gimpclone.c
	* app/paint/gimpconvolve.c
	* app/paint/gimpdodgeburn.c
	* app/paint/gimperaser.c
	* app/paint/gimppaintbrush.c
	* app/paint/gimppencil.c
	* app/paint/gimpsmudge.c:
	s/CORE_CAN_HANDLE_CHANGING_BRUSH/CORE_HANDLES_CHANGING_BRUSH/g,
	minor cleanup.

	* app/pdb/pdb-types.h: include "paint/paint-types.h"

	* app/tools/gimppainttool.[ch]: use gimp_paint_core_constrain(),
	removed paint_tool->state because it's not needed any more,
	lots of cleanup.

	* tools/pdbgen/app.pl: another eeky special case for "paint/".

	* tools/pdbgen/pdb/paint_tools.pdb: include stuff from "paint/",
	not "tools/".

	* app/pdb/paint_tools_cmds.c: regenerated.
parent 7387f8cc
2002-02-15 Michael Natterer <mitch@gimp.org>
* app/display/gimpdisplayshell-handlers.c: added back the handler
which invalidates the display_title on dirty/clean. Removing it
was simply wrong.
* app/display/gimpdisplayshell-scale.c: don't call
gimp_display_shell_update_title() directly but set
shell->title_dirty to TRUE before calling gdisplays_flush().
* app/paint/gimppaintcore.[ch]: added gimp_paint_core_constrain()
which does the "snap to 15 degrees" stuff formerly done in
GimpPaintTool. Call gimp_brush_select_brush() in
gimp_paint_core_paint() if paint_state == MOTION, not in several
other places. Reordered functions, added some comments and
documentation.
* app/paint/gimpairbrush.c
* app/paint/gimpclone.c
* app/paint/gimpconvolve.c
* app/paint/gimpdodgeburn.c
* app/paint/gimperaser.c
* app/paint/gimppaintbrush.c
* app/paint/gimppencil.c
* app/paint/gimpsmudge.c:
s/CORE_CAN_HANDLE_CHANGING_BRUSH/CORE_HANDLES_CHANGING_BRUSH/g,
minor cleanup.
* app/pdb/pdb-types.h: include "paint/paint-types.h"
* app/tools/gimppainttool.[ch]: use gimp_paint_core_constrain(),
removed paint_tool->state because it's not needed any more,
lots of cleanup.
* tools/pdbgen/app.pl: another eeky special case for "paint/".
* tools/pdbgen/pdb/paint_tools.pdb: include stuff from "paint/",
not "tools/".
* app/pdb/paint_tools_cmds.c: regenerated.
2002-02-14 Michael Natterer <mitch@gimp.org>
Core/UI separation for the paint tools:
......
......@@ -38,6 +38,8 @@
/* local function prototypes */
static void gimp_display_shell_clean_dirty_handler (GimpImage *gimage,
GimpDisplayShell *shell);
static void gimp_display_shell_undo_event_handler (GimpImage *gimage,
gint event,
GimpDisplayShell *shell);
......@@ -72,6 +74,12 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
gimage = shell->gdisp->gimage;
g_signal_connect (G_OBJECT (gimage), "clean",
G_CALLBACK (gimp_display_shell_clean_dirty_handler),
shell);
g_signal_connect (G_OBJECT (gimage), "dirty",
G_CALLBACK (gimp_display_shell_clean_dirty_handler),
shell);
g_signal_connect (G_OBJECT (gimage), "undo_event",
G_CALLBACK (gimp_display_shell_undo_event_handler),
shell);
......@@ -133,11 +141,21 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
g_signal_handlers_disconnect_by_func (G_OBJECT (gimage),
gimp_display_shell_undo_event_handler,
shell);
g_signal_handlers_disconnect_by_func (G_OBJECT (gimage),
gimp_display_shell_clean_dirty_handler,
shell);
}
/* private functions */
static void
gimp_display_shell_clean_dirty_handler (GimpImage *gimage,
GimpDisplayShell *shell)
{
shell->title_dirty = TRUE;
}
static void
gimp_display_shell_undo_event_handler (GimpImage *gimage,
gint event,
......
......@@ -395,10 +395,11 @@ gimp_display_shell_scale_resize (GimpDisplayShell *shell,
if (resize_window || redisplay)
{
gimp_display_shell_expose_full (shell);
gdisplays_flush ();
/* title may have changed if it includes the zoom ratio */
gimp_display_shell_update_title (shell);
shell->title_dirty = TRUE;
gdisplays_flush ();
}
/* re-enable the active tool */
......
......@@ -121,7 +121,7 @@ gimp_airbrush_init (GimpAirbrush *airbrush)
paint_core = GIMP_PAINT_CORE (airbrush);
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
......@@ -143,13 +143,9 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
GimpPaintCoreState paint_state)
{
AirbrushOptions *options;
GimpBrush *brush;
options = (AirbrushOptions *) paint_options;
brush =
gimp_context_get_brush (gimp_get_current_context (drawable->gimage->gimp));
switch (paint_state)
{
case INIT_PAINT:
......@@ -309,7 +305,7 @@ gimp_airbrush_motion (GimpPaintCore *paint_core,
/* paste the newly painted area to the image */
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (pressure, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (gimp_get_current_context (gimage->gimp)),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
SOFT, scale, paint_appl_mode);
}
......@@ -136,7 +136,7 @@ gimp_clone_init (GimpClone *clone)
paint_core = GIMP_PAINT_CORE (clone);
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
paint_core->flags |= CORE_TRACES_ON_WINDOW;
clone->set_source = FALSE;
......@@ -433,7 +433,7 @@ gimp_clone_motion (GimpPaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
pressure_options->pressure ? PRESSURE : SOFT,
scale, CONSTANT);
......
......@@ -408,7 +408,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_core_replace_canvas (paint_core, drawable,
OPAQUE_OPACITY,
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_opacity (context) * 255,
pressure_options->pressure ? PRESSURE : SOFT,
scale,
INCREMENTAL);
......
......@@ -121,7 +121,7 @@ gimp_dodgeburn_init (GimpDodgeBurn *dodgeburn)
paint_core = GIMP_PAINT_CORE (dodgeburn);
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
......
......@@ -99,7 +99,7 @@ gimp_eraser_init (GimpEraser *eraser)
paint_core = GIMP_PAINT_CORE (eraser);
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
......
......@@ -108,7 +108,7 @@ gimp_paintbrush_init (GimpPaintbrush *paintbrush)
paint_core = GIMP_PAINT_CORE (paintbrush);
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
......
......@@ -193,29 +193,39 @@ gimp_paint_core_init (GimpPaintCore *core)
{
gint i, j;
core->ID = global_core_ID++;
core->ID = global_core_ID++;
core->distance = 0.0;
core->spacing = 0.0;
core->x1 = 0;
core->y1 = 0;
core->x2 = 0;
core->y2 = 0;
core->distance = 0.0;
core->spacing = 0.0;
core->x1 = 0;
core->y1 = 0;
core->x2 = 0;
core->y2 = 0;
core->brush = NULL;
core->brush = NULL;
core->flags = 0;
core->flags = 0;
core->undo_tiles = NULL;
core->canvas_tiles = NULL;
core->undo_tiles = NULL;
core->canvas_tiles = NULL;
core->orig_buf = NULL;
core->canvas_buf = NULL;
core->orig_buf = NULL;
core->canvas_buf = NULL;
core->pressure_brush = NULL;
core->solid_brush = NULL;
core->scale_brush = NULL;
core->scale_pixmap = NULL;
core->pressure_brush = NULL;
core->solid_brush = NULL;
core->last_solid_brush = NULL;
core->scale_brush = NULL;
core->last_scale_brush = NULL;
core->last_scale_width = 0;
core->last_scale_height = 0;
core->scale_pixmap = NULL;
core->last_scale_pixmap = NULL;
core->last_scale_pixmap_width = 0;
core->last_scale_pixmap_height = 0;
g_assert (PAINT_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE);
......@@ -223,10 +233,10 @@ gimp_paint_core_init (GimpPaintCore *core)
for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
core->kernel_brushes[i][j] = NULL;
core->last_brush_mask = NULL;
core->cache_invalid = FALSE;
core->last_brush_mask = NULL;
core->cache_invalid = FALSE;
core->grr_brush = NULL;
core->grr_brush = NULL;
}
static void
......@@ -263,8 +273,6 @@ gimp_paint_core_finalize (GObject *object)
core->scale_pixmap = NULL;
}
g_assert (PAINT_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE);
for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
if (core->kernel_brushes[i][j])
......@@ -295,6 +303,14 @@ gimp_paint_core_paint (GimpPaintCore *core,
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (paint_options != NULL);
if (paint_state == MOTION_PAINT &&
(core->flags & CORE_HANDLES_CHANGING_BRUSH))
{
core->brush = gimp_brush_select_brush (core->brush,
&core->last_coords,
&core->cur_coords);
}
GIMP_PAINT_CORE_GET_CLASS (core)->paint (core,
drawable,
paint_options,
......@@ -371,6 +387,128 @@ gimp_paint_core_start (GimpPaintCore *core,
return TRUE;
}
void
gimp_paint_core_finish (GimpPaintCore *core,
GimpDrawable *drawable)
{
GimpImage *gimage;
GimpPaintCoreUndo *pu;
g_return_if_fail (GIMP_IS_PAINT_CORE (core));
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
/* Determine if any part of the image has been altered--
* if nothing has, then just return...
*/
if ((core->x2 == core->x1) ||
(core->y2 == core->y1))
return;
undo_push_group_start (gimage, PAINT_CORE_UNDO);
pu = g_new0 (GimpPaintCoreUndo, 1);
pu->core_ID = core->ID;
pu->core_type = G_TYPE_FROM_INSTANCE (core);
pu->last_coords = core->start_coords;
/* Push a paint undo */
undo_push_paint (gimage, pu);
/* push an undo */
gimp_drawable_apply_image (drawable,
core->x1, core->y1,
core->x2, core->y2,
core->undo_tiles,
TRUE);
core->undo_tiles = NULL;
/* push the group end */
undo_push_group_end (gimage);
/* invalidate the drawable--have to do it here, because
* it is not done during the actual painting.
*/
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (drawable));
}
void
gimp_paint_core_cleanup (GimpPaintCore *core)
{
g_return_if_fail (GIMP_IS_PAINT_CORE (core));
if (core->undo_tiles)
{
tile_manager_destroy (core->undo_tiles);
core->undo_tiles = NULL;
}
if (core->canvas_tiles)
{
tile_manager_destroy (core->canvas_tiles);
core->canvas_tiles = NULL;
}
if (core->orig_buf)
{
temp_buf_free (core->orig_buf);
core->orig_buf = NULL;
}
if (core->canvas_buf)
{
temp_buf_free (core->canvas_buf);
core->canvas_buf = NULL;
}
}
/**
* gimp_paint_core_constrain:
* @core: the #GimpPaintCore.
*
* Restricts the (core->last_coords, core->curr_coords) vector to 15
* degree steps, possibly changing core->curr_coords
**/
void
gimp_paint_core_constrain (GimpPaintCore *core)
{
static const gint tangens2[6] = { 34, 106, 196, 334, 618, 1944 };
static const gint cosinus[7] = { 256, 247, 222, 181, 128, 66, 0 };
gint dx, dy, i, radius, frac;
g_return_if_fail (GIMP_IS_PAINT_CORE (core));
dx = core->cur_coords.x - core->last_coords.x;
dy = core->cur_coords.y - core->last_coords.y;
if (dy)
{
radius = sqrt (SQR (dx) + SQR (dy));
frac = abs ((dx << 8) / dy);
for (i = 0; i < 6; i++)
{
if (frac < tangens2[i])
break;
}
dx = (dx > 0 ?
(cosinus[6-i] * radius) >> 8 :
- ((cosinus[6-i] * radius) >> 8));
dy = (dy > 0 ?
(cosinus[i] * radius) >> 8 :
- ((cosinus[i] * radius) >> 8));
}
core->cur_coords.x = core->last_coords.x + dx;
core->cur_coords.y = core->last_coords.y + dy;
}
void
gimp_paint_core_interpolate (GimpPaintCore *core,
GimpDrawable *drawable,
......@@ -401,12 +539,12 @@ gimp_paint_core_interpolate (GimpPaintCore *core,
delta.ytilt = core->cur_coords.ytilt - core->last_coords.ytilt;
delta.wheel = core->cur_coords.wheel - core->last_coords.wheel;
/* return if there has been no motion */
if (! delta.x &&
! delta.y &&
/* return if there has been no motion */
if (! delta.x &&
! delta.y &&
! delta.pressure &&
! delta.xtilt &&
! delta.ytilt &&
! delta.xtilt &&
! delta.ytilt &&
! delta.wheel)
return;
......@@ -444,31 +582,18 @@ gimp_paint_core_interpolate (GimpPaintCore *core,
{
t = (core->distance - initial) / dist;
core->cur_coords.x = (core->last_coords.x +
delta.x * t);
core->cur_coords.y = (core->last_coords.y +
delta.y * t);
core->cur_coords.pressure = (core->last_coords.pressure +
delta.pressure * t);
core->cur_coords.xtilt = (core->last_coords.xtilt +
delta.xtilt * t);
core->cur_coords.ytilt = (core->last_coords.ytilt +
delta.ytilt * t);
core->cur_coords.wheel = (core->last_coords.wheel +
delta.ytilt * t);
core->pixel_dist = pixel_initial + pixel_dist * t;
core->cur_coords.x = core->last_coords.x + t * delta.x;
core->cur_coords.y = core->last_coords.y + t * delta.y;
core->cur_coords.pressure = core->last_coords.pressure + t * delta.pressure;
core->cur_coords.xtilt = core->last_coords.xtilt + t * delta.xtilt;
core->cur_coords.ytilt = core->last_coords.ytilt + t * delta.ytilt;
core->cur_coords.wheel = core->last_coords.wheel + t * delta.wheel;
core->pixel_dist = pixel_initial + t * pixel_dist;
/* save the current brush */
current_brush = core->brush;
if (core->flags & CORE_CAN_HANDLE_CHANGING_BRUSH)
{
core->brush = gimp_brush_select_brush (core->brush,
&core->last_coords,
&core->cur_coords);
}
gimp_paint_core_paint (core, drawable, paint_options, MOTION_PAINT);
/* restore the current brush pointer */
......@@ -487,83 +612,8 @@ gimp_paint_core_interpolate (GimpPaintCore *core,
core->pixel_dist = pixel_initial + pixel_dist;
}
void
gimp_paint_core_finish (GimpPaintCore *core,
GimpDrawable *drawable)
{
GimpImage *gimage;
GimpPaintCoreUndo *pu;
g_return_if_fail (GIMP_IS_PAINT_CORE (core));
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
/* Determine if any part of the image has been altered--
* if nothing has, then just return...
*/
if ((core->x2 == core->x1) ||
(core->y2 == core->y1))
return;
undo_push_group_start (gimage, PAINT_CORE_UNDO);
pu = g_new0 (GimpPaintCoreUndo, 1);
pu->core_ID = core->ID;
pu->core_type = G_TYPE_FROM_INSTANCE (core);
pu->last_coords = core->start_coords;
/* Push a paint undo */
undo_push_paint (gimage, pu);
/* push an undo */
gimp_drawable_apply_image (drawable,
core->x1, core->y1,
core->x2, core->y2,
core->undo_tiles,
TRUE);
core->undo_tiles = NULL;
/* push the group end */
undo_push_group_end (gimage);
/* invalidate the drawable--have to do it here, because
* it is not done during the actual painting.
*/
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (drawable));
}
void
gimp_paint_core_cleanup (GimpPaintCore *core)
{
g_return_if_fail (GIMP_IS_PAINT_CORE (core));
if (core->undo_tiles)
{
tile_manager_destroy (core->undo_tiles);
core->undo_tiles = NULL;
}
if (core->canvas_tiles)
{
tile_manager_destroy (core->canvas_tiles);
core->canvas_tiles = NULL;
}
if (core->orig_buf)
{
temp_buf_free (core->orig_buf);
core->orig_buf = NULL;
}
if (core->canvas_buf)
{
temp_buf_free (core->canvas_buf);
core->canvas_buf = NULL;
}
}
/* protected functions */
void
gimp_paint_core_get_color_from_gradient (GimpPaintCore *core,
......@@ -572,29 +622,22 @@ gimp_paint_core_get_color_from_gradient (GimpPaintCore *core,
GimpRGB *color,
GradientPaintMode mode)
{
gdouble distance; /* distance in current brush stroke */
gdouble y;
gdouble pos;
distance = core->pixel_dist;
y = (gdouble) distance / gradient_length;
pos = (gdouble) core->pixel_dist / gradient_length;
/* for the once modes, set y close to 1.0 after the first chunk */
if ((mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && y >= 1.0)
y = 0.9999999;
/* for the once modes, set pos close to 1.0 after the first chunk */
if ((mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && pos >= 1.0)
pos = 0.9999999;
if ((((gint) y & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
y = 1.0 - (y - (gint) y);
if ((((gint) pos & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
pos = 1.0 - (pos - (gint) pos);
else
y = y - (gint) y;
pos = pos - (gint) pos;
gimp_gradient_get_color_at (gradient, y, color);
gimp_gradient_get_color_at (gradient, pos, color);
}
/************************/
/* Painting functions */
/************************/
TempBuf *
gimp_paint_core_get_paint_area (GimpPaintCore *core,
GimpDrawable *drawable,
......
......@@ -44,16 +44,18 @@ typedef enum /*< pdb-skip >*/
typedef enum /*< pdb-skip >*/
{
CORE_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
* if the brush changes while
* painting.
*/
CORE_TRACES_ON_WINDOW /* Set for tools that perform temporary
* rendering directly to the window. These
* require sequencing with gdisplay_flush()
* routines. See clone.c for example.
*/
/* Set for tools that don't mind if
* the brush changes while painting.
*/
CORE_HANDLES_CHANGING_BRUSH = 0x1 << 0,
/* Set for tools that perform
* temporary rendering directly to the
* window. These require sequencing with
* gdisplay_flush() routines.
* See gimpclone.c for example.
*/
CORE_TRACES_ON_WINDOW = 0x1 << 1
} GimpPaintCoreFlags;
......@@ -71,18 +73,19 @@ struct _GimpPaintCore
{
GimpObject parent_instance;
gint ID; /* unique instance ID */
gint ID; /* unique instance ID */
GimpCoords start_coords; /* starting coords */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
GimpCoords start_coords; /* starting coords (for undo only) */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
gint x1, y1; /* image space coords */
gint x2, y2; /* image space coords */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
gint x1, y1; /* undo extents in image coords */
gint x2, y2; /* undo extents in image coords */
GimpBrush *brush; /* current brush */
......@@ -145,30 +148,35 @@ struct _GimpPaintCoreUndo
};
GType gimp_paint_core_get_type (void) G_GNUC_CONST;
GType gimp_paint_core_get_type (void) G_GNUC_CONST;
void gimp_paint_core_paint (GimpPaintCore *core,
GimpDrawable *drawable,
PaintOptions *options,
GimpPaintCoreState state);
gboolean gimp_paint_core_start (GimpPaintCore *core,
GimpDrawable *drawable,
GimpCoords *coords);
void gimp_paint_core_finish (GimpPaintCore *core,
GimpDrawable *drawable);
void gimp_paint_core_cleanup (GimpPaintCore *core);
void gimp_paint_core_constrain (GimpPaintCore *core);
void gimp_paint_core_interpolate (GimpPaintCore *core,
GimpDrawable *drawable,
PaintOptions *paint_options);
void gimp_paint_core_paint (GimpPaintCore *core,
GimpDrawable *drawable,
PaintOptions *options,
GimpPaintCoreState state);