gimp/app/tools/gimpiscissorstool.c

2216 lines
71 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
1997-11-24 22:05:25 +00:00
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
1997-11-24 22:05:25 +00:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
1997-11-24 22:05:25 +00:00
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1997-11-24 22:05:25 +00:00
*/
/* This tool is based on a paper from SIGGRAPH '95:
* "Intelligent Scissors for Image Composition", Eric N. Mortensen and
* William A. Barrett, Brigham Young University.
*
* thanks to Professor D. Forsyth for prompting us to implement this tool. */
app/tools/gimptoolcontrol.[ch] resurrected the motion hints and cursor * app/tools/gimptoolcontrol.[ch] * libgimptool/gimptool.c: resurrected the motion hints and cursor changing code. app/tools/gimpairbrushtool.c app/tools/gimpbezierselecttool.c app/tools/gimpblendtool.c app/tools/gimpbucketfilltool.c app/tools/gimpbycolorselecttool.c app/tools/gimpclonetool.c app/tools/gimpcolorbalancetool.c app/tools/gimpcolorpickertool.c app/tools/gimpconvolvetool.c app/tools/gimpcroptool.c app/tools/gimpcurvestool.c app/tools/gimpdodgeburntool.c app/tools/gimpeditselectiontool.c app/tools/gimpellipseselecttool.c app/tools/gimperasertool.c app/tools/gimpfliptool.c app/tools/gimpfuzzyselecttool.c app/tools/gimphistogramtool.c app/tools/gimphuesaturationtool.c app/tools/gimpimagemaptool.c app/tools/gimpinktool.c app/tools/gimpiscissorstool.c app/tools/gimplevelstool.c app/tools/gimpmagnifytool.c app/tools/gimpmeasuretool.c app/tools/gimpmovetool.c app/tools/gimppaintbrushtool.c app/tools/gimppainttool.c app/tools/gimppathtool.c app/tools/gimppenciltool.c app/tools/gimpperspectivetool.c app/tools/gimprectselecttool.c app/tools/gimprotatetool.c app/tools/gimpscaletool.c app/tools/gimpselectiontool.c app/tools/gimpsheartool.c app/tools/gimpsmudgetool.c app/tools/gimptexttool.c app/tools/gimptransformtool.c app/tools/gimpvectortool.c: set the motion mode; fix a few parameters * app/tools/gimpinktool.c (gimp_ink_tool_button_press): uncommented some code I had temporarily commented out and didn't uncomment before committing * libgimptool/gimptoolcontrol.h * app/tools/gimptoolcontrol-displayshell.[ch]: merged with gimptoolcontrol.[ch]. The distinction was fairly arbitrary. * plug-ins/tools/gimptoolcontrol.c: added some stubs * app/tools/Makefile.am * app/tools/tool_manager.c * app/display/gimpdisplayshell-callbacks.c: changed accordingly * libgimp/gimpimage_pdb.c: applied a patch from Pippen to correct documentation on the undo operations
2002-04-21 07:31:12 +00:00
/* Personal note: Dr. Barrett, one of the authors of the paper written above
* is not only one of the most brilliant people I have ever met, he is an
* incredible professor who genuinely cares about his students and wants them
* to learn as much as they can about the topic.
*
* I didn't even notice I was taking a class from the person who wrote the
* paper until halfway through the semester.
* -- Rockwalrus
*/
/* The history of this implementation is lonog and varied. It was
2013-01-27 17:52:38 +02:00
* originally done by Spencer and Peter, and worked fine in the 0.54
* (motif only) release of GIMP. Later revisions (0.99.something
* until about 1.1.4) completely changed the algorithm used, until it
* bore little resemblance to the one described in the paper above.
* The 0.54 version of the algorithm was then forwards ported to 1.1.4
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 15:22:01 +00:00
* by Austin Donnelly.
*/
1997-11-24 22:05:25 +00:00
/* Livewire boundary implementation done by Laramie Leavitt */
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc 1999-09-01 Tor Lillqvist <tml@iki.fi> * app/appenv.h * libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc from app/appenv.h here, so plug-ins can use them, too. Remove some commented-out old stuff in appenv.h. * libgimp/gimp.h: Include gimpmath.h. * libgimp/gimp.c (gimp_main): Win32: Don't install signal handlers, we can't do anything useful in the handler ourselves anyway (it would be nice to print out a backtrace, but that seems pretty hard to do, even if not impossible). Let Windows inform the user about the crash. If the plug-in was compiled with MSVC, and the user also has it, she is offered a chance to start the debugger automatically anyway. * app/*several*.c: Include gimpmath.h for G_PI etc. Don't include <math.h>, as gimpmath.h includes it. * plug-ins/*/*many*.c: Include config.h. Don't include <math.h>. Remove all the duplicated definitions of G_PI and rint(). Use RINT() instead of rint(). * app/app_procs.[ch]: app_exit() takes a gboolean. * app/batch.c * app/commands.c * app/interface.c: Call app_exit() with FALSE or TRUE. * app/main.c (on_error): Call gimp_fatal_error. (main): Don't install any signal handler on Win32 here, either. * app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format the message and call MessageBox with it. g_on_error_query doesn't do anything useful on Win32, and printf'ing a message to stdout or stderr doesn't do anything, either, in a windowing application.
1999-09-01 20:30:56 +00:00
#include "config.h"
1997-11-24 22:05:25 +00:00
#include <stdlib.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
2001-08-05 16:08:19 +00:00
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "gegl/gimp-gegl-utils.h"
#include "core/gimpchannel.h"
Treat changes to the selection like changes to any other drawable: 2003-10-06 Michael Natterer <mitch@gimp.org> Treat changes to the selection like changes to any other drawable: * app/core/gimpchannel.c * app/core/gimpchannel-combine.c: call gimp_drawable_update() after changing the channel. * app/core/gimpimage.[ch]: added struct GimpImageFlushAccumulator with one member "gboolean mask_changed". Connect to "update" of the selection and set accum.mask_changed to TRUE in the callback. Added default implementation for GimpImage::flush() and emit "mask_changed" there. Unrelated: * app/core/gimpimage.h: removed GimpGuide struct... * app/core/gimpimage-guides.h: ...and added it here. * app/core/gimpimage-undo-push.c (undo_pop_mask) (undo_pop_channel_mod): don't distinguish between selection and non-selection channels and just call gimp_drawable_update(). * app/core/gimpundo.h * app/core/gimpimage-undo.c: removed "gboolean mask_changed" from the GimpUndoAccumulator struct since we don't have to care about that signal explicitly any more. * app/display/gimpdisplay-foreach.[ch]: removed gimp_displays_flush(). * tools/pdbgen/pdb/display.pdb (displays_flush_invoker): call gimp_image_flush() on all images so the flush accumulator is honored. This generalization enables the removal of more special purpose code which was needed to treat the selection different: * app/core/gimpimage-mask-select.[ch]: removed... * app/core/gimpchannel-select.[ch]: ...and added under a new name because it's not selection specific any more. * app/core/gimpimage-mask.[ch]: removed... * app/core/gimpselection.[ch]: ...added the two remaining functions here. Removed all calls to gimp_image_mask_changed(). * app/core/Makefile.am * app/core/gimp-edit.c * app/core/gimpdrawable-transform.c * app/core/gimpimage-scale.c * app/core/gimpimage-snap.c * app/display/gimpdisplayshell.c * app/gui/channels-commands.c * app/gui/layers-commands.c * app/gui/select-commands.c * app/gui/vectors-commands.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimpiscissorstool.c * app/tools/gimprectselecttool.c * app/tools/gimptransformtool.c * app/widgets/gimpchanneltreeview.c * app/widgets/gimpselectioneditor.c * app/widgets/gimpvectorstreeview.c * app/xcf/xcf-save.c * tools/pdbgen/pdb/paths.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/selection_tools.pdb: changed accordingly. * app/core/gimpdrawable-bucket-fill.c * app/core/gimpimage-colormap.c * app/core/gimplayer-floating-sel.c * app/core/gimplayer.c * app/gui/image-menu.c * app/paint/gimppaintcore.c * app/tools/gimpcroptool.c * app/tools/gimpinkoptions.c * app/tools/gimpvectortool.c: removed useless and/or obsolete #includes. * app/pdb/display_cmds.c * app/pdb/paths_cmds.c * app/pdb/selection_cmds.c * app/pdb/selection_tools_cmds.c: regenerated.
2003-10-06 12:17:11 +00:00
#include "core/gimpchannel-select.h"
#include "core/gimpimage.h"
#include "core/gimppickable.h"
#include "core/gimpscanconvert.h"
#include "core/gimptempbuf.h"
#include "core/gimptoolinfo.h"
1997-11-24 22:05:25 +00:00
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpwidgets-utils.h"
#include "display/gimpcanvasitem.h"
#include "display/gimpdisplay.h"
#include "gimpiscissorsoptions.h"
#include "gimpiscissorstool.h"
#include "gimptilehandleriscissors.h"
#include "gimptoolcontrol.h"
Makefile.am configure.in added the new library below. 2001-01-24 Michael Natterer <mitch@gimp.org> * Makefile.am * configure.in * gimptool.in: added the new library below. * libgimpwidgets/Makefile.am * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.[ch] * libgimpwidgets/gimpcolorbutton.[ch] * libgimpwidgets/gimpdialog.[ch] * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimphelpui.[ch] * libgimpwidgets/gimppatheditor.[ch] * libgimpwidgets/gimppixmap.[ch] * libgimpwidgets/gimpquerybox.[ch] * libgimpwidgets/gimpsizeentry.[ch] * libgimpwidgets/gimpunitmenu.[ch] * libgimpwidgets/gimpwidgets.[ch] * libgimpwidgets/gimpwidgets.def * libgimpwidgets/gimpwidgetstypes.h: new shared library. Currently there are some ugly dependencies into libgimp. These will be removed and go to a "libgimpglue" library which will be a library for functions which share a common interface between plug-ins and the app but have different implementations. Include "libgimp/gimpunit.h" from "libgimpwidgets/gimpwidgetstypes.h" to simulate this upcoming separation. * libgimp/Makefile.am * libgimp/gimpchainbutton.[ch] * libgimp/gimpcolorarea.[ch] * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimpfileselection.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimppixmap.[ch] * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: removed from here. * libgimp/gimpui.h * libgimp/gimpuitypes.h * libgimp/makefile.mingw.in * libgimp/makefile.msc: changed accordingly. * app/[all ui files] * app/pdb/palette_cmds.c * app/pdb/tools_cmds.c * tools/pdbgen/pdb/palette.pdb * tools/pdbgen/pdb/tools.pdb: #include "libgimpwidgets/gimpwidgets.h" and removed useless includes. * app/apptypes.h: #include "libgimpwidgets/gimpwidgetstypes.h" * app/Makefile.am * plug-ins/[all makefiles which link against libgimpui]: link against libgimpwidgets.la * po-libgimp/POTFILES.in: changed file locations.
2001-01-24 22:36:18 +00:00
#include "gimp-intl.h"
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 15:22:01 +00:00
1997-11-24 22:05:25 +00:00
/* defines */
#define GRADIENT_SEARCH 32 /* how far to look when snapping to an edge */
#define EXTEND_BY 0.2 /* proportion to expand cost map by */
#define FIXED 5 /* additional fixed size to expand cost map */
1997-11-24 22:05:25 +00:00
#define COST_WIDTH 2 /* number of bytes for each pixel in cost map */
/* weight to give between gradient (_G) and direction (_D) */
#define OMEGA_D 0.2
#define OMEGA_G 0.8
1997-11-24 22:05:25 +00:00
/* sentinel to mark seed point in ?cost? map */
#define SEED_POINT 9
1997-11-24 22:05:25 +00:00
/* Functional defines */
#define PIXEL_COST(x) ((x) >> 8)
#define PIXEL_DIR(x) ((x) & 0x000000ff)
1997-11-24 22:05:25 +00:00
struct _ISegment
{
gint x1, y1;
gint x2, y2;
GPtrArray *points;
};
struct _ICurve
{
GQueue *segments;
gboolean first_point;
gboolean closed;
};
/* local function prototypes */
static void gimp_iscissors_tool_finalize (GObject *object);
static void gimp_iscissors_tool_control (GimpTool *tool,
GimpToolAction action,
GimpDisplay *display);
static void gimp_iscissors_tool_button_press (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonPressType press_type,
GimpDisplay *display);
static void gimp_iscissors_tool_button_release (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonReleaseType release_type,
GimpDisplay *display);
static void gimp_iscissors_tool_motion (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *display);
static void gimp_iscissors_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display);
static void gimp_iscissors_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display);
static const gchar * gimp_iscissors_tool_can_undo (GimpTool *tool,
GimpDisplay *display);
static const gchar * gimp_iscissors_tool_can_redo (GimpTool *tool,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_undo (GimpTool *tool,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_redo (GimpTool *tool,
GimpDisplay *display);
static void gimp_iscissors_tool_draw (GimpDrawTool *draw_tool);
static void gimp_iscissors_tool_push_undo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static void gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static void iscissors_convert (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static GeglBuffer * gradient_map_new (GimpPickable *pickable);
static void find_optimal_path (GeglBuffer *gradient_map,
2012-04-08 20:25:49 +02:00
GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys);
static void find_max_gradient (GimpIscissorsTool *iscissors,
GimpPickable *pickable,
gint *x,
gint *y);
static void calculate_segment (GimpIscissorsTool *iscissors,
ISegment *segment);
static GimpCanvasItem * iscissors_draw_segment (GimpDrawTool *draw_tool,
ISegment *segment);
static gint mouse_over_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static gboolean clicked_on_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static GList * mouse_over_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static gboolean clicked_on_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static GPtrArray * plot_pixels (GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye);
static ISegment * isegment_new (gint x1,
gint y1,
gint x2,
gint y2);
static ISegment * isegment_copy (ISegment *segment);
static void isegment_free (ISegment *segment);
static ICurve * icurve_new (void);
static ICurve * icurve_copy (ICurve *curve);
static void icurve_clear (ICurve *curve);
static void icurve_free (ICurve *curve);
static ISegment * icurve_append_segment (ICurve *curve,
gint x1,
gint y1,
gint x2,
gint y2);
static ISegment * icurve_insert_segment (ICurve *curve,
GList *sibling,
gint x1,
gint y1,
gint x2,
gint y2);
static void icurve_delete_segment (ICurve *curve,
ISegment *segment);
static void icurve_close (ICurve *curve);
static GimpScanConvert *
icurve_create_scan_convert (ICurve *curve);
1997-11-24 22:05:25 +00:00
/* static variables */
/* where to move on a given link direction */
static const gint move[8][2] =
{
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
{ 1, 0 },
{ 0, 1 },
{ -1, 1 },
{ 1, 1 },
{ -1, 0 },
{ 0, -1 },
{ 1, -1 },
{ -1, -1 },
};
/* IE:
* '---+---+---`
* | 7 | 5 | 6 |
* +---+---+---+
* | 4 | | 0 |
* +---+---+---+
* | 2 | 1 | 3 |
* `---+---+---'
*/
1997-11-24 22:05:25 +00:00
static gfloat distance_weights[GRADIENT_SEARCH * GRADIENT_SEARCH];
static gint diagonal_weight[256];
static gint direction_value[256][4];
G_DEFINE_TYPE (GimpIscissorsTool, gimp_iscissors_tool,
GIMP_TYPE_SELECTION_TOOL)
#define parent_class gimp_iscissors_tool_parent_class
void
2002-03-29 03:50:29 +00:00
gimp_iscissors_tool_register (GimpToolRegisterCallback callback,
app/tools/gimpairbrushtool.[ch] app/tools/gimpbezierselecttool.[ch] 2002-05-03 Sven Neumann <sven@gimp.org> * app/tools/gimpairbrushtool.[ch] * app/tools/gimpbezierselecttool.[ch] * app/tools/gimpblendtool.[ch] * app/tools/gimpbrightnesscontrasttool.[ch] * app/tools/gimpbucketfilltool[.ch] * app/tools/gimpbycolorselecttool[.ch] * app/tools/gimpclonetool[.ch] * app/tools/gimpcolorbalancetool[.ch] * app/tools/gimpcolorpickertool[.ch] * app/tools/gimpconvolvetool[.ch] * app/tools/gimpcroptool[.ch] * app/tools/gimpcurvestool[.ch] * app/tools/gimpdodgeburntool[.ch] * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool[.ch] * app/tools/gimperasertool[.ch] * app/tools/gimpfliptool[.ch] * app/tools/gimpfreeselecttool[.ch] * app/tools/gimpfuzzyselecttool[.ch] * app/tools/gimphistogramtool[.ch] * app/tools/gimphuesaturationtool[.ch] * app/tools/gimpinktool[.ch] * app/tools/gimpiscissorstool[.ch] * app/tools/gimplevelstool[.ch] * app/tools/gimpmagnifytool[.ch] * app/tools/gimpmeasuretool[.ch] * app/tools/gimpmovetool[.ch] * app/tools/gimppaintbrushtool[.ch] * app/tools/gimppainttool.c * app/tools/gimppathtool[.ch] * app/tools/gimppenciltool[.ch] * app/tools/gimpperspectivetool[.ch] * app/tools/gimpposterizetool[.ch] * app/tools/gimprectselecttool[.ch] * app/tools/gimprotatetool[.ch] * app/tools/gimpscaletool[.ch] * app/tools/gimpselectiontool.c * app/tools/gimpsheartool[.ch] * app/tools/gimpsmudgetool[.ch] * app/tools/gimptexttool[.ch] * app/tools/gimpthresholdtool[.ch] * app/tools/gimptool.c * app/tools/gimptoolcontrol.h * app/tools/gimptoolmodule[.ch] * app/tools/gimptransformtool.c * app/tools/gimpvectortool[.ch] * app/tools/path_tool.c * app/tools/tool_manager[.ch] * app/tools/tools.c * libgimptool/gimptool.c * libgimptool/gimptoolcontrol.h * libgimptool/gimptoolmodule.h: removed tons of warnings. Do we need to add -Werror to the CFLAGS to avoid such a mess in the future ?! Also had to enforce the GIMP coding style in lots of places :-( * libgimp/gimppixelrgn.c: got sick and tired of debugging plug-ins, so I've added checks for most parameters passed to the GimpPixelRgn functions. This will slow down plug-in execution a little bit but should help to find bugs early.
2002-05-03 11:31:08 +00:00
gpointer data)
{
2002-03-29 03:50:29 +00:00
(* callback) (GIMP_TYPE_ISCISSORS_TOOL,
GIMP_TYPE_ISCISSORS_OPTIONS,
gimp_iscissors_options_gui,
0,
./mitch --sanitize-identifier-namespace 2002-03-20 Michael Natterer <mitch@gimp.org> ./mitch --sanitize-identifier-namespace * app/core/gimpcontext.c * app/display/gimpdisplayshell-callbacks.c * app/display/gimpdisplayshell-dnd.c * app/gui/dialogs-commands.c * app/gui/dialogs-constructors.c * app/gui/dialogs.c * app/gui/edit-commands.c * app/gui/gui.c * app/gui/menus.c * app/gui/vectors-commands.c * app/gui/view-commands.c * app/tools/gimpairbrushtool.c * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpellipseselecttool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppaintbrushtool.c * app/tools/gimppathtool.c * app/tools/gimppenciltool.c * app/tools/gimpperspectivetool.c * app/tools/gimpposterizetool.c * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpscaletool.c * app/tools/gimpsheartool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimpthresholdtool.c * app/tools/gimpvectortool.c * app/widgets/gimpdnd.c * app/widgets/gimptoolbox-indicator-area.c * app/widgets/gimptoolbox.c: s/gimp:/gimp-/g and s/_/-/g for all identifier strings (e.g. gimp:eraser_tool -> gimp-eraser-tool, gimp:layer-list -> gimp-layer-list, ...) * plug-ins/tools/common/gimpbrushselecttool.c: s/gimp:brush_select_tool/gimp-brush-select-tool-module/ Don't quite remember why I introduced the "gimp:" prefix in the first place, but we can always add it back if we need it (for whatever reason) You may want to edit your ~/.gimp-1.3/sessionrc and devicerc or all session settings will be lost due to parse errors.
2002-03-21 12:17:17 +00:00
"gimp-iscissors-tool",
_("Scissors Select"),
2006-09-18 18:00:22 +00:00
_("Scissors Select Tool: Select shapes using intelligent edge-fitting"),
N_("_Scissors Select"),
"I",
NULL, GIMP_HELP_TOOL_ISCISSORS,
GIMP_ICON_TOOL_ISCISSORS,
app/tools/gimpairbrushtool.[ch] app/tools/gimpbezierselecttool.[ch] 2002-05-03 Sven Neumann <sven@gimp.org> * app/tools/gimpairbrushtool.[ch] * app/tools/gimpbezierselecttool.[ch] * app/tools/gimpblendtool.[ch] * app/tools/gimpbrightnesscontrasttool.[ch] * app/tools/gimpbucketfilltool[.ch] * app/tools/gimpbycolorselecttool[.ch] * app/tools/gimpclonetool[.ch] * app/tools/gimpcolorbalancetool[.ch] * app/tools/gimpcolorpickertool[.ch] * app/tools/gimpconvolvetool[.ch] * app/tools/gimpcroptool[.ch] * app/tools/gimpcurvestool[.ch] * app/tools/gimpdodgeburntool[.ch] * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool[.ch] * app/tools/gimperasertool[.ch] * app/tools/gimpfliptool[.ch] * app/tools/gimpfreeselecttool[.ch] * app/tools/gimpfuzzyselecttool[.ch] * app/tools/gimphistogramtool[.ch] * app/tools/gimphuesaturationtool[.ch] * app/tools/gimpinktool[.ch] * app/tools/gimpiscissorstool[.ch] * app/tools/gimplevelstool[.ch] * app/tools/gimpmagnifytool[.ch] * app/tools/gimpmeasuretool[.ch] * app/tools/gimpmovetool[.ch] * app/tools/gimppaintbrushtool[.ch] * app/tools/gimppainttool.c * app/tools/gimppathtool[.ch] * app/tools/gimppenciltool[.ch] * app/tools/gimpperspectivetool[.ch] * app/tools/gimpposterizetool[.ch] * app/tools/gimprectselecttool[.ch] * app/tools/gimprotatetool[.ch] * app/tools/gimpscaletool[.ch] * app/tools/gimpselectiontool.c * app/tools/gimpsheartool[.ch] * app/tools/gimpsmudgetool[.ch] * app/tools/gimptexttool[.ch] * app/tools/gimpthresholdtool[.ch] * app/tools/gimptool.c * app/tools/gimptoolcontrol.h * app/tools/gimptoolmodule[.ch] * app/tools/gimptransformtool.c * app/tools/gimpvectortool[.ch] * app/tools/path_tool.c * app/tools/tool_manager[.ch] * app/tools/tools.c * libgimptool/gimptool.c * libgimptool/gimptoolcontrol.h * libgimptool/gimptoolmodule.h: removed tons of warnings. Do we need to add -Werror to the CFLAGS to avoid such a mess in the future ?! Also had to enforce the GIMP coding style in lots of places :-( * libgimp/gimppixelrgn.c: got sick and tired of debugging plug-ins, so I've added checks for most parameters passed to the GimpPixelRgn functions. This will slow down plug-in execution a little bit but should help to find bugs early.
2002-05-03 11:31:08 +00:00
data);
}
static void
gimp_iscissors_tool_class_init (GimpIscissorsToolClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
gint i, j;
gint radius;
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 14:53:55 +00:00
object_class->finalize = gimp_iscissors_tool_finalize;
tool_class->control = gimp_iscissors_tool_control;
tool_class->button_press = gimp_iscissors_tool_button_press;
tool_class->button_release = gimp_iscissors_tool_button_release;
tool_class->motion = gimp_iscissors_tool_motion;
tool_class->key_press = gimp_iscissors_tool_key_press;
tool_class->oper_update = gimp_iscissors_tool_oper_update;
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
tool_class->cursor_update = gimp_iscissors_tool_cursor_update;
tool_class->can_undo = gimp_iscissors_tool_can_undo;
tool_class->can_redo = gimp_iscissors_tool_can_redo;
tool_class->undo = gimp_iscissors_tool_undo;
tool_class->redo = gimp_iscissors_tool_redo;
draw_tool_class->draw = gimp_iscissors_tool_draw;
for (i = 0; i < 256; i++)
{
/* The diagonal weight array */
diagonal_weight[i] = (int) (i * G_SQRT2);
/* The direction value array */
direction_value[i][0] = (127 - abs (127 - i)) * 2;
direction_value[i][1] = abs (127 - i) * 2;
direction_value[i][2] = abs (191 - i) * 2;
direction_value[i][3] = abs (63 - i) * 2;
}
/* set the 256th index of the direction_values to the highest cost */
direction_value[255][0] = 255;
direction_value[255][1] = 255;
direction_value[255][2] = 255;
direction_value[255][3] = 255;
/* compute the distance weights */
radius = GRADIENT_SEARCH >> 1;
for (i = 0; i < GRADIENT_SEARCH; i++)
for (j = 0; j < GRADIENT_SEARCH; j++)
distance_weights[i * GRADIENT_SEARCH + j] =
1.0 / (1 + sqrt (SQR (i - radius) + SQR (j - radius)));
}
static void
gimp_iscissors_tool_init (GimpIscissorsTool *iscissors)
{
GimpTool *tool = GIMP_TOOL (iscissors);
app/core/core-types.h moved GimpToolInfo back into the core. * app/core/core-types.h * libgimptool/gimptooltypes.h: moved GimpToolInfo back into the core. * libgimptool/gimptoolcontrol.h * app/tools/gimptoolcontrol.c: got rid of gimp_tool_control_new * libgimptool/gimptool.c (gimp_tool_init): create the GimpToolControl here instead of in the descendant classes * app/tools/gimpairbrushtool.c * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppaintbrushtool.c * app/tools/gimppathtool.c * app/tools/gimppenciltool.c * app/tools/gimpperspectivetool.c * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpscaletool.c * app/tools/gimpsheartool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimpvectortool.c * plug-ins/tools/tool-safe-mode.c: changed accordingly * libgimpproxy/gimpproxytypes.h: autogenerated
2002-05-02 21:03:27 +00:00
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_snap_to (tool->control, FALSE);
gimp_tool_control_set_preserve (tool->control, FALSE);
gimp_tool_control_set_dirty_mask (tool->control,
GIMP_DIRTY_IMAGE_SIZE |
GIMP_DIRTY_ACTIVE_DRAWABLE);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_ISCISSORS);
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
iscissors->op = ISCISSORS_OP_NONE;
iscissors->curve = icurve_new ();
iscissors->state = NO_ACTION;
}
static void
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 14:53:55 +00:00
gimp_iscissors_tool_finalize (GObject *object)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (object);
icurve_free (iscissors->curve);
iscissors->curve = NULL;
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 14:53:55 +00:00
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_iscissors_tool_control (GimpTool *tool,
GimpToolAction action,
GimpDisplay *display)
1997-11-24 22:05:25 +00:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
1997-11-24 22:05:25 +00:00
switch (action)
{
case GIMP_TOOL_ACTION_PAUSE:
case GIMP_TOOL_ACTION_RESUME:
break;
1997-11-24 22:05:25 +00:00
case GIMP_TOOL_ACTION_HALT:
gimp_iscissors_tool_halt (iscissors, display);
break;
case GIMP_TOOL_ACTION_COMMIT:
gimp_iscissors_tool_commit (iscissors, display);
break;
}
GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
1997-11-24 22:05:25 +00:00
}
static void
gimp_iscissors_tool_button_press (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonPressType press_type,
GimpDisplay *display)
1997-11-24 22:05:25 +00:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
ISegment *segment;
iscissors->x = RINT (coords->x);
iscissors->y = RINT (coords->y);
1997-11-24 22:05:25 +00:00
/* If the tool was being used in another image...reset it */
if (display != tool->display)
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
1997-11-24 22:05:25 +00:00
gimp_tool_control_activate (tool->control);
tool->display = display;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
1997-11-24 22:05:25 +00:00
switch (iscissors->state)
{
case NO_ACTION:
iscissors->state = SEED_PLACEMENT;
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
if (! (state & gimp_get_extend_selection_mask ()))
find_max_gradient (iscissors, GIMP_PICKABLE (image),
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
iscissors->y = CLAMP (iscissors->y, 0, gimp_image_get_height (image) - 1);
gimp_iscissors_tool_push_undo (iscissors);
segment = icurve_append_segment (iscissors->curve,
iscissors->x,
iscissors->y,
iscissors->x,
iscissors->y);
/* Initialize the draw tool only on starting the tool */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
1997-11-24 22:05:25 +00:00
break;
default:
2005-08-21 20:28:05 +00:00
/* Check if the mouse click occurred on a vertex or the curve itself */
if (clicked_on_vertex (iscissors, coords->x, coords->y))
{
iscissors->state = SEED_ADJUSTMENT;
/* recalculate both segments */
if (iscissors->segment1)
{
iscissors->segment1->x1 = iscissors->x;
iscissors->segment1->y1 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
iscissors->segment2->x2 = iscissors->x;
iscissors->segment2->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
}
/* If the iscissors is closed, check if the click was inside */
else if (iscissors->curve->closed && iscissors->mask &&
gimp_pickable_get_opacity_at (GIMP_PICKABLE (iscissors->mask),
iscissors->x,
iscissors->y))
{
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
}
else if (! iscissors->curve->closed)
{
/* if we're not closed, we're adding a new point */
ISegment *last = g_queue_peek_tail (iscissors->curve->segments);
iscissors->state = SEED_PLACEMENT;
gimp_iscissors_tool_push_undo (iscissors);
if (last->x1 == last->x2 &&
last->y1 == last->y2)
{
last->x2 = iscissors->x;
last->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, last);
}
else
{
segment = icurve_append_segment (iscissors->curve,
last->x2,
last->y2,
iscissors->x,
iscissors->y);
if (options->interactive)
calculate_segment (iscissors, segment);
}
}
1997-11-24 22:05:25 +00:00
break;
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
1997-11-24 22:05:25 +00:00
}
static void
iscissors_convert (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (iscissors);
GimpImage *image = gimp_display_get_image (display);
GimpScanConvert *sc;
sc = icurve_create_scan_convert (iscissors->curve);
if (iscissors->mask)
g_object_unref (iscissors->mask);
iscissors->mask = gimp_channel_new_mask (image,
gimp_image_get_width (image),
gimp_image_get_height (image));
gimp_scan_convert_render (sc,
gimp_drawable_get_buffer (GIMP_DRAWABLE (iscissors->mask)),
0, 0, options->antialias);
gimp_scan_convert_free (sc);
}
1997-11-24 22:05:25 +00:00
static void
gimp_iscissors_tool_button_release (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonReleaseType release_type,
GimpDisplay *display)
1997-11-24 22:05:25 +00:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
1997-11-24 22:05:25 +00:00
gimp_tool_control_halt (tool->control);
/* Make sure X didn't skip the button release event -- as it's known
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
* to do
*/
if (iscissors->state == WAITING)
return;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
1997-11-24 22:05:25 +00:00
if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
1997-11-24 22:05:25 +00:00
{
/* Progress to the next stage of intelligent selection */
switch (iscissors->state)
{
case SEED_PLACEMENT:
/* Add a new segment */
if (! iscissors->curve->first_point)
{
/* Determine if we're connecting to the first point */
ISegment *segment = g_queue_peek_head (iscissors->curve->segments);
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), display,
iscissors->x, iscissors->y,
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->x = segment->x1;
iscissors->y = segment->y1;
icurve_close (iscissors->curve);
if (! options->interactive)
{
segment = g_queue_peek_tail (iscissors->curve->segments);
calculate_segment (iscissors, segment);
}
gimp_iscissors_tool_free_redo (iscissors);
}
else
{
segment = g_queue_peek_tail (iscissors->curve->segments);
if (segment->x1 != segment->x2 ||
segment->y1 != segment->y2)
{
if (! options->interactive)
calculate_segment (iscissors, segment);
gimp_iscissors_tool_free_redo (iscissors);
}
else
{
gimp_iscissors_tool_pop_undo (iscissors);
}
}
}
else /* this was our first point */
{
iscissors->curve->first_point = FALSE;
gimp_iscissors_tool_free_redo (iscissors);
}
break;
case SEED_ADJUSTMENT:
if (state & gimp_get_modify_selection_mask ())
{
if (iscissors->segment1 && iscissors->segment2)
{
icurve_delete_segment (iscissors->curve,
iscissors->segment2);
calculate_segment (iscissors, iscissors->segment1);
}
}
else
{
/* recalculate both segments */
if (iscissors->segment1)
{
if (! options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
if (! options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
}
gimp_iscissors_tool_free_redo (iscissors);
break;
default:
break;
}
}
else
{
switch (iscissors->state)
{
case SEED_PLACEMENT:
case SEED_ADJUSTMENT:
gimp_iscissors_tool_pop_undo (iscissors);
break;
default:
break;
}
1997-11-24 22:05:25 +00:00
}
if (iscissors->curve->first_point)
iscissors->state = NO_ACTION;
else
iscissors->state = WAITING;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
/* convert the curves into a region */
if (iscissors->curve->closed)
iscissors_convert (iscissors, display);
1997-11-24 22:05:25 +00:00
}
static void
gimp_iscissors_tool_motion (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *display)
1997-11-24 22:05:25 +00:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
ISegment *segment;
if (iscissors->state == NO_ACTION)
return;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
iscissors->x = RINT (coords->x);
iscissors->y = RINT (coords->y);
/* Hold the shift key down to disable the auto-edge snap feature */
if (! (state & gimp_get_extend_selection_mask ()))
find_max_gradient (iscissors, GIMP_PICKABLE (image),
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
iscissors->y = CLAMP (iscissors->y, 0, gimp_image_get_height (image) - 1);
1997-11-24 22:05:25 +00:00
switch (iscissors->state)
{
case SEED_PLACEMENT:
segment = g_queue_peek_tail (iscissors->curve->segments);
segment->x2 = iscissors->x;
segment->y2 = iscissors->y;
if (iscissors->curve->first_point)
{
segment->x1 = segment->x2;
segment->y1 = segment->y2;
}
else
{
if (options->interactive)
calculate_segment (iscissors, segment);
}
break;
case SEED_ADJUSTMENT:
if (iscissors->segment1)
{
iscissors->segment1->x1 = iscissors->x;
iscissors->segment1->y1 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
iscissors->segment2->x2 = iscissors->x;
iscissors->segment2->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
1997-11-24 22:05:25 +00:00
break;
default:
1997-11-24 22:05:25 +00:00
break;
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
1997-11-24 22:05:25 +00:00
}
static void
gimp_iscissors_tool_draw (GimpDrawTool *draw_tool)
1997-11-24 22:05:25 +00:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (draw_tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (draw_tool);
GimpCanvasItem *item;
GList *list;
1997-11-24 22:05:25 +00:00
/* First, render all segments and lines */
if (! iscissors->curve->first_point)
1997-11-24 22:05:25 +00:00
{
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
{
ISegment *segment = list->data;
1997-11-24 22:05:25 +00:00
/* plot the segment */
item = iscissors_draw_segment (draw_tool, segment);
/* if this segment is currently being added or adjusted */
if ((iscissors->state == SEED_PLACEMENT &&
! list->next)
||
(iscissors->state == SEED_ADJUSTMENT &&
(segment == iscissors->segment1 ||
segment == iscissors->segment2)))
{
if (! options->interactive)
item = gimp_draw_tool_add_line (draw_tool,
segment->x1, segment->y1,
segment->x2, segment->y2);
if (item)
gimp_canvas_item_set_highlight (item, TRUE);
}
}
}
1997-11-24 22:05:25 +00:00
/* Then, render the handles on top of the segments */
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
{
ISegment *segment = list->data;
if (! iscissors->curve->first_point)
{
gboolean adjustment = (iscissors->state == SEED_ADJUSTMENT &&
segment == iscissors->segment1);
item = gimp_draw_tool_add_handle (draw_tool,
adjustment ?
GIMP_HANDLE_CROSS :
GIMP_HANDLE_FILLED_CIRCLE,
segment->x1,
segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER);
if (adjustment)
gimp_canvas_item_set_highlight (item, TRUE);
}
/* Draw the last point if the curve is not closed */
if (! list->next && ! iscissors->curve->closed)
{
gboolean placement = (iscissors->state == SEED_PLACEMENT);
item = gimp_draw_tool_add_handle (draw_tool,
placement ?
GIMP_HANDLE_CROSS :
GIMP_HANDLE_FILLED_CIRCLE,
segment->x2,
segment->y2,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER);
if (placement)
gimp_canvas_item_set_highlight (item, TRUE);
}
}
}
1997-11-24 22:05:25 +00:00
static GimpCanvasItem *
iscissors_draw_segment (GimpDrawTool *draw_tool,
ISegment *segment)
{
GimpCanvasItem *item;
GimpVector2 *points;
gpointer *point;
gint i, len;
if (! segment->points)
return NULL;
len = segment->points->len;
points = g_new (GimpVector2, len);
for (i = 0, point = segment->points->pdata; i < len; i++, point++)
{
guint32 coords = GPOINTER_TO_INT (*point);
points[i].x = (coords & 0x0000ffff);
points[i].y = (coords >> 16);
1997-11-24 22:05:25 +00:00
}
item = gimp_draw_tool_add_lines (draw_tool, points, len, NULL, FALSE);
g_free (points);
return item;
1997-11-24 22:05:25 +00:00
}
static void
gimp_iscissors_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
display);
/* parent sets a message in the status bar, but it will be replaced here */
if (mouse_over_vertex (iscissors, coords->x, coords->y) > 1)
{
GdkModifierType snap_mask = gimp_get_extend_selection_mask ();
GdkModifierType remove_mask = gimp_get_modify_selection_mask ();
if (state & remove_mask)
{
gimp_tool_replace_status (tool, display,
_("Click to remove this point"));
iscissors->op = ISCISSORS_OP_REMOVE_POINT;
}
else
{
gchar *status =
gimp_suggest_modifiers (_("Click-Drag to move this point"),
(snap_mask | remove_mask) & ~state,
_("%s: disable auto-snap"),
_("%s: remove this point"),
NULL);
gimp_tool_replace_status (tool, display, "%s", status);
g_free (status);
iscissors->op = ISCISSORS_OP_MOVE_POINT;
}
}
else if (mouse_over_segment (iscissors, coords->x, coords->y))
{
ISegment *segment = g_queue_peek_head (iscissors->curve->segments);
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), display,
RINT (coords->x), RINT (coords->y),
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
gimp_tool_replace_status (tool, display,
_("Click to close the curve"));
iscissors->op = ISCISSORS_OP_CONNECT;
}
else
{
gimp_tool_replace_status (tool, display,
_("Click to add a point on this segment"));
iscissors->op = ISCISSORS_OP_ADD_POINT;
}
}
else if (iscissors->curve->closed && iscissors->mask)
{
if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (iscissors->mask),
RINT (coords->x),
RINT (coords->y)))
{
if (proximity)
{
gimp_tool_replace_status (tool, display,
_("Click or press Enter to convert to"
" a selection"));
}
iscissors->op = ISCISSORS_OP_SELECT;
}
else
{
if (proximity)
{
gimp_tool_replace_status (tool, display,
_("Press Enter to convert to a"
" selection"));
}
iscissors->op = ISCISSORS_OP_IMPOSSIBLE;
}
}
else
{
switch (iscissors->state)
{
case WAITING:
if (proximity)
{
GdkModifierType snap_mask = gimp_get_extend_selection_mask ();
gchar *status;
status = gimp_suggest_modifiers (_("Click or Click-Drag to add a"
" point"),
snap_mask & ~state,
_("%s: disable auto-snap"),
NULL, NULL);
bumped minimum required version of GLib to 2.18.0. 2008-11-04 Sven Neumann <sven@sven> * configure.in: bumped minimum required version of GLib to 2.18.0. * INSTALL: document the updated dependency. * app/core/gimp.[ch]: introduced gimp_message_literal(), a variant of gimp_message() that takes a literal string. * app/errors.[ch]: removed format arguments from gimp_fatal_error() and gimp_terminate() and let them take a literal string instead. * app/tools/gimptool.[ch]: introduced gimp_tool_message_literal(), a variant of gimp_tool_message() that takes a literal string. * app/actions/documents-commands.c * app/actions/drawable-commands.c * app/actions/edit-commands.c * app/actions/error-console-commands.c * app/actions/file-commands.c * app/actions/gradients-commands.c * app/actions/image-commands.c * app/actions/layers-commands.c * app/actions/palettes-commands.c * app/actions/plug-in-commands.c * app/actions/select-commands.c * app/actions/vectors-commands.c * app/config/gimprc.c * app/core/gimp-modules.c * app/core/gimp-parasites.c * app/core/gimp-templates.c * app/core/gimp-units.c * app/core/gimpchannel.c * app/core/gimpcontainer-filter.c * app/core/gimpdrawable-bucket-fill.c * app/core/gimpimage-convert.c * app/core/gimpimage-merge.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimplayer-floating-sel.c * app/core/gimplayer.c * app/core/gimpselection.c * app/dialogs/convert-dialog.c * app/dialogs/dialogs.c * app/dialogs/palette-import-dialog.c * app/dialogs/preferences-dialog.c * app/dialogs/quit-dialog.c * app/dialogs/stroke-dialog.c * app/display/gimpdisplayshell-dnd.c * app/file/file-open.c * app/file/file-procedure.c * app/file/file-save.c * app/file/file-utils.c * app/gegl/gimpcurvesconfig.c * app/gegl/gimplevelsconfig.c * app/gui/gui-message.c * app/gui/gui.c * app/gui/session.c * app/paint/gimpbrushcore.c * app/paint/gimpclone.c * app/paint/gimpheal.c * app/paint/gimpperspectiveclone.c * app/paint/gimpsourcecore.c * app/pdb/gimppdb-utils.c * app/pdb/gimpprocedure.c * app/plug-in/gimpplugin-message.c * app/plug-in/gimpplugin.c * app/plug-in/gimppluginmanager-restore.c * app/plug-in/gimppluginprocedure.c * app/text/gimptextlayer.c * app/tools/gimp-tools.c * app/tools/gimpaligntool.c * app/tools/gimpblendtool.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcurvestool.c * app/tools/gimpdesaturatetool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpforegroundselecttool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpgegltool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpimagemaptool-settings.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmeasuretool.c * app/tools/gimppainttool.c * app/tools/gimpposterizetool.c * app/tools/gimpselectiontool.c * app/tools/gimpsourcetool.c * app/tools/gimpthresholdtool.c * app/tools/gimptransformtool.c * app/tools/gimpvectortool.c * app/widgets/gimpactionview.c * app/widgets/gimpcontrollerlist.c * app/widgets/gimpcontrollers.c * app/widgets/gimpdataeditor.c * app/widgets/gimpdevices.c * app/widgets/gimpdnd-xds.c * app/widgets/gimperrordialog.c * app/widgets/gimphelp.c * app/widgets/gimpitemtreeview.c * app/widgets/gimppdbdialog.c * app/widgets/gimpsettingsbox.c * app/widgets/gimpvectorstreeview.c * app/widgets/gimpwidgets-utils.c * app/xcf/xcf-load.c * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/floating_sel.pdb * tools/pdbgen/pdb/image.pdb: use the _literal variants for g_set_error(), gimp_message() and gimp_tool_message(). * app/pdb/convert-cmds.c * app/pdb/edit-cmds.c * app/pdb/floating-sel-cmds.c * app/pdb/image-cmds.c: regenerated. svn path=/trunk/; revision=27548
2008-11-04 12:33:09 +00:00
gimp_tool_replace_status (tool, display, "%s", status);
g_free (status);
}
iscissors->op = ISCISSORS_OP_ADD_POINT;
break;
default:
/* if NO_ACTION, keep parent's status bar message (selection tool) */
iscissors->op = ISCISSORS_OP_NONE;
break;
}
}
}
static void
gimp_iscissors_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
switch (iscissors->op)
{
case ISCISSORS_OP_SELECT:
{
GimpSelectionOptions *options;
options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
/* Do not overwrite the modifiers for add, subtract, intersect */
if (options->operation == GIMP_CHANNEL_OP_REPLACE)
{
modifier = GIMP_CURSOR_MODIFIER_SELECT;
}
}
break;
case ISCISSORS_OP_MOVE_POINT:
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case ISCISSORS_OP_ADD_POINT:
modifier = GIMP_CURSOR_MODIFIER_PLUS;
break;
case ISCISSORS_OP_REMOVE_POINT:
modifier = GIMP_CURSOR_MODIFIER_MINUS;
break;
case ISCISSORS_OP_CONNECT:
modifier = GIMP_CURSOR_MODIFIER_JOIN;
break;
case ISCISSORS_OP_IMPOSSIBLE:
modifier = GIMP_CURSOR_MODIFIER_BAD;
break;
default:
break;
}
added fields for both the tool's toggled and untoggled GdkCursorType, 2002-02-04 Michael Natterer <mitch@gimp.org> * app/tools/gimptool.[ch]: added fields for both the tool's toggled and untoggled GdkCursorType, GimpToolCursorType and GimpCursorModifier. Added a default implementation of gimp_tool_cursor_update() which uses the new fields. Added gimp_tool_set_cursor() as simple wrapper around the resp. GimpDisplayShell functions so tools don't need to know them. Tool implementations can either set the new fields in their cursor_update() function and chain up or call the new wrapper. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpdodgeburntool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.[ch] * app/tools/gimppathtool.c * app/tools/gimpselectiontool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.c: changed accordingly: - set default values in the tools' instance_init functions. - changed the cursor_update() stuff. - removed inclusion of subclasses in gimppainttool.c - the cursor_update() functions are better than before but still evil. - i probably broke some of them...
2002-02-04 17:43:01 +00:00
if (modifier != GIMP_CURSOR_MODIFIER_NONE)
{
gimp_tool_set_cursor (tool, display,
GIMP_CURSOR_MOUSE,
GIMP_TOOL_CURSOR_ISCISSORS,
modifier);
}
else
{
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords,
state, display);
}
}
static gboolean
gimp_iscissors_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (display != tool->display)
return FALSE;
switch (kevent->keyval)
{
case GDK_KEY_BackSpace:
if (! iscissors->curve->closed &&
g_queue_peek_tail (iscissors->curve->segments))
{
ISegment *segment = g_queue_peek_tail (iscissors->curve->segments);
if (g_queue_get_length (iscissors->curve->segments) > 1)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_iscissors_tool_push_undo (iscissors);
icurve_delete_segment (iscissors->curve, segment);
gimp_iscissors_tool_free_redo (iscissors);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
else if (segment->x2 != segment->x1 || segment->y2 != segment->y1)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_iscissors_tool_push_undo (iscissors);
segment->x2 = segment->x1;
segment->y2 = segment->y1;
g_ptr_array_remove_range (segment->points,
0, segment->points->len);
gimp_iscissors_tool_free_redo (iscissors);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
else
{
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
}
return TRUE;
}
return FALSE;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
if (iscissors->curve->closed && iscissors->mask)
{
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
return TRUE;
}
else if (g_queue_get_length (iscissors->curve->segments) > 1)
{
/* Create a closed curve if there are at least three points
and we haven't connected it yet */
ISegment *first = g_queue_peek_head (iscissors->curve->segments);
ISegment *last = g_queue_peek_tail (iscissors->curve->segments);
if (first && last && first != last)
{
ISegment *segment;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_iscissors_tool_push_undo (iscissors);
segment = icurve_append_segment (iscissors->curve,
last->x2, last->y2,
first->x1, first->y1);
icurve_close (iscissors->curve);
calculate_segment (iscissors, segment);
iscissors_convert (iscissors, display);
gimp_iscissors_tool_free_redo (iscissors);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
return TRUE;
}
return FALSE;
case GDK_KEY_Escape:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
return TRUE;
default:
return FALSE;
}
}
static const gchar *
gimp_iscissors_tool_can_undo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (! iscissors->undo_stack)
return NULL;
return _("Modify Scissors Curve");
}
static const gchar *
gimp_iscissors_tool_can_redo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (! iscissors->redo_stack)
return NULL;
return _("Modify Scissors Curve");
}
static gboolean
gimp_iscissors_tool_undo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
iscissors->redo_stack = g_list_prepend (iscissors->redo_stack,
iscissors->curve);
iscissors->curve = iscissors->undo_stack->data;
iscissors->undo_stack = g_list_remove (iscissors->undo_stack,
iscissors->curve);
if (! iscissors->undo_stack)
{
iscissors->state = NO_ACTION;
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
static gboolean
gimp_iscissors_tool_redo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
if (! iscissors->undo_stack)
{
iscissors->state = WAITING;
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
}
iscissors->undo_stack = g_list_prepend (iscissors->undo_stack,
iscissors->curve);
iscissors->curve = iscissors->redo_stack->data;
iscissors->redo_stack = g_list_remove (iscissors->redo_stack,
iscissors->curve);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
static void
gimp_iscissors_tool_push_undo (GimpIscissorsTool *iscissors)
{
iscissors->undo_stack = g_list_prepend (iscissors->undo_stack,
icurve_copy (iscissors->curve));
}
static void
gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors)
{
icurve_free (iscissors->curve);
iscissors->curve = iscissors->undo_stack->data;
iscissors->undo_stack = g_list_remove (iscissors->undo_stack,
iscissors->curve);
if (! iscissors->undo_stack)
{
iscissors->state = NO_ACTION;
gimp_draw_tool_stop (GIMP_DRAW_TOOL (iscissors));
}
}
static void
gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors)
{
g_list_free_full (iscissors->redo_stack,
(GDestroyNotify) icurve_free);
iscissors->redo_stack = NULL;
/* update the undo actions / menu items */
gimp_image_flush (gimp_display_get_image (GIMP_TOOL (iscissors)->display));
}
static void
gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
icurve_clear (iscissors->curve);
iscissors->segment1 = NULL;
iscissors->segment2 = NULL;
iscissors->state = NO_ACTION;
if (iscissors->undo_stack)
{
g_list_free_full (iscissors->undo_stack, (GDestroyNotify) icurve_free);
iscissors->undo_stack = NULL;
}
if (iscissors->redo_stack)
{
g_list_free_full (iscissors->redo_stack, (GDestroyNotify) icurve_free);
iscissors->redo_stack = NULL;
}
g_clear_object (&iscissors->gradient_map);
g_clear_object (&iscissors->mask);
}
static void
gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (iscissors);
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
if (! iscissors->curve->closed)
{
ISegment *first = g_queue_peek_head (iscissors->curve->segments);
ISegment *last = g_queue_peek_tail (iscissors->curve->segments);
if (first && last && first != last)
{
ISegment *segment;
segment = icurve_append_segment (iscissors->curve,
last->x2,
last->y2,
first->x1,
first->y1);
icurve_close (iscissors->curve);
calculate_segment (iscissors, segment);
iscissors_convert (iscissors, display);
}
}
if (iscissors->curve->closed && iscissors->mask)
{
gimp_channel_select_channel (gimp_image_get_mask (image),
gimp_tool_get_undo_desc (tool),
iscissors->mask,
0, 0,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
gimp_image_flush (image);
}
}
/* XXX need some scan-conversion routines from somewhere. maybe. ? */
static gint
mouse_over_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
1997-11-24 22:05:25 +00:00
{
GList *list;
gint segments_found = 0;
1997-11-24 22:05:25 +00:00
/* traverse through the list, returning non-zero if the current cursor
* position is on an existing curve vertex. Set the segment1 and segment2
* variables to the two segments containing the vertex in question
*/
1997-11-24 22:05:25 +00:00
iscissors->segment1 = iscissors->segment2 = NULL;
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
1997-11-24 22:05:25 +00:00
{
ISegment *segment = list->data;
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
x, y,
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->segment1 = segment;
if (segments_found++)
return segments_found;
}
else if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
x, y,
GIMP_HANDLE_CIRCLE,
segment->x2, segment->y2,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->segment2 = segment;
if (segments_found++)
return segments_found;
}
1997-11-24 22:05:25 +00:00
}
return segments_found;
}
static gboolean
clicked_on_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
{
gint segments_found = mouse_over_vertex (iscissors, x, y);
if (segments_found > 1)
{
gimp_iscissors_tool_push_undo (iscissors);
return TRUE;
}
/* if only one segment was found, the segments are unconnected, and
* the user only wants to move either the first or last point
* disallow this for now.
*/
if (segments_found == 1)
return FALSE;
return clicked_on_segment (iscissors, x, y);
1997-11-24 22:05:25 +00:00
}
static GList *
mouse_over_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
1997-11-24 22:05:25 +00:00
{
GList *list;
1997-11-24 22:05:25 +00:00
/* traverse through the list, returning the curve segment's list element
* if the current cursor position is on a curve...
*/
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
1997-11-24 22:05:25 +00:00
{
ISegment *segment = list->data;
gpointer *pt;
gint len;
1997-11-24 22:05:25 +00:00
if (! segment->points)
continue;
pt = segment->points->pdata;
len = segment->points->len;
while (len--)
{
guint32 coords = GPOINTER_TO_INT (*pt);
gint tx, ty;
pt++;
tx = coords & 0x0000ffff;
ty = coords >> 16;
/* Is the specified point close enough to the segment? */
if (gimp_draw_tool_calc_distance_square (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
tx, ty,
x, y) < SQR (GIMP_TOOL_HANDLE_SIZE_CIRCLE / 2))
{
return list;
}
}
}
1997-11-24 22:05:25 +00:00
return NULL;
}
static gboolean
clicked_on_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
{
GList *list = mouse_over_segment (iscissors, x, y);
/* traverse through the list, getting back the curve segment's list
* element if the current cursor position is on a segment...
* If this occurs, replace the segment with two new segments,
* separated by a new vertex.
*/
if (list)
{
ISegment *segment = list->data;
ISegment *new_segment;
gimp_iscissors_tool_push_undo (iscissors);
new_segment = icurve_insert_segment (iscissors->curve,
list,
iscissors->x,
iscissors->y,
segment->x2,
segment->y2);
iscissors->segment1 = new_segment;
iscissors->segment2 = segment;
return TRUE;
1997-11-24 22:05:25 +00:00
}
return FALSE;
1997-11-24 22:05:25 +00:00
}
1997-11-24 22:05:25 +00:00
static void
calculate_segment (GimpIscissorsTool *iscissors,
ISegment *segment)
1997-11-24 22:05:25 +00:00
{
GimpDisplay *display = GIMP_TOOL (iscissors)->display;
GimpPickable *pickable = GIMP_PICKABLE (gimp_display_get_image (display));
gint width;
gint height;
gint xs, ys, xe, ye;
gint x1, y1, x2, y2;
gint ewidth, eheight;
/* Initialise the gradient map buffer for this pickable if we don't
* already have one.
*/
if (! iscissors->gradient_map)
iscissors->gradient_map = gradient_map_new (pickable);
width = gegl_buffer_get_width (iscissors->gradient_map);
height = gegl_buffer_get_height (iscissors->gradient_map);
/* Calculate the lowest cost path from one vertex to the next as specified
* by the parameter "segment".
* Here are the steps:
* 1) Calculate the appropriate working area for this operation
* 2) Allocate a temp buf for the dynamic programming array
* 3) Run the dynamic programming algorithm to find the optimal path
* 4) Translate the optimal path into pixels in the isegment data
* structure.
*/
1997-11-24 22:05:25 +00:00
/* Get the bounding box */
xs = CLAMP (segment->x1, 0, width - 1);
ys = CLAMP (segment->y1, 0, height - 1);
xe = CLAMP (segment->x2, 0, width - 1);
ye = CLAMP (segment->y2, 0, height - 1);
x1 = MIN (xs, xe);
y1 = MIN (ys, ye);
x2 = MAX (xs, xe) + 1; /* +1 because if xe = 199 & xs = 0, x2 - x1, width = 200 */
y2 = MAX (ys, ye) + 1;
/* expand the boundaries past the ending points by
* some percentage of width and height. This serves the following purpose:
* It gives the algorithm more area to search so better solutions
* are found. This is particularly helpful in finding "bumps" which
* fall outside the bounding box represented by the start and end
* coordinates of the "segment".
*/
ewidth = (x2 - x1) * EXTEND_BY + FIXED;
eheight = (y2 - y1) * EXTEND_BY + FIXED;
1997-11-24 22:05:25 +00:00
if (xe >= xs)
x2 += CLAMP (ewidth, 0, width - x2);
else
x1 -= CLAMP (ewidth, 0, x1);
app/actions/channels-commands.c app/actions/colormap-actions.c 2007-12-25 Michael Natterer <mitch@gimp.org> * app/actions/channels-commands.c * app/actions/colormap-actions.c * app/actions/colormap-commands.c * app/actions/image-commands.c * app/core/gimp-edit.c * app/core/gimpdrawable-preview.c * app/core/gimpimage-colorhash.c * app/core/gimpimage-colormap.c * app/core/gimpimage-convert.c * app/core/gimpimage-crop.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-flip.c * app/core/gimpimage-guides.c * app/core/gimpimage-merge.c * app/core/gimpimage-preview.c * app/core/gimpimage-quick-mask.c * app/core/gimpimage-resize.c * app/core/gimpimage-rotate.c * app/core/gimpimage-sample-points.c * app/core/gimpimage-scale.c * app/core/gimpimage-snap.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimpimageundo.c * app/core/gimpitem-preview.c * app/core/gimpitem.c * app/core/gimplayer.c * app/core/gimppalette-import.c * app/core/gimpprojection-construct.c * app/core/gimpprojection.c * app/core/gimpselection.c * app/core/gimpundo.c * app/dialogs/layer-options-dialog.c * app/dialogs/print-size-dialog.c * app/display/gimpdisplay.c * app/display/gimpdisplayshell-draw.c * app/display/gimpdisplayshell-scale.c * app/display/gimpdisplayshell-scroll.c * app/display/gimpdisplayshell-title.c * app/display/gimpdisplayshell-transform.c * app/display/gimpdisplayshell.c * app/display/gimpstatusbar.c * app/file/file-open.c * app/paint/gimppaintoptions.c * app/tools/gimpaligntool.c * app/tools/gimpcolortool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimpperspectiveclonetool.c * app/tools/gimprectangleselecttool.c * app/tools/gimprectangletool.c * app/tools/gimprotatetool.c * app/vectors/gimpvectors-export.c * app/vectors/gimpvectors-import.c * app/vectors/gimpvectors.c * app/widgets/gimpimagepropview.c * app/widgets/gimpnavigationview.c * app/widgets/gimpselectioneditor.c * app/widgets/gimpviewrendererdrawable.c * app/widgets/gimpviewrendererimage.c * app/xcf/xcf-load.c * app/xcf/xcf-save.c * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/image.pdb: use accessors for many image properties. * app/pdb/guides_cmds.c * app/pdb/image_cmds.c: regenerated. svn path=/trunk/; revision=24432
2007-12-25 16:21:40 +00:00
if (ye >= ys)
y2 += CLAMP (eheight, 0, height - y2);
else
y1 -= CLAMP (eheight, 0, y1);
/* blow away any previous points list we might have */
if (segment->points)
{
g_ptr_array_free (segment->points, TRUE);
segment->points = NULL;
}
if ((x2 - x1) && (y2 - y1))
1997-11-24 22:05:25 +00:00
{
/* If the bounding box has width and height... */
GimpTempBuf *dp_buf; /* dynamic programming buffer */
gint dp_width = (x2 - x1);
gint dp_height = (y2 - y1);
dp_buf = gimp_temp_buf_new (dp_width, dp_height,
babl_format ("Y u32"));
/* find the optimal path of pixels from (x1, y1) to (x2, y2) */
find_optimal_path (iscissors->gradient_map, dp_buf,
x1, y1, x2, y2, xs, ys);
/* get a list of the pixels in the optimal path */
segment->points = plot_pixels (dp_buf, x1, y1, xs, ys, xe, ye);
gimp_temp_buf_unref (dp_buf);
}
else if ((x2 - x1) == 0)
{
/* If the bounding box has no width */
/* plot a vertical line */
gint y = ys;
gint dir = (ys > ye) ? -1 : 1;
segment->points = g_ptr_array_new ();
while (y != ye)
{
g_ptr_array_add (segment->points, GINT_TO_POINTER ((y << 16) + xs));
y += dir;
}
}
else if ((y2 - y1) == 0)
{
/* If the bounding box has no height */
/* plot a horizontal line */
gint x = xs;
gint dir = (xs > xe) ? -1 : 1;
segment->points = g_ptr_array_new ();
while (x != xe)
{
g_ptr_array_add (segment->points, GINT_TO_POINTER ((ys << 16) + x));
x += dir;
}
1997-11-24 22:05:25 +00:00
}
}
/* badly need to get a replacement - this is _way_ too expensive */
static gboolean
gradient_map_value (GeglSampler *map_sampler,
const GeglRectangle *map_extent,
gint x,
gint y,
guint8 *grad,
guint8 *dir)
{
if (x >= map_extent->x &&
y >= map_extent->y &&
x < map_extent->width &&
y < map_extent->height)
{
guint8 sample[2];
gegl_sampler_get (map_sampler, x, y, NULL, sample, GEGL_ABYSS_NONE);
*grad = sample[0];
*dir = sample[1];
return TRUE;
}
1997-11-24 22:05:25 +00:00
return FALSE;
1997-11-24 22:05:25 +00:00
}
static gint
calculate_link (GeglSampler *map_sampler,
const GeglRectangle *map_extent,
gint x,
gint y,
guint32 pixel,
gint link)
1997-11-24 22:05:25 +00:00
{
gint value = 0;
guint8 grad1, dir1, grad2, dir2;
if (! gradient_map_value (map_sampler, map_extent, x, y, &grad1, &dir1))
{
grad1 = 0;
dir1 = 255;
}
/* Convert the gradient into a cost: large gradients are good, and
* so have low cost. */
grad1 = 255 - grad1;
/* calculate the contribution of the gradient magnitude */
if (link > 1)
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
value += diagonal_weight[grad1] * OMEGA_G;
1997-11-24 22:05:25 +00:00
else
value += grad1 * OMEGA_G;
/* calculate the contribution of the gradient direction */
x += (gint8)(pixel & 0xff);
y += (gint8)((pixel & 0xff00) >> 8);
if (! gradient_map_value (map_sampler, map_extent, x, y, &grad2, &dir2))
{
grad2 = 0;
dir2 = 255;
}
value +=
(direction_value[dir1][link] + direction_value[dir2][link]) * OMEGA_D;
return value;
}
1997-11-24 22:05:25 +00:00
static GPtrArray *
plot_pixels (GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye)
{
gint x, y;
guint32 coords;
gint link;
gint width = gimp_temp_buf_get_width (dp_buf);
guint *data;
GPtrArray *list;
1997-11-24 22:05:25 +00:00
/* Start the data pointer at the correct location */
data = (guint *) gimp_temp_buf_get_data (dp_buf) + (ye - y1) * width + (xe - x1);
1997-11-24 22:05:25 +00:00
x = xe;
y = ye;
1997-11-24 22:05:25 +00:00
list = g_ptr_array_new ();
1997-11-24 22:05:25 +00:00
while (TRUE)
{
coords = (y << 16) + x;
g_ptr_array_add (list, GINT_TO_POINTER (coords));
1997-11-24 22:05:25 +00:00
link = PIXEL_DIR (*data);
if (link == SEED_POINT)
return list;
1997-11-24 22:05:25 +00:00
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
x += move[link][0];
y += move[link][1];
data += move[link][1] * width + move[link][0];
}
1997-11-24 22:05:25 +00:00
/* won't get here */
return NULL;
}
1997-11-24 22:05:25 +00:00
#define PACK(x, y) ((((y) & 0xff) << 8) | ((x) & 0xff))
#define OFFSET(pixel) ((gint8)((pixel) & 0xff) + \
((gint8)(((pixel) & 0xff00) >> 8)) * \
gimp_temp_buf_get_width (dp_buf))
1997-11-24 22:05:25 +00:00
static void
find_optimal_path (GeglBuffer *gradient_map,
2012-04-08 20:25:49 +02:00
GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys)
{
GeglSampler *map_sampler;
const GeglRectangle *map_extent;
gint i, j, k;
gint x, y;
gint link;
gint linkdir;
gint dirx, diry;
gint min_cost;
gint new_cost;
gint offset;
gint cum_cost[8];
gint link_cost[8];
gint pixel_cost[8];
guint32 pixel[8];
guint32 *data;
guint32 *d;
gint dp_buf_width = gimp_temp_buf_get_width (dp_buf);
gint dp_buf_height = gimp_temp_buf_get_height (dp_buf);
/* initialize the gradient map sampler and extent */
map_sampler = gegl_buffer_sampler_new (gradient_map,
gegl_buffer_get_format (gradient_map),
GEGL_SAMPLER_NEAREST);
map_extent = gegl_buffer_get_extent (gradient_map);
/* initialize the dynamic programming buffer */
data = (guint32 *) gimp_temp_buf_data_clear (dp_buf);
/* what directions are we filling the array in according to? */
dirx = (xs - x1 == 0) ? 1 : -1;
diry = (ys - y1 == 0) ? 1 : -1;
linkdir = (dirx * diry);
y = ys;
for (i = 0; i < dp_buf_height; i++)
1997-11-24 22:05:25 +00:00
{
x = xs;
1997-11-24 22:05:25 +00:00
d = data + (y-y1) * dp_buf_width + (x-x1);
1997-11-24 22:05:25 +00:00
for (j = 0; j < dp_buf_width; j++)
{
min_cost = G_MAXINT;
2013-01-27 17:52:38 +02:00
/* pixel[] array encodes how to get to a neighbour, if possible.
* 0 means no connection (eg edge).
* Rest packed as bottom two bytes: y offset then x offset.
* Initially, we assume we can't get anywhere.
*/
for (k = 0; k < 8; k++)
pixel[k] = 0;
/* Find the valid neighboring pixels */
/* the previous pixel */
if (j)
pixel[((dirx == 1) ? 4 : 0)] = PACK (-dirx, 0);
/* the previous row of pixels */
if (i)
{
pixel[((diry == 1) ? 5 : 1)] = PACK (0, -diry);
link = (linkdir == 1) ? 3 : 2;
if (j)
pixel[((diry == 1) ? (link + 4) : link)] = PACK (-dirx, -diry);
link = (linkdir == 1) ? 2 : 3;
if (j != dp_buf_width - 1)
pixel[((diry == 1) ? (link + 4) : link)] = PACK (dirx, -diry);
}
/* find the minimum cost of going through each neighbor to reach the
* seed point...
*/
link = -1;
for (k = 0; k < 8; k ++)
if (pixel[k])
{
link_cost[k] = calculate_link (map_sampler, map_extent,
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-08 19:14:51 +00:00
xs + j*dirx, ys + i*diry,
pixel [k],
((k > 3) ? k - 4 : k));
offset = OFFSET (pixel [k]);
pixel_cost[k] = PIXEL_COST (d[offset]);
cum_cost[k] = pixel_cost[k] + link_cost[k];
if (cum_cost[k] < min_cost)
{
min_cost = cum_cost[k];
link = k;
}
}
/* If anything can be done... */
if (link >= 0)
{
/* set the cumulative cost of this pixel and the new direction
*/
*d = (cum_cost[link] << 8) + link;
/* possibly change the links from the other pixels to this pixel...
* these changes occur if a neighboring pixel will receive a lower
* cumulative cost by going through this pixel.
*/
for (k = 0; k < 8; k ++)
if (pixel[k] && k != link)
{
/* if the cumulative cost at the neighbor is greater than
* the cost through the link to the current pixel, change the
* neighbor's link to point to the current pixel.
*/
new_cost = link_cost[k] + cum_cost[link];
if (pixel_cost[k] > new_cost)
{
/* reverse the link direction /--------------------\ */
offset = OFFSET (pixel[k]);
d[offset] = (new_cost << 8) + ((k > 3) ? k - 4 : k + 4);
}
}
}
/* Set the seed point */
else if (!i && !j)
{
*d = SEED_POINT;
}
/* increment the data pointer and the x counter */
d += dirx;
x += dirx;
}
1997-11-24 22:05:25 +00:00
/* increment the y counter */
y += diry;
1997-11-24 22:05:25 +00:00
}
g_object_unref (map_sampler);
1997-11-24 22:05:25 +00:00
}
static GeglBuffer *
gradient_map_new (GimpPickable *pickable)
{
GeglBuffer *buffer;
GeglTileHandler *handler;
1997-11-24 22:05:25 +00:00
buffer = gimp_pickable_get_buffer (pickable);
buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer)),
babl_format_n (babl_type ("u8"), 2));
1997-11-24 22:05:25 +00:00
handler = gimp_tile_handler_iscissors_new (pickable);
1997-11-24 22:05:25 +00:00
gimp_tile_handler_validate_assign (GIMP_TILE_HANDLER_VALIDATE (handler),
buffer);
gimp_tile_handler_validate_invalidate (GIMP_TILE_HANDLER_VALIDATE (handler),
GEGL_RECTANGLE (0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer)));
g_object_unref (handler);
return buffer;
1997-11-24 22:05:25 +00:00
}
static void
find_max_gradient (GimpIscissorsTool *iscissors,
GimpPickable *pickable,
gint *x,
gint *y)
1997-11-24 22:05:25 +00:00
{
GeglBufferIterator *iter;
GeglRectangle *roi;
gint width;
gint height;
gint radius;
gint cx, cy;
gint x1, y1, x2, y2;
gfloat max_gradient;
/* Initialise the gradient map buffer for this pickable if we don't
* already have one.
*/
if (! iscissors->gradient_map)
iscissors->gradient_map = gradient_map_new (pickable);
width = gegl_buffer_get_width (iscissors->gradient_map);
height = gegl_buffer_get_height (iscissors->gradient_map);
radius = GRADIENT_SEARCH >> 1;
/* calculate the extent of the search */
cx = CLAMP (*x, 0, width);
cy = CLAMP (*y, 0, height);
x1 = CLAMP (cx - radius, 0, width);
y1 = CLAMP (cy - radius, 0, height);
x2 = CLAMP (cx + radius, 0, width);
y2 = CLAMP (cy + radius, 0, height);
/* calculate the factor to multiply the distance from the cursor by */
max_gradient = 0;
*x = cx;
*y = cy;
iter = gegl_buffer_iterator_new (iscissors->gradient_map,
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
0, NULL,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
roi = &iter->items[0].roi;
while (gegl_buffer_iterator_next (iter))
1997-11-24 22:05:25 +00:00
{
guint8 *data = iter->items[0].data;
gint endx = roi->x + roi->width;
gint endy = roi->y + roi->height;
gint i, j;
for (i = roi->y; i < endy; i++)
{
const guint8 *gradient = data + 2 * roi->width * (i - roi->y);
for (j = roi->x; j < endx; j++)
{
gfloat g = *gradient;
gradient += COST_WIDTH;
g *= distance_weights [(i - y1) * GRADIENT_SEARCH + (j - x1)];
if (g > max_gradient)
{
max_gradient = g;
*x = j;
*y = i;
}
}
}
1997-11-24 22:05:25 +00:00
}
}
static ISegment *
isegment_new (gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = g_slice_new0 (ISegment);
segment->x1 = x1;
segment->y1 = y1;
segment->x2 = x2;
segment->y2 = y2;
return segment;
}
static ISegment *
isegment_copy (ISegment *segment)
{
ISegment *copy = isegment_new (segment->x1,
segment->y1,
segment->x2,
segment->y2);
if (segment->points)
{
gint i;
copy->points = g_ptr_array_sized_new (segment->points->len);
for (i = 0; i < segment->points->len; i++)
{
gpointer value = g_ptr_array_index (segment->points, i);
g_ptr_array_add (copy->points, value);
}
}
return copy;
}
static void
isegment_free (ISegment *segment)
{
if (segment->points)
g_ptr_array_free (segment->points, TRUE);
g_slice_free (ISegment, segment);
}
static ICurve *
icurve_new (void)
{
ICurve *curve = g_slice_new0 (ICurve);
curve->segments = g_queue_new ();
curve->first_point = TRUE;
return curve;
}
static ICurve *
icurve_copy (ICurve *curve)
{
ICurve *copy = icurve_new ();
GList *link;
for (link = g_queue_peek_head_link (curve->segments);
link;
link = g_list_next (link))
{
g_queue_push_tail (copy->segments, isegment_copy (link->data));
}
copy->first_point = curve->first_point;
copy->closed = curve->closed;
return copy;
}
static void
icurve_clear (ICurve *curve)
{
while (! g_queue_is_empty (curve->segments))
isegment_free (g_queue_pop_head (curve->segments));
curve->first_point = TRUE;
curve->closed = FALSE;
}
static void
icurve_free (ICurve *curve)
{
g_queue_free_full (curve->segments, (GDestroyNotify) isegment_free);
g_slice_free (ICurve, curve);
}
static ISegment *
icurve_append_segment (ICurve *curve,
gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = isegment_new (x1, y1, x2, y2);
g_queue_push_tail (curve->segments, segment);
return segment;
}
static ISegment *
icurve_insert_segment (ICurve *curve,
GList *sibling,
gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = sibling->data;
ISegment *new_segment;
new_segment = isegment_new (x1, y1, x2, y2);
segment->x2 = x1;
segment->y2 = y1;
g_queue_insert_after (curve->segments, sibling, new_segment);
return new_segment;
}
static void
icurve_delete_segment (ICurve *curve,
ISegment *segment)
{
GList *link = g_queue_find (curve->segments, segment);
ISegment *next_segment = NULL;
if (link->next)
next_segment = link->next->data;
else if (curve->closed)
next_segment = g_queue_peek_head (curve->segments);
if (next_segment)
{
next_segment->x1 = segment->x1;
next_segment->y1 = segment->y1;
}
g_queue_remove (curve->segments, segment);
isegment_free (segment);
}
static void
icurve_close (ICurve *curve)
{
ISegment *first = g_queue_peek_head (curve->segments);
ISegment *last = g_queue_peek_tail (curve->segments);
last->x2 = first->x1;
last->y2 = first->y1;
curve->closed = TRUE;
}
static GimpScanConvert *
icurve_create_scan_convert (ICurve *curve)
{
GimpScanConvert *sc;
GList *list;
GimpVector2 *points;
guint n_total_points = 0;
sc = gimp_scan_convert_new ();
for (list = g_queue_peek_tail_link (curve->segments);
list;
list = g_list_previous (list))
{
ISegment *segment = list->data;
n_total_points += segment->points->len;
}
points = g_new (GimpVector2, n_total_points);
n_total_points = 0;
/* go over the segments in reverse order, adding the points we have */
for (list = g_queue_peek_tail_link (curve->segments);
list;
list = g_list_previous (list))
{
ISegment *segment = list->data;
guint n_points;
gint i;
n_points = segment->points->len;
for (i = 0; i < n_points; i++)
{
guint32 packed = GPOINTER_TO_INT (g_ptr_array_index (segment->points,
i));
points[n_total_points + i].x = packed & 0x0000ffff;
points[n_total_points + i].y = packed >> 16;
}
n_total_points += n_points;
}
gimp_scan_convert_add_polyline (sc, n_total_points, points, TRUE);
g_free (points);
return sc;
}