Commit dca988f7 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Core/UI separation for the paint tools:

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

	Core/UI separation for the paint tools:

	* configure.in
	* app/Makefile.am
	* app/paint/.cvsignore
	* app/paint/Makefile.am: added new directory for the paint methods
	without GUI and tools around them.

	* app/paint/paint-types.h: typedefs for this module.

	* app/paint/gimppaintcore-kernels.h
	* app/paint/gimppaintcore.[ch]: the general paint logic taken
	from GimpPaintTool.

	* app/paint/gimpairbrush.[ch]
	* app/paint/gimpclone.[ch]
	* app/paint/gimpconvolve.[ch]
	* app/paint/gimpdodgeburn.[ch]
	* app/paint/gimperaser.[ch]
	* app/paint/gimppaintbrush.[ch]
	* app/paint/gimppencil.[ch]
	* app/paint/gimpsmudge.[ch]: subclasses of GimpPaintCore,
	implementing their own paint() methods.  Needs more hacking
	to get the GtkWidget pointers out of the options structs.

	* app/tools/gimppainttool_kernels.h: removed.

	* app/tools/tools-types.h: removed the paint tool enums.

	* app/tools/gimpairbrushtool.[ch]
	* app/tools/gimpclonetool.[ch]
	* app/tools/gimpconvolvetool.[ch]
	* app/tools/gimpdodgeburntool.[ch]
	* app/tools/gimperasertool.[ch]
	* app/tools/gimppaintbrushtool.[ch]
	* app/tools/gimppainttool.[ch]
	* app/tools/gimppenciltool.[ch]
	* app/tools/gimpsmudgetool.[ch]: all paint tools are pure GUI
	things now.  PaintOptions and friends still need to be chopped up
	though...

	* app/undo.c: changed PaintUndo to GimpPaintCoreUndo, some minor
	cleanup.

	* tools/kernelgen.c: changed accordingly.

	* tools/pdbgen/Makefile.am: scan paint/paint-types.h for enums.

	* tools/pdbgen/pdb/paint_tools.pdb: hardcode "success = FALSE" for
	all paint PDB wrappers.  The non-gui stuff is completely broken.
	More commits to come...

	* app/pdb/paint_tools_cmds.c
	* tools/pdbgen/enums.pl: regenerated.
parent dac875d3
2002-02-14 Michael Natterer <mitch@gimp.org>
Core/UI separation for the paint tools:
* configure.in
* app/Makefile.am
* app/paint/.cvsignore
* app/paint/Makefile.am: added new directory for the paint methods
without GUI and tools around them.
* app/paint/paint-types.h: typedefs for this module.
* app/paint/gimppaintcore-kernels.h
* app/paint/gimppaintcore.[ch]: the general paint logic taken
from GimpPaintTool.
* app/paint/gimpairbrush.[ch]
* app/paint/gimpclone.[ch]
* app/paint/gimpconvolve.[ch]
* app/paint/gimpdodgeburn.[ch]
* app/paint/gimperaser.[ch]
* app/paint/gimppaintbrush.[ch]
* app/paint/gimppencil.[ch]
* app/paint/gimpsmudge.[ch]: subclasses of GimpPaintCore,
implementing their own paint() methods. Needs more hacking
to get the GtkWidget pointers out of the options structs.
* app/tools/gimppainttool_kernels.h: removed.
* app/tools/tools-types.h: removed the paint tool enums.
* app/tools/gimpairbrushtool.[ch]
* app/tools/gimpclonetool.[ch]
* app/tools/gimpconvolvetool.[ch]
* app/tools/gimpdodgeburntool.[ch]
* app/tools/gimperasertool.[ch]
* app/tools/gimppaintbrushtool.[ch]
* app/tools/gimppainttool.[ch]
* app/tools/gimppenciltool.[ch]
* app/tools/gimpsmudgetool.[ch]: all paint tools are pure GUI
things now. PaintOptions and friends still need to be chopped up
though...
* app/undo.c: changed PaintUndo to GimpPaintCoreUndo, some minor
cleanup.
* tools/kernelgen.c: changed accordingly.
* tools/pdbgen/Makefile.am: scan paint/paint-types.h for enums.
* tools/pdbgen/pdb/paint_tools.pdb: hardcode "success = FALSE" for
all paint PDB wrappers. The non-gui stuff is completely broken.
More commits to come...
* app/pdb/paint_tools_cmds.c
* tools/pdbgen/enums.pl: regenerated.
2002-02-13 Michael Natterer <mitch@gimp.org>
* app/tools/gimppainttool.[ch]: moved all global variables into
......
......@@ -5,6 +5,7 @@ SUBDIRS = \
base \
core \
config \
paint \
xcf \
file \
pdb \
......@@ -133,6 +134,7 @@ gimp_1_3_LDADD = @STRIP_BEGIN@ \
tools/libapptools.a \
display/libappdisplay.a \
widgets/libappwidgets.a \
paint/libapppaint.a \
core/libappcore.a \
xcf/libappxcf.a \
file/libappfile.a \
......
......@@ -47,6 +47,8 @@
#include "core/gimpparasite.h"
#include "core/gimpparasitelist.h"
#include "paint/gimppaintcore.h"
#include "tools/gimpbycolorselecttool.h"
#include "tools/gimptool.h"
#include "tools/gimpdrawtool.h"
......@@ -1265,48 +1267,50 @@ undo_pop_transform (GimpImage *gimage,
UndoType type,
gpointer tu_ptr)
{
GimpTool *active_tool;
GimpTransformTool *tt;
TransformUndo *tu;
TileManager *temp;
gdouble d;
gint i;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
if (active_tool)
{
GimpTransformTool *tt;
TransformUndo *tu;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
path_transform_do_undo (gimage, tu->path_undo);
path_transform_do_undo (gimage, tu->path_undo);
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID != active_tool->ID)
return TRUE;
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID == active_tool->ID)
{
TileManager *temp;
gdouble d;
gint i;
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
}
}
}
return TRUE;
......@@ -1338,7 +1342,7 @@ undo_push_paint (GimpImage *gimage,
Undo *new;
if ((new = undo_push (gimage,
sizeof (PaintUndo), PAINT_UNDO, FALSE)))
sizeof (GimpPaintCoreUndo), PAINT_UNDO, FALSE)))
{
new->data = pu_ptr;
new->pop_func = undo_pop_paint;
......@@ -1359,28 +1363,30 @@ undo_pop_paint (GimpImage *gimage,
UndoType type,
gpointer pu_ptr)
{
GimpTool *active_tool;
GimpPaintTool *pt;
PaintUndo *pu;
GimpCoords tmp_coords;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
if (active_tool)
{
GimpPaintTool *pt;
GimpPaintCoreUndo *pu;
pt = (GimpPaintTool *) active_tool;
pu = (PaintUndo *) pu_ptr;
pt = (GimpPaintTool *) active_tool;
pu = (GimpPaintCoreUndo *) pu_ptr;
/* only pop if the active tool is the tool that pushed this undo */
if (pu->tool_ID != active_tool->ID)
return TRUE;
/* only pop if the active paint core is the one that pushed this undo */
if (pu->core_ID == pt->core->ID)
{
GimpCoords tmp_coords;
/* swap the paint core information */
tmp_coords = pt->last_coords;
pt->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
/* swap the paint core information */
tmp_coords = pt->core->last_coords;
pt->core->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
}
}
return TRUE;
}
......@@ -1390,9 +1396,9 @@ undo_free_paint (UndoState state,
UndoType type,
gpointer pu_ptr)
{
PaintUndo *pu;
GimpPaintCoreUndo *pu;
pu = (PaintUndo *) pu_ptr;
pu = (GimpPaintCoreUndo *) pu_ptr;
g_free (pu);
}
......
Makefile
Makefile.in
.deps
.libs
*.lo
libapppaint.la
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libapppaint.a
libapppaint_a_SOURCES = @STRIP_BEGIN@ \
gimpairbrush.c \
gimpairbrush.h \
gimpclone.c \
gimpclone.h \
gimpconvolve.c \
gimpconvolve.h \
gimpdodgeburn.c \
gimpdodgeburn.h \
gimperaser.c \
gimperaser.h \
gimppaintcore.c \
gimppaintcore.h \
gimppencil.c \
gimppencil.h \
gimppaintbrush.c \
gimppaintbrush.h \
gimpsmudge.c \
gimpsmudge.h \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-DG_LOG_DOMAIN=\"Gimp-Paint\" \
@GIMP_THREAD_FLAGS@ \
@GIMP_MP_FLAGS@ \
@STRIP_END@
INCLUDES = @STRIP_BEGIN@ \
-I$(top_builddir) \
-I$(top_srcdir) \
-I$(top_builddir)/app \
-I$(top_srcdir)/app \
$(GTK_CFLAGS) \
$(PANGOFT2_CFLAGS) \
-I$(includedir) \
@STRIP_END@
......@@ -21,9 +21,8 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/temp-buf.h"
......@@ -35,258 +34,167 @@
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplay-foreach.h"
#include "gimpairbrush.h"
#include "gimpairbrushtool.h"
#include "paint_options.h"
#include "gimptool.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
/* The maximum amount of pressure that can be exerted */
#define MAX_PRESSURE 0.075
/* Default pressure setting */
#define AIRBRUSH_DEFAULT_RATE 0.0
#define AIRBRUSH_DEFAULT_PRESSURE 10.0
#define AIRBRUSH_DEFAULT_INCREMENTAL FALSE
#define OFF 0
#define ON 1
/* the airbrush structures */
typedef struct _AirbrushTimeout AirbrushTimeout;
struct _AirbrushTimeout
{
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
GimpDrawable *drawable;
};
typedef struct _AirbrushOptions AirbrushOptions;
struct _AirbrushOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
gdouble pressure;
gdouble pressure_d;
GtkObject *pressure_w;
PaintOptions *paint_options;
};
/* local function prototypes */
static void gimp_airbrush_class_init (GimpAirbrushClass *klass);
static void gimp_airbrush_init (GimpAirbrush *airbrush);
static void gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass);
static void gimp_airbrush_tool_init (GimpAirbrushTool *airbrush);
static void gimp_airbrush_finalize (GObject *object);
static void gimp_airbrush_tool_finalize (GObject *object);
static void gimp_airbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental);
static gint airbrush_time_out (gpointer data);
static void gimp_airbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options);
static gboolean gimp_airbrush_timeout (gpointer data);
static GimpToolOptions * airbrush_options_new (GimpToolInfo *tool_info);
static void airbrush_options_reset (GimpToolOptions *tool_options);
static guint timeout_id = 0;
static AirbrushTimeout airbrush_timeout;
/* local variables */
static gint timer; /* timer for successive paint applications */
static gint timer_state = OFF; /* state of airbrush tool */
static AirbrushTimeout airbrush_timeout;
static GimpPaintCoreClass *parent_class = NULL;
static gdouble non_gui_rate;
static gdouble non_gui_pressure;
static gboolean non_gui_incremental;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_airbrush_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_AIRBRUSH_TOOL,
airbrush_options_new,
TRUE,
"gimp:airbrush_tool",
_("Airbrush"),
_("Airbrush with variable pressure"),
N_("/Tools/Paint Tools/Airbrush"), "A",
NULL, "tools/airbrush.html",
GIMP_STOCK_TOOL_AIRBRUSH);
}
GType
gimp_airbrush_tool_get_type (void)
gimp_airbrush_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpAirbrushToolClass),
sizeof (GimpAirbrushClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_airbrush_tool_class_init,
(GClassInitFunc) gimp_airbrush_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpAirbrushTool),
sizeof (GimpAirbrush),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_airbrush_tool_init,
(GInstanceInitFunc) gimp_airbrush_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpAirbrushTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpAirbrush",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass)
gimp_airbrush_class_init (GimpAirbrushClass *klass)
{
GObjectClass *object_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
object_class = G_OBJECT_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_airbrush_tool_finalize;
object_class->finalize = gimp_airbrush_finalize;
paint_tool_class->paint = gimp_airbrush_tool_paint;
paint_core_class->paint = gimp_airbrush_paint;
}
static void
gimp_airbrush_tool_init (GimpAirbrushTool *airbrush)
gimp_airbrush_init (GimpAirbrush *airbrush)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (airbrush);
paint_tool = GIMP_PAINT_TOOL (airbrush);
paint_core = GIMP_PAINT_CORE (airbrush);
tool->tool_cursor = GIMP_AIRBRUSH_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_airbrush_tool_finalize (GObject *object)
gimp_airbrush_finalize (GObject *object)
{
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_airbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
GimpBrush *brush;
if (! drawable)
return;
AirbrushOptions *options;
GimpBrush *brush;
options = (AirbrushOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
options = (AirbrushOptions *) paint_options;
brush =
gimp_context_get_brush (gimp_get_current_context (drawable->gimage->gimp));
switch (state)
switch (paint_state)
{
case INIT_PAINT:
if (timer_state == ON)
if (timeout_id)
{
g_warning ("killing stray timer, please report to lewing@gimp.org");
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
break;
case MOTION_PAINT:
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
gimp_airbrush_tool_motion (paint_tool,
drawable,
pressure_options,
pressure,
incremental);
gimp_airbrush_motion (paint_core,
drawable,
paint_options);
if (rate != 0.0)
if (options->rate != 0.0)
{
gdouble timeout;
airbrush_timeout.paint_tool = paint_tool;
airbrush_timeout.drawable = drawable;
airbrush_timeout.paint_core = paint_core;
airbrush_timeout.drawable = drawable;
airbrush_timeout.paint_options = paint_options;
timeout = (pressure_options->rate ?
(10000 / (rate * 2.0 * paint_tool->cur_coords.pressure)) :
(10000 / rate));
timeout = (paint_options->pressure_options->rate ?
(10000 / (options->rate * 2.0 * paint_core->cur_coords.pressure)) :
(10000 / options->rate));
timer = gtk_timeout_add (timeout, airbrush_time_out, paint_tool);
timer_state = ON;
timeout_id = g_timeout_add (timeout,
gimp_airbrush_timeout,
NULL);
}
break;
case FINISH_PAINT:
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
break;
......@@ -295,50 +203,31 @@ gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
}
}
static gint
airbrush_time_out (gpointer client_data)
static gboolean
gimp_airbrush_timeout (gpointer client_data)
{
GimpTool *tool;
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
tool = GIMP_TOOL (client_data);
options = (AirbrushOptions *) tool->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
gdouble rate;
gimp_airbrush_tool_motion (airbrush_timeout.paint_tool,
airbrush_timeout.drawable,
pressure_options,
pressure,
incremental);
gimp_airbrush_motion (airbrush_timeout.paint_core,
airbrush_timeout.drawable,
airbrush_timeout.paint_options);
gdisplays_flush ();
rate = ((AirbrushOptions *) airbrush_timeout.paint_options)->rate;
/* restart the timer */
if (rate != 0.0)
{
if (pressure_options->rate)
if (airbrush_timeout.paint_options->pressure_options->rate)
{
/* set a new timer */
timer = gtk_timeout_add ((10000 / (rate * 2.0 * airbrush_timeout.paint_tool->cur_coords.pressure)),
airbrush_time_out, NULL);
if (timeout_id)
g_source_remove (timeout_id);
timeout_id = g_timeout_add ((10000 /
(rate * 2.0 *
airbrush_timeout.paint_core->cur_coords.pressure)),
gimp_airbrush_timeout,
NULL);
return FALSE;
}
......@@ -349,42 +238,42 @@ airbrush_time_out (gpointer client_data)
}
static void
gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental)
gimp_airbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
if (!drawable)
return;
PaintApplicationMode paint_appl_mode;
gdouble pressure;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)