switchin() and switchout() Magic functions now used.

Documented new switchin() and switchout() functions.
This commit is contained in:
William Kendrick 2008-07-08 01:54:00 +00:00
parent b4ed444f0f
commit 2e61076718
4 changed files with 183 additions and 37 deletions

View file

@ -1,14 +1,14 @@
Creating Tux Paint Magic Tool Plugins Creating Tux Paint Magic Tool Plugins
Copyright 2007-2007 by Bill Kendrick and others Copyright 2007-2008 by Bill Kendrick and others
New Breed Software New Breed Software
bill@newbreedsoftware.com bill@newbreedsoftware.com
http://www.tuxpaint.org/ http://www.tuxpaint.org/
July 5, 2007 - November 21, 2007 July 5, 2007 - July 7, 2008
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Overview Overview
@ -22,50 +22,39 @@ Overview
graphics tools, such as The GIMP, should be familiar with this plugin graphics tools, such as The GIMP, should be familiar with this plugin
concept.) concept.)
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Table of Contents Table of Contents
* Prequisites * Prequisites
* Interfaces * Interfaces
* 'Magic' tool plugin functions * 'Magic' tool plugin functions
* Common arguments to plugin functions * Common arguments to plugin functions
* Required Plugin Functions * Required Plugin Functions
* Plugin "housekeeping" functions * Plugin "housekeeping" functions
* Plugin event functions * Plugin event functions
* Tux Paint Functions and Data * Tux Paint Functions and Data
* Pixel Manipulations * Pixel Manipulations
* Helper Functions * Helper Functions
* Informational * Informational
* Tux Paint System Calls * Tux Paint System Calls
* Color Conversions * Color Conversions
* Helper Macros in "tp_magic_api.h" * Helper Macros in "tp_magic_api.h"
* Constant Definitions in "tp_magic_api.h" * Constant Definitions in "tp_magic_api.h"
* Compiling * Compiling
* Linux and other Unix-like Platforms * Linux and other Unix-like Platforms
* Windows * Windows
* Mac OS X * Mac OS X
* Installing * Installing
* Linux and other Unix-like Platforms * Linux and other Unix-like Platforms
* Windows * Windows
* Mac OS X * Mac OS X
* Creating plugins with multiple effects * Creating plugins with multiple effects
* Example Code * Example Code
* Getting Help * Getting Help
* Glossary * Glossary
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Prerequisites Prerequisites
@ -76,7 +65,7 @@ Prerequisites
Familiarity with the SDL API is highly recommended, but some basic SDL Familiarity with the SDL API is highly recommended, but some basic SDL
concepts will be covered in this document. concepts will be covered in this document.
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Interfaces Interfaces
@ -101,7 +90,7 @@ Interfaces
header files) for building a plugin. (See "Compiling", below.) header files) for building a plugin. (See "Compiling", below.)
The C header file and command-line tool mentioned above are included The C header file and command-line tool mentioned above are included
with Tux Paint -- or in some cases, as part of a "Tux Paint 'Magic' Tool with Tux Paint - or in some cases, as part of a "Tux Paint 'Magic' Tool
Plugin Development package". Plugin Development package".
'Magic' tool plugin functions 'Magic' tool plugin functions
@ -117,7 +106,6 @@ Interfaces
Here is a description of arguments that many of your plugin's Here is a description of arguments that many of your plugin's
functions will need to accept. functions will need to accept.
* magic_api * api * magic_api * api
Pointer to a C structure containing pointers to Tux Paint Pointer to a C structure containing pointers to Tux Paint
functions and other data that the plugin can (and sometimes functions and other data that the plugin can (and sometimes
@ -258,6 +246,40 @@ Interfaces
Plugin event functions: Plugin event functions:
* void switchin(magic_api * api, int which,
SDL_Surface * snapshot, SDL_Surface * canvas)
void switchout(magic_api * api, int which,
SDL_Surface * snapshot, SDL_Surface * canvas)
switchin() is called whenever one of the plugin's Magic tools
becomes active, and switchout() is called whenever one becomes
inactive. This can be because the user just clicked a specific
Magic tool (the current one is switched-out, and a new one is
switched-in).
It can also happen when user leaves/returns from the selection
of "Magic" tools when doing some other activity (i.e., using a
different tool, such as "Text" or "Brush", activating a
momentary tool, such as "Undo" and "Redo", or returning from a
dialog - possibly with a new picture when it switches back -
such as "Open", "New" or "Quit"). In this case, the same Magic
tool is first 'switched-out', and then 'switched-back-in',
usually moments later.
These functions allow users to interact in complicated was with
Magic tools (for example, a tool that lets the user draw
multiple freehand strokes, and then uses that as input such as
handwriting - normally, the user could click somewhere in the
canvas to tell the Magic tool they are 'finished', but if they
switch to another tool, the Magic tool may want to undo any
temporary changes to the canvas).
These functions could also be used to streamline certain
effects; a behind-the-scenes copy of the entire canvas could be
altered in some way when the user first switches to the canvas,
and then pieces of that copy could be drawn on the canvas when
they draw with the Magic tool.
Note: Added to Tux Paint 0.9.21; Magic API version '0x00000002'
* void set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 g) * void set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 g)
Tux Paint will call this function to inform the plugin of the Tux Paint will call this function to inform the plugin of the
RGB values of the currently-selected color in Tux Paint's RGB values of the currently-selected color in Tux Paint's
@ -468,8 +490,7 @@ Interfaces
This function notifies Tux Paint of special events. Various This function notifies Tux Paint of special events. Various
values defined in "tp_magic_api.h" can be 'or'ed together (using values defined in "tp_magic_api.h" can be 'or'ed together (using
C's boolean 'or': "|") and sent to this function. C's boolean 'or': "|") and sent to this function.
* SPECIAL_FLIP - The contents of the canvas has been flipped
* SPECIAL_FLIP -- The contents of the canvas has been flipped
vertically. vertically.
If a 'Starter' image was used as the basis of this image, If a 'Starter' image was used as the basis of this image,
@ -479,7 +500,7 @@ Interfaces
(or unflipped) should be recorded on disk when the current (or unflipped) should be recorded on disk when the current
drawing is saved. drawing is saved.
* SPECIAL_MIRROR -- Similar to SPECIAL_FLIP, but for magic * SPECIAL_MIRROR - Similar to SPECIAL_FLIP, but for magic
tools that mirror the contents of the canvas horizontally. tools that mirror the contents of the canvas horizontally.
Color Conversions Color Conversions
@ -559,7 +580,7 @@ Interfaces
These are flags for Tux Paint's "special_notify()" helper These are flags for Tux Paint's "special_notify()" helper
function. They are described above. function. They are described above.
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Compiling Compiling
@ -570,9 +591,9 @@ Compiling
source code. source code.
Use the "tp-magic-config --cflags" command, supplied as part of Use the "tp-magic-config --cflags" command, supplied as part of
Tux Paint -- or in some cases, as part of a "Tux Paint 'Magic' Tool Tux Paint - or in some cases, as part of a "Tux Paint 'Magic' Tool
Plugin Development package" -- to provide additional command-line Plugin Development package" - to provide additional command-line flags
flags to your C compiler that will help it build your plugin. to your C compiler that will help it build your plugin.
Command-Line Example Command-Line Example
@ -658,15 +679,15 @@ Compiling
TBD TBD
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Installing Installing
Linux and other Unix-like Platforms Linux and other Unix-like Platforms
Use the "tp-magic-config" command-line tool, supplied as part of Use the "tp-magic-config" command-line tool, supplied as part of
Tux Paint -- or in some cases, as part of a "Tux Paint 'Magic' Tool Tux Paint - or in some cases, as part of a "Tux Paint 'Magic' Tool
Plugin Development package" -- to determine where your plugins' files Plugin Development package" - to determine where your plugins' files
should go. should go.
Shared Object Shared Object
@ -803,7 +824,7 @@ Installing
TBD TBD
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Creating plugins with multiple effects Creating plugins with multiple effects
@ -842,7 +863,7 @@ Creating plugins with multiple effects
{ {
/* Becomes, for example, /* Becomes, for example,
"/usr/share/tuxpaint/sounds/magic/one.ogg" */ "/usr/share/tuxpaint/sounds/magic/one.ogg" */
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", snprintf(fname, sizeof(fname), "%s/sounds/magic/%s",
api->data_prefix, my_plugin_snd_filenames[i]; api->data_prefix, my_plugin_snd_filenames[i];
@ -865,14 +886,14 @@ Creating plugins with multiple effects
an effect with little effort. ("NUM_TOOLS" will simply be '1', your an effect with little effort. ("NUM_TOOLS" will simply be '1', your
arrays will be of length '1', etc.) arrays will be of length '1', etc.)
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Example Code Example Code
The C source file "tp_magic_example.c" contains a complete example of a The C source file "tp_magic_example.c" contains a complete example of a
plugin with multiple simple effects. plugin with multiple simple effects.
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Getting Help Getting Help
@ -884,7 +905,7 @@ Getting Help
"tuxpaint-devel" and "tuxpaint-users" mailing lists: "tuxpaint-devel" and "tuxpaint-users" mailing lists:
http://www.tuxpaint.org/lists/. http://www.tuxpaint.org/lists/.
-------------------------------------------------------------------------- ----------------------------------------------------------------------
Glossary Glossary

View file

@ -9,13 +9,13 @@ alink="#FF00FF">
<center> <center>
<h1>Creating Tux Paint Magic Tool Plugins</h1> <h1>Creating Tux Paint Magic Tool Plugins</h1>
<p>Copyright 2007-2007 by Bill Kendrick and others<br> <p>Copyright 2007-2008 by Bill Kendrick and others<br>
New Breed Software</p> New Breed Software</p>
<p><a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a><br> <p><a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a><br>
<a href="http://www.tuxpaint.org/">http://www.tuxpaint.org/</a></p> <a href="http://www.tuxpaint.org/">http://www.tuxpaint.org/</a></p>
<p>July 5, 2007 - November 21, 2007</p> <p>July 5, 2007 - July 7, 2008</p>
</center> </center>
<hr size=2 noshade> <hr size=2 noshade>
@ -319,6 +319,45 @@ then the names of your functions must begin with "<code><b>zoom_</b></code>"
<h5><a name="eventfuncs">Plugin event functions:</a></h5> <h5><a name="eventfuncs">Plugin event functions:</a></h5>
<ul> <ul>
<li><code><b>void switchin(magic_api&nbsp;*&nbsp;api,
int&nbsp;which,
SDL_Surface&nbsp;*&nbsp;snapshot, SDL_Surface&nbsp;*&nbsp;canvas)
</b></code><br>
<code><b>void switchout(magic_api&nbsp;*&nbsp;api,
int&nbsp;which,
SDL_Surface&nbsp;*&nbsp;snapshot, SDL_Surface&nbsp;*&nbsp;canvas)
</b></code><br>
<code>switchin()</code> is called whenever one of the plugin's Magic
tools becomes active, and <code>switchout()</code> is called whenever
one becomes inactive. This can be because the user just clicked a
specific Magic tool (the current one is switched-out, and a new one
is switched-in).<br>
<br>
It can also happen when user leaves/returns
from the selection of "Magic" tools when doing some other activity
(i.e., using a different tool, such as "Text" or "Brush", activating
a momentary tool, such as "Undo" and "Redo", or returning from a
dialog &mdash; possibly with a new picture when it switches back
&mdash; such as "Open", "New" or "Quit"). In this case, the same
Magic tool is first 'switched-out', and then 'switched-back-in', usually
moments later.<br>
<br>
These functions allow users to interact in complicated was with Magic
tools (for example, a tool that lets the user draw <i>multiple</i>
freehand strokes, and then uses that as input such as handwriting &mdash;
normally, the user could click somewhere in the canvas to tell the
Magic tool they are 'finished', but if they switch to another tool, the
Magic tool may want to undo any temporary changes to the canvas).<br>
<br>
These functions could also be used to streamline certain effects;
a behind-the-scenes copy of the entire canvas could be altered in some
way when the user first switches to the canvas, and then pieces of that
copy could be drawn on the canvas when they draw with the Magic tool.
<br>
<i>Note: Added to Tux&nbsp;Paint 0.9.21; Magic API version
'0x00000002'</i><br>
<br>
<li><code><b>void set_color(magic_api&nbsp;*&nbsp;api, <li><code><b>void set_color(magic_api&nbsp;*&nbsp;api,
Uint8&nbsp;r, Uint8&nbsp;g, Uint8&nbsp;g) Uint8&nbsp;r, Uint8&nbsp;g, Uint8&nbsp;g)
</b></code><br> </b></code><br>

View file

@ -1,6 +1,7 @@
/* tp_magic_example.c /* tp_magic_example.c
An example of a "Magic" tool plugin for Tux Paint An example of a "Magic" tool plugin for Tux Paint
Last modified: 2008.07.07
*/ */
@ -481,3 +482,34 @@ void example_line_callback(void * ptr, int which,
} }
} }
// Switch-In event
//
// This happens whenever a Magic tool is enabled, either because the
// user just selected it, or they just came back to "Magic" after using
// another tool (e.g., Brush or Text), and this was the most-recently
// selected Magic tool. (This also applies to momentary tools, like
// Undo and Redo, and image-changing tools such as New and Open.)
//
// Our example doesn't do anything when we switch to, or away from, our
// Magic tools, so we just do nothing here.
void example_switchin(magic_api * api, int which, SDL_Surface * canvas)
{
}
// Switch-Out event
//
// This happens whenever a Magic tool is disabled, either because the
// user selected a different Magic tool, or they selected a completely
// different tool (e.g., Brush or Text).
// (This also applies to momentary tools, like Undo and Redo, and
// image-changing tools such as New and Open, in which case the
// switchin() function will be called moments later.)
//
// Our example doesn't do anything when we switch to, or away from, our
// Magic tools, so we just do nothing here.
void example_switchout(magic_api * api, int which, SDL_Surface * canvas)
{
}

View file

@ -1550,6 +1550,9 @@ SDL_Surface * magic_scale(SDL_Surface * surf, int w, int h, int aspect);
void reset_touched(void); void reset_touched(void);
Uint8 magic_touched(int x, int y); Uint8 magic_touched(int x, int y);
void magic_switchin(SDL_Surface * last);
void magic_switchout(SDL_Surface * last);
#ifdef DEBUG #ifdef DEBUG
static char *debug_gettext(const char *str); static char *debug_gettext(const char *str);
static int charsize(Uint16 c); static int charsize(Uint16 c);
@ -1953,7 +1956,9 @@ static void mainloop(void)
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
magic_switchout(canvas);
done = do_quit(cur_tool); done = do_quit(cur_tool);
magic_switchin(canvas);
} }
else if (event.type == SDL_ACTIVEEVENT) else if (event.type == SDL_ACTIVEEVENT)
{ {
@ -1974,7 +1979,9 @@ static void mainloop(void)
if (key == SDLK_ESCAPE && !disable_quit) if (key == SDLK_ESCAPE && !disable_quit)
{ {
magic_switchout(canvas);
done = do_quit(cur_tool); done = do_quit(cur_tool);
magic_switchin(canvas);
} }
else if (key == SDLK_s && (mod & KMOD_ALT)) else if (key == SDLK_s && (mod & KMOD_ALT))
{ {
@ -2000,18 +2007,24 @@ static void mainloop(void)
else if (key == SDLK_ESCAPE && else if (key == SDLK_ESCAPE &&
(mod & KMOD_SHIFT) && (mod & KMOD_CTRL)) (mod & KMOD_SHIFT) && (mod & KMOD_CTRL))
{ {
magic_switchout(canvas);
done = do_quit(cur_tool); done = do_quit(cur_tool);
magic_switchin(canvas);
} }
#ifdef WIN32 #ifdef WIN32
else if (key == SDLK_F4 && (mod & KMOD_ALT)) else if (key == SDLK_F4 && (mod & KMOD_ALT))
{ {
magic_switchout(canvas);
done = do_quit(cur_tool); done = do_quit(cur_tool);
magic_switchin(canvas);
} }
#endif #endif
else if (key == SDLK_z && (mod & KMOD_CTRL) && !noshortcuts) else if (key == SDLK_z && (mod & KMOD_CTRL) && !noshortcuts)
{ {
/* Ctrl-Z - Undo */ /* Ctrl-Z - Undo */
magic_switchout(canvas);
if (tool_avail[TOOL_UNDO]) if (tool_avail[TOOL_UNDO])
{ {
hide_blinking_cursor(); hide_blinking_cursor();
@ -2024,11 +2037,15 @@ static void mainloop(void)
update_screen_rect(&r_tools); update_screen_rect(&r_tools);
shape_tool_mode = SHAPE_TOOL_MODE_DONE; shape_tool_mode = SHAPE_TOOL_MODE_DONE;
} }
magic_switchin(canvas);
} }
else if (key == SDLK_r && (mod & KMOD_CTRL) && !noshortcuts) else if (key == SDLK_r && (mod & KMOD_CTRL) && !noshortcuts)
{ {
/* Ctrl-R - Redo */ /* Ctrl-R - Redo */
magic_switchout(canvas);
if (tool_avail[TOOL_REDO]) if (tool_avail[TOOL_REDO])
{ {
hide_blinking_cursor(); hide_blinking_cursor();
@ -2036,11 +2053,15 @@ static void mainloop(void)
update_screen_rect(&r_tools); update_screen_rect(&r_tools);
shape_tool_mode = SHAPE_TOOL_MODE_DONE; shape_tool_mode = SHAPE_TOOL_MODE_DONE;
} }
magic_switchin(canvas);
} }
else if (key == SDLK_o && (mod & KMOD_CTRL) && !noshortcuts) else if (key == SDLK_o && (mod & KMOD_CTRL) && !noshortcuts)
{ {
/* Ctrl-O - Open */ /* Ctrl-O - Open */
magic_switchout(canvas);
disable_avail_tools(); disable_avail_tools();
draw_toolbar(); draw_toolbar();
draw_colors(COLORSEL_CLOBBER_WIPE); draw_colors(COLORSEL_CLOBBER_WIPE);
@ -2075,11 +2096,15 @@ static void mainloop(void)
/* FIXME: Make delay configurable: */ /* FIXME: Make delay configurable: */
control_drawtext_timer(1000, tool_tips[cur_tool], 0); control_drawtext_timer(1000, tool_tips[cur_tool], 0);
magic_switchin(canvas);
} }
else if ((key == SDLK_n && (mod & KMOD_CTRL)) && !noshortcuts) else if ((key == SDLK_n && (mod & KMOD_CTRL)) && !noshortcuts)
{ {
/* Ctrl-N - New */ /* Ctrl-N - New */
magic_switchout(canvas);
hide_blinking_cursor(); hide_blinking_cursor();
shape_tool_mode = SHAPE_TOOL_MODE_DONE; shape_tool_mode = SHAPE_TOOL_MODE_DONE;
@ -2114,11 +2139,15 @@ static void mainloop(void)
draw_shapes(); draw_shapes();
else if (cur_tool == TOOL_ERASER) else if (cur_tool == TOOL_ERASER)
draw_erasers(); draw_erasers();
magic_switchin(canvas);
} }
else if (key == SDLK_s && (mod & KMOD_CTRL) && !noshortcuts) else if (key == SDLK_s && (mod & KMOD_CTRL) && !noshortcuts)
{ {
/* Ctrl-S - Save */ /* Ctrl-S - Save */
magic_switchout(canvas);
hide_blinking_cursor(); hide_blinking_cursor();
if (do_save(cur_tool, 0)) if (do_save(cur_tool, 0))
{ {
@ -2131,6 +2160,8 @@ static void mainloop(void)
/* cur_tool = old_tool; */ /* cur_tool = old_tool; */
draw_toolbar(); draw_toolbar();
update_screen_rect(&r_tools); update_screen_rect(&r_tools);
magic_switchin(canvas);
} }
#ifdef __APPLE__ #ifdef __APPLE__
else if (key == SDLK_p && (mod & KMOD_CTRL) && (mod & KMOD_SHIFT) && else if (key == SDLK_p && (mod & KMOD_CTRL) && (mod & KMOD_SHIFT) &&
@ -2339,6 +2370,8 @@ static void mainloop(void)
{ {
/* A tool on the left has been pressed! */ /* A tool on the left has been pressed! */
magic_switchout(canvas);
which = GRIDHIT_GD(r_tools, gd_tools); which = GRIDHIT_GD(r_tools, gd_tools);
if (which < NUM_TOOLS && tool_avail[which] && if (which < NUM_TOOLS && tool_avail[which] &&
@ -2368,7 +2401,6 @@ static void mainloop(void)
} }
} }
old_tool = cur_tool; old_tool = cur_tool;
cur_tool = which; cur_tool = which;
draw_toolbar(); draw_toolbar();
@ -2473,6 +2505,7 @@ static void mainloop(void)
magic_current_snd_ptr = NULL; magic_current_snd_ptr = NULL;
draw_magic(); draw_magic();
draw_colors(magics[cur_magic].colors); draw_colors(magics[cur_magic].colors);
if (magics[cur_magic].colors) if (magics[cur_magic].colors)
magic_funcs[magics[cur_magic].handle_idx].set_color( magic_funcs[magics[cur_magic].handle_idx].set_color(
magic_api_struct, magic_api_struct,
@ -2638,6 +2671,8 @@ static void mainloop(void)
update_screen_rect(&r_toolopt); update_screen_rect(&r_toolopt);
update_screen_rect(&r_ttoolopt); update_screen_rect(&r_ttoolopt);
} }
magic_switchin(canvas);
} }
else if (HIT(r_toolopt) && valid_click(event.button.button)) else if (HIT(r_toolopt) && valid_click(event.button.button))
{ {
@ -3101,6 +3136,8 @@ static void mainloop(void)
} }
else if (cur_tool == TOOL_MAGIC) else if (cur_tool == TOOL_MAGIC)
{ {
magic_switchout(canvas);
if (cur_thing != cur_magic) if (cur_thing != cur_magic)
{ {
cur_magic = cur_thing; cur_magic = cur_thing;
@ -3118,6 +3155,8 @@ static void mainloop(void)
if (do_draw) if (do_draw)
draw_magic(); draw_magic();
magic_switchin(canvas);
} }
/* Update the screen: */ /* Update the screen: */
@ -18765,3 +18804,18 @@ Uint32 magic_getpixel(SDL_Surface * surface, int x, int y)
} }
void magic_switchout(SDL_Surface * last)
{
if (cur_tool == TOOL_MAGIC)
magic_funcs[magics[cur_magic].handle_idx].switchout(magic_api_struct,
magics[cur_magic].idx,
canvas, last);
}
void magic_switchin(SDL_Surface * last)
{
if (cur_tool == TOOL_MAGIC)
magic_funcs[magics[cur_magic].handle_idx].switchin(magic_api_struct,
magics[cur_magic].idx,
canvas, last);
}