1999-03-06 07:50:24 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1999 Andy Thomas alt@picnic.demon.co.uk
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (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, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
* Some of this code is based on the layers_dialog box code.
|
|
|
|
*/
|
Check for mmap.
* configure.in: Check for mmap.
* app/makefile.msc: Depend on gimpi.lib.
* app/app_procs.c (app_init): Fix gccism: Allocate filenames (an
array with non-constant size) dynamically.
* app/{datafiles,fileops,general,install,module_db,temp_buf}.c:
Include glib.h before standard headers, because of certain obscure
details related to compiling with gcc on Win32.
(If you really want to know: glib.h defines he names of POSIXish
(but non-ANSI) functions as prefixed with underscore, because
that's how they are named in the msvcrt runtime C library we want
to use. However, defining stat as _stat causes some problems if
done after including the mingw32 <sys/stat.h>. So, it's easiest to
include <glib.h> early.)
* app/main.c: Use _stdcall and __argc, __argv with MSC, but
__attribute__((stdcall)) and _argc, _argv with gcc. Don't print
the "Passed serialization test" message on Win32. (It would open
up an otherwise unnecessary console window.)
* app/paint_funcs.c (gaussian_blur_region): Don't use variable sum
until initialized.
* app/{bezier_select,paths_dialog}.c: Include config.h and define
rint() if necessary.
* app/plug_in.c: Use _spawnv, not spawnv, on Win32 and OS/2.
1999-05-29 01:47:17 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
#include <stdio.h>
|
1999-03-13 06:04:30 +08:00
|
|
|
#include <errno.h>
|
2000-03-26 06:19:17 +08:00
|
|
|
#include <string.h>
|
1999-08-05 07:22:29 +08:00
|
|
|
|
2000-04-28 01:27:28 +08:00
|
|
|
#include <gdk/gdkkeysyms.h>
|
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-02 04:30:56 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "appenv.h"
|
|
|
|
#include "draw_core.h"
|
|
|
|
#include "drawable.h"
|
|
|
|
#include "floating_sel.h"
|
|
|
|
#include "gimage.h"
|
1999-07-10 05:52:00 +08:00
|
|
|
#include "gimpimage.h"
|
|
|
|
#include "gimpdrawable.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "gimage_mask.h"
|
1999-07-10 05:52:00 +08:00
|
|
|
#include "gdisplay.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "gimprc.h"
|
|
|
|
#include "gimpset.h"
|
1999-09-28 01:58:10 +08:00
|
|
|
#include "gimpui.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "image_render.h"
|
1999-06-07 01:26:51 +08:00
|
|
|
#include "lc_dialogP.h"
|
|
|
|
#include "menus.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "ops_buttons.h"
|
|
|
|
#include "bezier_select.h"
|
|
|
|
#include "bezier_selectP.h"
|
2000-02-16 21:52:33 +08:00
|
|
|
#include "path.h"
|
|
|
|
#include "pathP.h"
|
|
|
|
#include "path_transform.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "paths_dialog.h"
|
1999-06-07 01:26:51 +08:00
|
|
|
#include "paths_dialogP.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "undo.h"
|
|
|
|
|
1999-07-10 05:52:00 +08:00
|
|
|
#include "drawable_pvt.h"
|
1999-08-05 07:22:29 +08:00
|
|
|
|
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-02 04:30:56 +08:00
|
|
|
#include "libgimp/gimpmath.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
#include "libgimp/gimpintl.h"
|
|
|
|
|
1999-03-13 06:43:12 +08:00
|
|
|
#include "pixmaps/new.xpm"
|
|
|
|
#include "pixmaps/duplicate.xpm"
|
|
|
|
#include "pixmaps/delete.xpm"
|
|
|
|
#include "pixmaps/pennorm.xpm"
|
|
|
|
#include "pixmaps/penadd.xpm"
|
|
|
|
#include "pixmaps/pendel.xpm"
|
|
|
|
#include "pixmaps/penedit.xpm"
|
|
|
|
#include "pixmaps/penstroke.xpm"
|
1999-03-14 02:55:04 +08:00
|
|
|
#include "pixmaps/toselection.xpm"
|
1999-07-10 05:52:00 +08:00
|
|
|
#include "pixmaps/topath.xpm"
|
1999-03-13 06:43:12 +08:00
|
|
|
#include "pixmaps/path.xbm"
|
1999-07-08 03:09:52 +08:00
|
|
|
#include "pixmaps/locked.xbm"
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
typedef struct _PathsDialog PathsDialog;
|
|
|
|
|
|
|
|
struct _PathsDialog
|
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
GtkWidget *vbox;
|
1999-11-03 17:58:46 +08:00
|
|
|
GtkWidget *paths_list;
|
|
|
|
|
|
|
|
GtkWidget *ops_menu;
|
1999-03-06 07:50:24 +08:00
|
|
|
GtkAccelGroup *accel_group;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gdouble ratio;
|
2000-02-24 20:35:25 +08:00
|
|
|
gint image_width, image_height;
|
|
|
|
gint gimage_width, gimage_height;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/* pixmaps for the no preview bitmap */
|
2000-02-24 20:35:25 +08:00
|
|
|
GdkPixmap *pixmap_normal;
|
|
|
|
GdkPixmap *pixmap_selected;
|
|
|
|
GdkPixmap *pixmap_locked_normal;
|
|
|
|
GdkPixmap *pixmap_locked_selected;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* state information */
|
2000-02-24 20:35:25 +08:00
|
|
|
gint selsigid;
|
|
|
|
GimpImage *gimage;
|
|
|
|
GdkGC *gc;
|
|
|
|
GdkColor black;
|
|
|
|
GdkColor white;
|
|
|
|
gint selected_row_num;
|
|
|
|
gboolean been_selected;
|
|
|
|
PathList *current_path_list;
|
1999-10-30 18:39:48 +08:00
|
|
|
};
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
typedef struct _PathWidget PathWidget;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
struct _PathWidget
|
|
|
|
{
|
|
|
|
GdkPixmap *paths_pixmap;
|
2000-02-16 21:52:33 +08:00
|
|
|
Path *bzp;
|
1999-10-30 18:39:48 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct _PathCounts PathCounts;
|
1999-04-14 05:50:28 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
struct _PathCounts
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
CountCurves c_count; /* Must be the first element */
|
|
|
|
gint total_count; /* Total number of curves */
|
1999-10-30 18:39:48 +08:00
|
|
|
};
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
static PathsDialog *paths_dialog = NULL;
|
2000-02-24 20:35:25 +08:00
|
|
|
static Path *copy_pp = NULL;
|
|
|
|
|
|
|
|
static void paths_dialog_realized (GtkWidget *widget);
|
|
|
|
static void paths_select_row (GtkWidget *widget,
|
|
|
|
gint row,
|
|
|
|
gint column,
|
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data);
|
|
|
|
static void paths_unselect_row (GtkWidget *widget,
|
|
|
|
gint row,
|
|
|
|
gint column,
|
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data);
|
|
|
|
static gint paths_list_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event);
|
|
|
|
static void paths_dialog_map_callback (GtkWidget *widget,
|
|
|
|
gpointer data);
|
|
|
|
static void paths_dialog_unmap_callback (GtkWidget *widget,
|
|
|
|
gpointer data);
|
|
|
|
static void paths_update_paths (gpointer data,
|
|
|
|
gint row);
|
|
|
|
static void paths_update_preview (BezierSelect *bezier_sel);
|
1999-10-30 18:39:48 +08:00
|
|
|
static void paths_dialog_preview_extents (void);
|
|
|
|
static void paths_dialog_new_point_callback (GtkWidget *, gpointer);
|
|
|
|
static void paths_dialog_add_point_callback (GtkWidget *, gpointer);
|
|
|
|
static void paths_dialog_delete_point_callback (GtkWidget *, gpointer);
|
|
|
|
static void paths_dialog_edit_point_callback (GtkWidget *, gpointer);
|
|
|
|
static void paths_dialog_advanced_to_path_callback (GtkWidget *, gpointer);
|
|
|
|
static void paths_dialog_null_callback (GtkWidget *, gpointer);
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
static void path_close (Path *);
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-07-10 05:52:00 +08:00
|
|
|
/* the ops buttons */
|
1999-11-03 17:58:46 +08:00
|
|
|
static GtkSignalFunc to_path_ext_callbacks[] =
|
1999-07-10 05:52:00 +08:00
|
|
|
{
|
|
|
|
paths_dialog_advanced_to_path_callback, /* SHIFT */
|
|
|
|
paths_dialog_null_callback, /* CTRL */
|
|
|
|
paths_dialog_null_callback, /* MOD1 */
|
|
|
|
paths_dialog_null_callback, /* SHIFT + CTRL */
|
|
|
|
};
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static OpsButton paths_ops_buttons[] =
|
|
|
|
{
|
1999-10-30 21:01:15 +08:00
|
|
|
{ new_xpm, paths_dialog_new_path_callback, NULL,
|
|
|
|
N_("New Path"),
|
|
|
|
"paths/new_path.html",
|
|
|
|
NULL, 0 },
|
|
|
|
{ duplicate_xpm, paths_dialog_dup_path_callback, NULL,
|
|
|
|
N_("Duplicate Path"),
|
|
|
|
"paths/duplicate_path.html",
|
|
|
|
NULL, 0 },
|
|
|
|
{ toselection_xpm, paths_dialog_path_to_sel_callback, NULL,
|
|
|
|
N_("Path to Selection"),
|
|
|
|
"paths/path_to_selection.html",
|
|
|
|
NULL, 0 },
|
|
|
|
{ topath_xpm, paths_dialog_sel_to_path_callback, to_path_ext_callbacks,
|
|
|
|
N_("Selection to Path"),
|
1999-12-18 00:37:50 +08:00
|
|
|
"filters/sel2path.html",
|
1999-10-30 21:01:15 +08:00
|
|
|
NULL, 0 },
|
|
|
|
{ penstroke_xpm, paths_dialog_stroke_path_callback, NULL,
|
|
|
|
N_("Stroke Path"),
|
|
|
|
"paths/stroke_path.html",
|
|
|
|
NULL, 0 },
|
|
|
|
{ delete_xpm, paths_dialog_delete_path_callback, NULL,
|
|
|
|
N_("Delete Path"),
|
|
|
|
"paths/delete_path.html",
|
|
|
|
NULL, 0 },
|
|
|
|
{ NULL, NULL, NULL, NULL, NULL, NULL, 0 }
|
1999-03-06 07:50:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static OpsButton point_ops_buttons[] =
|
|
|
|
{
|
1999-10-30 21:01:15 +08:00
|
|
|
{ pennorm_xpm, paths_dialog_new_point_callback, NULL,
|
1999-11-03 17:58:46 +08:00
|
|
|
N_("New Point"),
|
|
|
|
"#new_point_button",
|
1999-10-30 21:01:15 +08:00
|
|
|
NULL, 0 },
|
|
|
|
{ penadd_xpm, paths_dialog_add_point_callback, NULL,
|
1999-11-03 17:58:46 +08:00
|
|
|
N_("Add Point"),
|
|
|
|
"#add_point_button",
|
1999-10-30 21:01:15 +08:00
|
|
|
NULL, 0 },
|
|
|
|
{ pendel_xpm, paths_dialog_delete_point_callback, NULL,
|
1999-11-03 17:58:46 +08:00
|
|
|
N_("Delete Point"),
|
|
|
|
"#delete_point_button",
|
1999-10-30 21:01:15 +08:00
|
|
|
NULL, 0 },
|
|
|
|
{ penedit_xpm, paths_dialog_edit_point_callback, NULL,
|
1999-11-03 17:58:46 +08:00
|
|
|
N_("Edit Point"),
|
|
|
|
"#edit_point_button",
|
1999-10-30 21:01:15 +08:00
|
|
|
NULL, 0 },
|
|
|
|
{ NULL, NULL, NULL, NULL, NULL, NULL, 0 }
|
1999-03-06 07:50:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
1999-10-30 21:01:15 +08:00
|
|
|
paths_dialog_set_menu_sensitivity (void)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gboolean gimage = FALSE; /* is there a gimage */
|
|
|
|
gboolean pp = FALSE; /* paths present */
|
|
|
|
gboolean cpp = FALSE; /* is there a path in the pate buffer */
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (! paths_dialog)
|
|
|
|
return;
|
1999-10-19 04:55:25 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->gimage)
|
|
|
|
gimage = TRUE;
|
|
|
|
|
|
|
|
if (gimage && gimp_image_get_paths (paths_dialog->gimage))
|
|
|
|
pp = TRUE;
|
|
|
|
|
|
|
|
if (copy_pp)
|
|
|
|
cpp = TRUE;
|
|
|
|
|
|
|
|
#define SET_SENSITIVE(menu,condition) \
|
1999-11-24 03:11:29 +08:00
|
|
|
menus_set_sensitive ("<Paths>/" menu, (condition) != 0)
|
1999-10-30 18:39:48 +08:00
|
|
|
#define SET_OPS_SENSITIVE(button,condition) \
|
|
|
|
gtk_widget_set_sensitive (paths_ops_buttons[(button)].widget, \
|
|
|
|
(condition) != 0)
|
|
|
|
#define SET_POINT_SENSITIVE(button,condition) \
|
|
|
|
gtk_widget_set_sensitive (point_ops_buttons[(button)].widget, \
|
|
|
|
(condition) != 0)
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("New Path", gimage);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (0, gimage);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Duplicate Path", pp);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (1, pp);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Path to Selection", pp);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (2, pp);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Selection to Path", gimage);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (3, gimage);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Stroke Path", pp);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (4, pp);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Delete Path", pp);
|
1999-10-30 18:39:48 +08:00
|
|
|
SET_OPS_SENSITIVE (5, pp);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Copy Path", pp);
|
|
|
|
SET_SENSITIVE ("Paste Path", pp && cpp);
|
1999-10-30 18:39:48 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Import Path...", gimage);
|
|
|
|
SET_SENSITIVE ("Export Path...", pp);
|
1999-10-30 18:39:48 +08:00
|
|
|
|
2000-02-01 06:59:22 +08:00
|
|
|
SET_SENSITIVE ("Edit Path Attributes...", pp);
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* new point */
|
|
|
|
SET_POINT_SENSITIVE (0, pp);
|
|
|
|
|
|
|
|
/* add point */
|
|
|
|
SET_POINT_SENSITIVE (1, pp);
|
|
|
|
|
|
|
|
/* selete point */
|
|
|
|
SET_POINT_SENSITIVE (2, pp);
|
|
|
|
|
|
|
|
/* edit point */
|
|
|
|
SET_POINT_SENSITIVE (3, pp);
|
|
|
|
|
|
|
|
#undef SET_POINT_SENSITIVE
|
|
|
|
#undef SET_OPS_SENSITIVE
|
|
|
|
#undef SET_SENSITIVE
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
void
|
|
|
|
paths_dialog_set_default_op (void)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-01-12 04:08:45 +08:00
|
|
|
if(paths_dialog != NULL) /* Bug #5049: Clients may call this because it is possible */
|
|
|
|
/* to create a path before the L&C dialog exists. */
|
|
|
|
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (point_ops_buttons[0].widget),
|
|
|
|
TRUE);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
GtkWidget *
|
|
|
|
paths_dialog_create (void)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
GtkWidget *vbox;
|
|
|
|
GtkWidget *paths_list;
|
|
|
|
GtkWidget *scrolled_win;
|
|
|
|
GtkWidget *button_box;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog)
|
|
|
|
return paths_dialog->vbox;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog = g_new0 (PathsDialog, 1);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* The paths box */
|
1999-11-03 17:58:46 +08:00
|
|
|
paths_dialog->vbox = gtk_event_box_new ();
|
|
|
|
|
|
|
|
gimp_help_set_help_data (paths_dialog->vbox, NULL,
|
|
|
|
"dialogs/paths/paths.html");
|
|
|
|
|
|
|
|
vbox = gtk_vbox_new (FALSE, 1);
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
|
1999-11-03 17:58:46 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (paths_dialog->vbox), vbox);
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* The point operations */
|
2000-02-26 11:33:57 +08:00
|
|
|
button_box = ops_button_box_new (point_ops_buttons, OPS_BUTTON_RADIO);
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, TRUE, 2);
|
|
|
|
gtk_widget_show (button_box);
|
|
|
|
|
|
|
|
scrolled_win = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
|
|
|
|
GTK_POLICY_AUTOMATIC,
|
|
|
|
GTK_POLICY_ALWAYS);
|
|
|
|
gtk_widget_set_usize (scrolled_win, LIST_WIDTH, LIST_HEIGHT);
|
1999-11-03 17:58:46 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 2);
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
paths_dialog->paths_list = paths_list = gtk_clist_new (2);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (vbox), "destroy",
|
|
|
|
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
|
|
|
|
&paths_dialog);
|
|
|
|
|
|
|
|
gtk_clist_set_selection_mode (GTK_CLIST (paths_list), GTK_SELECTION_BROWSE);
|
|
|
|
gtk_clist_set_reorderable (GTK_CLIST (paths_list), FALSE);
|
|
|
|
gtk_clist_set_column_width (GTK_CLIST (paths_list), 0, locked_width);
|
|
|
|
gtk_clist_set_column_min_width (GTK_CLIST (paths_list), 1,
|
|
|
|
LIST_WIDTH - locked_width - 4);
|
|
|
|
gtk_clist_set_column_auto_resize (GTK_CLIST (paths_list), 1, TRUE);
|
|
|
|
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled_win), paths_list);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (paths_list), "event",
|
|
|
|
(GtkSignalFunc) paths_list_events,
|
|
|
|
paths_dialog);
|
|
|
|
gtk_container_set_focus_vadjustment (GTK_CONTAINER (paths_list),
|
|
|
|
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
|
1999-11-03 17:58:46 +08:00
|
|
|
GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (scrolled_win)->vscrollbar,
|
|
|
|
GTK_CAN_FOCUS);
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
paths_dialog->selsigid =
|
1999-11-03 17:58:46 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (paths_list), "select_row",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (paths_select_row),
|
|
|
|
NULL);
|
|
|
|
|
1999-11-03 17:58:46 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (paths_list), "unselect_row",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (paths_unselect_row),
|
|
|
|
NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_widget_show (scrolled_win);
|
|
|
|
gtk_widget_show (paths_list);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-11-03 23:17:56 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (paths_dialog->vbox), "realize",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (paths_dialog_realized),
|
|
|
|
NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_widget_show (vbox);
|
1999-11-03 17:58:46 +08:00
|
|
|
gtk_widget_show (paths_dialog->vbox);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* The ops buttons */
|
2000-02-26 11:33:57 +08:00
|
|
|
button_box = ops_button_box_new (paths_ops_buttons, OPS_BUTTON_NORMAL);
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 2);
|
|
|
|
gtk_widget_show (button_box);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
menus_get_paths_menu (&paths_dialog->ops_menu,
|
|
|
|
&paths_dialog->accel_group);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* Set up signals for map/unmap for the accelerators */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (vbox), "map",
|
|
|
|
(GtkSignalFunc) paths_dialog_map_callback,
|
|
|
|
NULL);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (vbox), "unmap",
|
|
|
|
(GtkSignalFunc) paths_dialog_unmap_callback,
|
|
|
|
NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_set_menu_sensitivity ();
|
|
|
|
|
|
|
|
paths_dialog_set_default_op ();
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
return paths_dialog->vbox;
|
|
|
|
}
|
|
|
|
|
1999-10-25 04:16:48 +08:00
|
|
|
static void
|
|
|
|
paths_dialog_realized (GtkWidget *widget)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
GdkColormap *colormap;
|
|
|
|
gchar dash_list[2]= {3,3};
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/* Help out small displays */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (preview_size < 64)
|
1999-03-13 06:04:30 +08:00
|
|
|
dash_list[1] = 1;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->gc = gdk_gc_new (widget->window);
|
|
|
|
gdk_gc_set_dashes (paths_dialog->gc, 2, dash_list, 2);
|
|
|
|
colormap = gtk_widget_get_colormap (paths_dialog->paths_list);
|
|
|
|
gdk_color_parse ("black", &paths_dialog->black);
|
|
|
|
gdk_color_alloc (colormap, &paths_dialog->black);
|
|
|
|
gdk_color_parse ("white", &paths_dialog->white);
|
|
|
|
gdk_color_alloc (colormap, &paths_dialog->white);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clears out row when list element is deleted/destroyed */
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
clear_pathwidget (gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget = data;
|
|
|
|
|
|
|
|
if (pwidget)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
if (pwidget->paths_pixmap)
|
|
|
|
gdk_pixmap_unref (pwidget->paths_pixmap);
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_free (pwidget);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
static Path*
|
1999-10-25 04:16:48 +08:00
|
|
|
path_dialog_new (GimpImage *gimage,
|
|
|
|
gint name_seed,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path *bzp;
|
|
|
|
gchar *s;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
s = g_strdup_printf (_("Path %d"), name_seed);
|
|
|
|
bzp = path_new (gimage, BEZIER, (GSList *) data, 0, 0, 0, 0, s);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
return bzp;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
static PathPoint*
|
1999-10-25 04:16:48 +08:00
|
|
|
path_start_last_seg (GSList *plist)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint *retp = plist->data;
|
1999-10-30 18:39:48 +08:00
|
|
|
while (plist)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
if (((PathPoint*) (plist->data))->type == BEZIER_MOVE &&
|
1999-10-30 18:39:48 +08:00
|
|
|
g_slist_next (plist))
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
plist = g_slist_next (plist);
|
1999-05-14 06:53:40 +08:00
|
|
|
retp = plist->data;
|
|
|
|
}
|
1999-10-30 18:39:48 +08:00
|
|
|
plist = g_slist_next (plist);
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
return retp;
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static void
|
2000-02-16 09:47:22 +08:00
|
|
|
path_close (Path *bzp)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint *pdata;
|
|
|
|
PathPoint *pathpoint;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* bzpaths are only really closed when converted to the BezierSelect ones */
|
|
|
|
bzp->closed = 1;
|
|
|
|
/* first point */
|
2000-02-16 09:47:22 +08:00
|
|
|
pdata = (PathPoint*)bzp->path_details->data;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
if (g_slist_length (bzp->path_details) < 5)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0 ; i < 2 ; i++)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
pathpoint = g_new0 (PathPoint, 1);
|
1999-10-30 18:39:48 +08:00
|
|
|
pathpoint->type = (i & 1) ? BEZIER_ANCHOR : BEZIER_CONTROL;
|
1999-03-22 08:51:30 +08:00
|
|
|
pathpoint->x = pdata->x+i;
|
|
|
|
pathpoint->y = pdata->y+i;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
bzp->path_details = g_slist_append (bzp->path_details, pathpoint);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
2000-02-16 09:47:22 +08:00
|
|
|
pathpoint = g_new0 (PathPoint, 1);
|
1999-10-30 18:39:48 +08:00
|
|
|
pdata = path_start_last_seg (bzp->path_details);
|
1999-03-22 08:51:30 +08:00
|
|
|
pathpoint->type = BEZIER_CONTROL;
|
|
|
|
pathpoint->x = pdata->x;
|
|
|
|
pathpoint->y = pdata->y;
|
1999-10-30 18:39:48 +08:00
|
|
|
/* printf("Closing to x,y %d,%d\n",(gint)pdata->x,(gint)pdata->y); */
|
|
|
|
bzp->path_details = g_slist_append (bzp->path_details, pathpoint);
|
1999-05-14 06:53:40 +08:00
|
|
|
bzp->state = BEZIER_EDIT;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
bz_change_name_row_to (gint row,
|
|
|
|
gchar *text)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
pwidget = (PathWidget *)
|
|
|
|
gtk_clist_get_row_data (GTK_CLIST (paths_dialog->paths_list), row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!pwidget)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
g_free (pwidget->bzp->name);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
pwidget->bzp->name = g_strdup (text);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_set_dash_line (GdkGC *gc,
|
|
|
|
gboolean state)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gdk_gc_set_foreground (paths_dialog->gc, &paths_dialog->black);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (state)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_ON_OFF_DASH,
|
|
|
|
GDK_CAP_BUTT, GDK_JOIN_ROUND);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID,
|
|
|
|
GDK_CAP_BUTT, GDK_JOIN_ROUND);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-30 18:39:48 +08:00
|
|
|
clear_pixmap_preview (PathWidget *pwidget)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-12-07 06:44:40 +08:00
|
|
|
guchar *rgb_buf;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-12-07 06:44:40 +08:00
|
|
|
rgb_buf = g_new0 (guchar,
|
|
|
|
(paths_dialog->image_width + 4)
|
|
|
|
*(paths_dialog->image_height + 4) * 3);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-12-07 06:44:40 +08:00
|
|
|
memset (rgb_buf,0xFF,(paths_dialog->image_width + 4)
|
|
|
|
*(paths_dialog->image_height + 4) * 3);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
gdk_draw_rgb_image (pwidget->paths_pixmap,
|
|
|
|
paths_dialog->gc,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
paths_dialog->image_width + 4,
|
|
|
|
paths_dialog->image_height + 4,
|
|
|
|
GDK_RGB_DITHER_NORMAL,
|
|
|
|
rgb_buf,
|
|
|
|
(paths_dialog->image_width + 4)*3);
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
paths_set_dash_line (paths_dialog->gc,FALSE);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gdk_draw_rectangle (pwidget->paths_pixmap,
|
|
|
|
paths_dialog->gc, FALSE, 0, 0,
|
|
|
|
paths_dialog->image_width+3,
|
|
|
|
paths_dialog->image_height+3);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gdk_draw_rectangle (pwidget->paths_pixmap,
|
|
|
|
paths_dialog->gc, FALSE, 1, 1,
|
|
|
|
paths_dialog->image_width+1,
|
|
|
|
paths_dialog->image_height+1);
|
1999-10-28 04:09:46 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
g_free (rgb_buf);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* insrow == -1 -> append else insert at insrow */
|
2000-01-24 02:04:28 +08:00
|
|
|
void
|
2000-02-16 09:47:22 +08:00
|
|
|
paths_add_path (Path *bzp,
|
2000-01-24 02:04:28 +08:00
|
|
|
gint insrow)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* Create a new entry in the list */
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
1999-03-06 07:50:24 +08:00
|
|
|
gint row;
|
1999-04-14 05:50:28 +08:00
|
|
|
gchar *row_data[2];
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
pwidget = g_new0 (PathWidget, 1);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!GTK_WIDGET_REALIZED (paths_dialog->vbox))
|
|
|
|
gtk_widget_realize (paths_dialog->vbox);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 21:01:15 +08:00
|
|
|
paths_dialog_preview_extents ();
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (preview_size)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* Need to add this to the list */
|
2000-02-24 20:35:25 +08:00
|
|
|
pwidget->paths_pixmap = gdk_pixmap_new (paths_dialog->vbox->window,
|
|
|
|
paths_dialog->image_width + 4,
|
|
|
|
paths_dialog->image_height + 4,
|
|
|
|
-1);
|
|
|
|
clear_pixmap_preview (pwidget);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!paths_dialog->pixmap_normal)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
|
|
|
paths_dialog->pixmap_normal =
|
|
|
|
gdk_pixmap_create_from_data (paths_dialog->vbox->window,
|
|
|
|
path_bits,
|
|
|
|
paths_dialog->image_width,
|
|
|
|
paths_dialog->image_height,
|
|
|
|
-1,
|
|
|
|
&paths_dialog->vbox->style->fg[GTK_STATE_SELECTED],
|
|
|
|
&paths_dialog->vbox->style->bg[GTK_STATE_SELECTED]);
|
|
|
|
paths_dialog->pixmap_selected =
|
|
|
|
gdk_pixmap_create_from_data (paths_dialog->vbox->window,
|
|
|
|
path_bits,
|
|
|
|
paths_dialog->image_width,
|
|
|
|
paths_dialog->image_height,
|
|
|
|
-1,
|
|
|
|
&paths_dialog->vbox->style->fg[GTK_STATE_NORMAL],
|
|
|
|
&paths_dialog->vbox->style->bg[GTK_STATE_SELECTED]);
|
|
|
|
}
|
|
|
|
pwidget->paths_pixmap = paths_dialog->pixmap_normal;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!paths_dialog->pixmap_locked_normal)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
1999-07-08 03:09:52 +08:00
|
|
|
paths_dialog->pixmap_locked_normal =
|
|
|
|
gdk_pixmap_create_from_data (paths_dialog->vbox->window,
|
|
|
|
locked_bits, locked_width, locked_height, -1,
|
|
|
|
&paths_dialog->vbox->style->fg[GTK_STATE_NORMAL],
|
|
|
|
&paths_dialog->vbox->style->white);
|
|
|
|
paths_dialog->pixmap_locked_selected =
|
|
|
|
gdk_pixmap_create_from_data (paths_dialog->vbox->window,
|
|
|
|
locked_bits, locked_width, locked_height, -1,
|
|
|
|
&paths_dialog->vbox->style->fg[GTK_STATE_SELECTED],
|
|
|
|
&paths_dialog->vbox->style->bg[GTK_STATE_SELECTED]);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gtk_clist_set_row_height (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->image_height + 6);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
row_data[0] = "";
|
1999-04-14 05:50:28 +08:00
|
|
|
row_data[1] = "";
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (insrow == -1)
|
|
|
|
row = gtk_clist_append (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row_data);
|
1999-03-06 07:50:24 +08:00
|
|
|
else
|
2000-02-24 20:35:25 +08:00
|
|
|
row = gtk_clist_insert (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
insrow,
|
|
|
|
row_data);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gtk_clist_set_pixtext (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
1,
|
|
|
|
bzp->name,
|
|
|
|
2,
|
|
|
|
pwidget->paths_pixmap,
|
|
|
|
NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gtk_clist_set_row_data_full (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
(gpointer) pwidget,
|
|
|
|
clear_pathwidget);
|
|
|
|
|
|
|
|
gtk_signal_handler_block (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
|
|
|
gtk_clist_select_row (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
|
|
|
1);
|
|
|
|
gtk_signal_handler_unblock (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
pwidget->bzp = bzp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_preview_extents (void)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
GimpImage *gimage;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
if (!paths_dialog)
|
|
|
|
return;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (! (gimage = paths_dialog->gimage))
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->gimage_width = gimage->width;
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->gimage_height = gimage->height;
|
|
|
|
|
|
|
|
/* Get the image width and height variables, based on the gimage */
|
|
|
|
if (gimage->width > gimage->height)
|
|
|
|
paths_dialog->ratio = (double) preview_size / (double) gimage->width;
|
|
|
|
else
|
|
|
|
paths_dialog->ratio = (double) preview_size / (double) gimage->height;
|
|
|
|
|
|
|
|
if (preview_size)
|
|
|
|
{
|
|
|
|
paths_dialog->image_width = (int) (paths_dialog->ratio * gimage->width);
|
|
|
|
paths_dialog->image_height = (int) (paths_dialog->ratio * gimage->height);
|
|
|
|
if (paths_dialog->image_width < 1) paths_dialog->image_width = 1;
|
|
|
|
if (paths_dialog->image_height < 1) paths_dialog->image_height = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->image_width = path_width;
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->image_height = path_height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_select_row (GtkWidget *widget,
|
|
|
|
gint row,
|
|
|
|
gint column,
|
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierSelect * bsel;
|
|
|
|
GDisplay *gdisp;
|
1999-04-14 05:50:28 +08:00
|
|
|
gint last_row;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
pwidget = (PathWidget *) gtk_clist_get_row_data (GTK_CLIST (widget), row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!pwidget ||
|
|
|
|
(paths_dialog->current_path_list->last_selected_row == row &&
|
|
|
|
paths_dialog->been_selected == TRUE))
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
if (column)
|
1999-04-14 05:50:28 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
last_row = paths_dialog->current_path_list->last_selected_row;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*)g_slist_nth_data(paths_dialog->current_path_list->bz_paths,row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
g_return_if_fail(bzp != NULL);
|
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
if(column == 0)
|
|
|
|
{
|
|
|
|
if(bzp->locked == 0)
|
|
|
|
{
|
|
|
|
bzp->locked = 1;
|
1999-07-08 03:09:52 +08:00
|
|
|
if (paths_dialog->selected_row_num == row)
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_selected,
|
|
|
|
NULL);
|
1999-07-08 03:09:52 +08:00
|
|
|
else
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_normal,
|
|
|
|
NULL);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gint tmprow;
|
|
|
|
|
|
|
|
bzp->locked = 0;
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_text (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
"");
|
1999-04-14 05:50:28 +08:00
|
|
|
/* There should be an easier way of updating the preview! */
|
1999-10-30 18:39:48 +08:00
|
|
|
bsel = path_to_beziersel (bzp);
|
1999-04-14 05:50:28 +08:00
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = row;
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_update_preview (bsel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bsel);
|
1999-04-14 05:50:28 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
paths_dialog->selected_row_num = tmprow;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Put hightlight back on the old original selection */
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_signal_handler_block (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_select_row (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
last_row,
|
|
|
|
1);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_signal_handler_unblock (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
paths_dialog->selected_row_num = row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = row;
|
|
|
|
paths_dialog->been_selected = TRUE;
|
|
|
|
|
1999-07-08 03:09:52 +08:00
|
|
|
if(bzp->locked)
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_selected,
|
|
|
|
NULL);
|
1999-07-08 03:09:52 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
bsel = path_to_beziersel (bzp);
|
|
|
|
gdisp = gdisplays_check_valid (paths_dialog->current_path_list->gdisp,
|
|
|
|
paths_dialog->gimage);
|
|
|
|
if (!gdisp)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-02 08:41:11 +08:00
|
|
|
/*g_warning("Lost image which bezier curve belonged to");*/
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bsel);
|
|
|
|
paths_update_preview (bsel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bsel);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-07-08 03:09:52 +08:00
|
|
|
paths_unselect_row (GtkWidget *widget,
|
|
|
|
gint row,
|
|
|
|
gint column,
|
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
pwidget = (PathWidget *) gtk_clist_get_row_data (GTK_CLIST (widget), row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!pwidget)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
1999-07-08 03:09:52 +08:00
|
|
|
|
1999-07-11 20:08:01 +08:00
|
|
|
bzp = pwidget->bzp;
|
1999-07-08 03:09:52 +08:00
|
|
|
|
1999-07-11 20:08:01 +08:00
|
|
|
g_return_if_fail (bzp != NULL);
|
1999-07-08 03:09:52 +08:00
|
|
|
|
|
|
|
if (column && bzp->locked)
|
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
1999-07-08 03:09:52 +08:00
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_normal,
|
|
|
|
NULL);
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
paths_dialog_update (GimpImage* gimage)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
PathList* new_path_list;
|
1999-03-06 07:50:24 +08:00
|
|
|
GSList *plist;
|
|
|
|
gint loop;
|
|
|
|
gint tmprow;
|
|
|
|
|
|
|
|
if (!paths_dialog || !gimage)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (paths_dialog->gimage == gimage &&
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->current_path_list ==
|
2000-02-16 09:47:22 +08:00
|
|
|
(PathList*) gimp_image_get_paths (gimage))
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->gimage = gimage;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
paths_dialog_preview_extents ();
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* clear clist out */
|
|
|
|
gtk_clist_freeze (GTK_CLIST (paths_dialog->paths_list));
|
|
|
|
gtk_clist_clear (GTK_CLIST (paths_dialog->paths_list));
|
|
|
|
gtk_clist_thaw (GTK_CLIST (paths_dialog->paths_list));
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
/* Find bz list */
|
2000-02-16 09:47:22 +08:00
|
|
|
new_path_list = (PathList*) gimp_image_get_paths (gimage);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
paths_dialog->current_path_list = new_path_list;
|
|
|
|
paths_dialog->been_selected = FALSE;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_set_menu_sensitivity ();
|
|
|
|
|
|
|
|
paths_dialog_set_default_op ();
|
|
|
|
|
|
|
|
if (!new_path_list)
|
|
|
|
return;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* update the clist to reflect this images bz list */
|
|
|
|
/* go around the image list populating the clist */
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (gimage != new_path_list->gimage)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_warning("paths list: internal list error");
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
plist = new_path_list->bz_paths;
|
|
|
|
loop = 0;
|
|
|
|
|
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
1999-10-30 18:39:48 +08:00
|
|
|
while (plist)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_update_paths (plist->data,loop);
|
1999-03-06 07:50:24 +08:00
|
|
|
loop++;
|
1999-10-30 18:39:48 +08:00
|
|
|
plist = g_slist_next (plist);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
paths_dialog->selected_row_num = tmprow;
|
|
|
|
|
|
|
|
/* select last one */
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_signal_handler_block (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
|
|
|
gtk_clist_select_row (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
|
|
|
1);
|
|
|
|
gtk_signal_handler_unblock (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selsigid);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_moveto (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
|
|
|
0,
|
|
|
|
0.5,
|
|
|
|
0.0);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_update_paths (gpointer data,
|
|
|
|
gint row)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-10-30 18:39:48 +08:00
|
|
|
BezierSelect *bezier_sel;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
paths_add_path ((bzp = (Path*) data), -1);
|
1999-03-06 07:50:24 +08:00
|
|
|
/* Now fudge the drawing....*/
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_sel = path_to_beziersel (bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = row;
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_update_preview (bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
1999-07-08 03:09:52 +08:00
|
|
|
if (bzp->locked)
|
|
|
|
{
|
|
|
|
if (paths_dialog->selected_row_num == row)
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_selected,
|
|
|
|
NULL);
|
1999-07-08 03:09:52 +08:00
|
|
|
else
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixmap (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
0,
|
|
|
|
paths_dialog->pixmap_locked_normal,
|
|
|
|
NULL);
|
1999-07-08 03:09:52 +08:00
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
do_rename_paths_callback (GtkWidget *widget,
|
2000-02-11 05:54:12 +08:00
|
|
|
gchar *text,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
GdkBitmap *mask;
|
|
|
|
guint8 spacing;
|
|
|
|
GdkPixmap *pixmap;
|
|
|
|
|
2000-02-11 05:54:12 +08:00
|
|
|
if (!(GTK_CLIST (data)->selection))
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_get_pixtext (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selected_row_num,
|
|
|
|
1,
|
|
|
|
NULL,
|
|
|
|
&spacing,
|
|
|
|
&pixmap,
|
|
|
|
&mask);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-11 05:54:12 +08:00
|
|
|
gtk_clist_set_pixtext (GTK_CLIST (data),
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog->selected_row_num,
|
|
|
|
1,
|
|
|
|
text,
|
|
|
|
spacing,
|
|
|
|
pixmap,
|
|
|
|
mask);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
bz_change_name_row_to (paths_dialog->selected_row_num, text);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
paths_dialog_edit_path_query (GtkWidget *widget)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-09-28 01:58:10 +08:00
|
|
|
GtkWidget *qbox;
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
GdkBitmap *mask;
|
1999-03-06 07:50:24 +08:00
|
|
|
gchar *text;
|
|
|
|
gint ret;
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* Get the current name */
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
ret = gtk_clist_get_pixtext (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->selected_row_num,
|
|
|
|
1,
|
|
|
|
&text,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&mask);
|
|
|
|
|
2000-02-01 06:59:22 +08:00
|
|
|
qbox = gimp_query_string_box (_("Edit Path Attributes"),
|
1999-09-28 01:58:10 +08:00
|
|
|
gimp_standard_help_func,
|
1999-10-04 16:40:33 +08:00
|
|
|
"paths/dialogs/rename_path.html",
|
1999-09-28 01:58:10 +08:00
|
|
|
_("Enter a new name for the path"),
|
|
|
|
text,
|
|
|
|
NULL, NULL,
|
|
|
|
do_rename_paths_callback, widget);
|
|
|
|
gtk_widget_show (qbox);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
paths_list_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event)
|
|
|
|
{
|
|
|
|
GdkEventButton *bevent;
|
1999-04-14 05:50:28 +08:00
|
|
|
static gint last_row = -1;
|
1999-10-25 04:16:48 +08:00
|
|
|
gint this_column;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case GDK_BUTTON_PRESS:
|
|
|
|
bevent = (GdkEventButton *) event;
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!gtk_clist_get_selection_info (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
bevent->x,
|
|
|
|
bevent->y,
|
|
|
|
&last_row, &this_column))
|
|
|
|
last_row = -1;
|
|
|
|
else if (paths_dialog->selected_row_num != last_row)
|
1999-03-06 07:50:24 +08:00
|
|
|
last_row = -1;
|
|
|
|
|
1999-11-20 20:12:41 +08:00
|
|
|
if (bevent->button == 3)
|
1999-10-25 04:16:48 +08:00
|
|
|
gtk_menu_popup (GTK_MENU (paths_dialog->ops_menu),
|
|
|
|
NULL, NULL, NULL, NULL, bevent->button, bevent->time);
|
1999-03-06 07:50:24 +08:00
|
|
|
break;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
case GDK_2BUTTON_PRESS:
|
|
|
|
bevent = (GdkEventButton *) event;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (last_row != -1 &&
|
|
|
|
gtk_clist_get_selection_info (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
bevent->x,
|
|
|
|
bevent->y,
|
|
|
|
NULL, &this_column))
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
if (this_column == 1)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
1999-09-28 01:58:10 +08:00
|
|
|
paths_dialog_edit_path_query (widget);
|
1999-04-14 05:50:28 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
static PathList *
|
2000-02-16 21:52:33 +08:00
|
|
|
path_add_to_current (PathList *pip,
|
|
|
|
Path *bzp,
|
|
|
|
GimpImage *gimage,
|
|
|
|
gint pos)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* add bzp to current list */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!pip)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* This image does not have a list */
|
2000-02-16 09:47:22 +08:00
|
|
|
pip = path_list_new (gimage, 0, NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* add to gimage */
|
1999-10-30 18:39:48 +08:00
|
|
|
gimp_image_set_paths (gimage, pip);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (pos < 0)
|
|
|
|
pip->bz_paths = g_slist_append (pip->bz_paths,bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
else
|
1999-10-30 18:39:48 +08:00
|
|
|
pip->bz_paths = g_slist_insert (pip->bz_paths,bzp,pos);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
return pip;
|
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
static Path*
|
2000-02-16 21:52:33 +08:00
|
|
|
paths_dialog_new_path (PathList **plp,
|
|
|
|
gpointer points,
|
|
|
|
GimpImage *gimage,
|
|
|
|
gint pos)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
static gint nseed = 0;
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
bzp = path_dialog_new (gimage, nseed++, points);
|
|
|
|
*plp = path_add_to_current (*plp, bzp, gimage, pos);
|
|
|
|
|
|
|
|
return (bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_new_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-19 04:55:25 +08:00
|
|
|
BezierSelect * bsel;
|
|
|
|
GDisplay *gdisp;
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
bzp = paths_dialog_new_path (&paths_dialog->current_path_list,
|
|
|
|
NULL,
|
|
|
|
paths_dialog->gimage,
|
|
|
|
paths_dialog->selected_row_num);
|
|
|
|
|
|
|
|
paths_add_path (bzp, paths_dialog->selected_row_num);
|
|
|
|
|
|
|
|
paths_dialog_set_menu_sensitivity ();
|
|
|
|
|
|
|
|
paths_dialog_set_default_op ();
|
1999-10-19 04:55:25 +08:00
|
|
|
|
|
|
|
/* Clear the path display out */
|
1999-10-30 18:39:48 +08:00
|
|
|
bsel = path_to_beziersel (bzp);
|
|
|
|
gdisp = gdisplays_check_valid (paths_dialog->current_path_list->gdisp,
|
|
|
|
paths_dialog->gimage);
|
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bsel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bsel);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_delete_path_callback (GtkWidget *widget,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-03-06 07:50:24 +08:00
|
|
|
gboolean new_sz;
|
|
|
|
gint row = paths_dialog->selected_row_num;
|
1999-09-25 07:01:10 +08:00
|
|
|
BezierSelect *bsel = NULL;
|
|
|
|
GDisplay *gdisp = NULL;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure & delete its content */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Remove from list */
|
1999-10-30 18:39:48 +08:00
|
|
|
plp->bz_paths = g_slist_remove (plp->bz_paths, bzp);
|
|
|
|
new_sz = (g_slist_length (plp->bz_paths) > 0);
|
2000-02-16 09:47:22 +08:00
|
|
|
path_free (bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-07-11 20:08:01 +08:00
|
|
|
/* Remove from the clist ... */
|
|
|
|
gtk_signal_handler_block_by_data (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog);
|
|
|
|
gtk_clist_remove (GTK_CLIST (paths_dialog->paths_list), row);
|
|
|
|
gtk_signal_handler_unblock_by_data (GTK_OBJECT (paths_dialog->paths_list),
|
|
|
|
paths_dialog);
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* If now empty free everything up */
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plp->bz_paths || g_slist_length (plp->bz_paths) == 0)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_signal_disconnect (GTK_OBJECT (plp->gimage),
|
|
|
|
plp->sig_id);
|
1999-09-25 07:01:10 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gimp_image_set_paths (plp->gimage, NULL);
|
2000-02-16 09:47:22 +08:00
|
|
|
path_list_free (plp);
|
1999-09-25 07:01:10 +08:00
|
|
|
|
|
|
|
/* Paste an empty BezierSelect to the current display to emulate an empty path list */
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
bsel = g_new0 (BezierSelect, 1);
|
|
|
|
bezier_select_reset (bsel);
|
|
|
|
gdisp = gdisplays_check_valid (paths_dialog->current_path_list->gdisp,
|
|
|
|
paths_dialog->gimage);
|
1999-09-25 07:01:10 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bsel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bsel);
|
1999-09-25 07:01:10 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->current_path_list = NULL;
|
2000-01-24 02:04:28 +08:00
|
|
|
|
|
|
|
paths_dialog_set_menu_sensitivity ();
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!new_sz)
|
|
|
|
paths_dialog_set_default_op ();
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_paste_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
|
|
|
PathPoint* pp;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
gint tmprow;
|
|
|
|
GDisplay *gdisp;
|
|
|
|
|
|
|
|
gint row = paths_dialog->selected_row_num;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!copy_pp)
|
1999-05-14 06:53:40 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-05-14 06:53:40 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!plp)
|
1999-05-14 06:53:40 +08:00
|
|
|
return;
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
if (bzp->path_details)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
|
|
|
pp = bzp->path_details->data;
|
|
|
|
pp->type = BEZIER_MOVE;
|
1999-10-30 18:39:48 +08:00
|
|
|
bzp->path_details = g_slist_concat (copy_pp->path_details,
|
|
|
|
bzp->path_details);
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bzp->closed = TRUE;
|
|
|
|
bzp->path_details = copy_pp->path_details;
|
|
|
|
bzp->state = copy_pp->state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* First point on new curve is a moveto */
|
|
|
|
copy_pp->path_details = NULL;
|
2000-02-16 09:47:22 +08:00
|
|
|
path_free (copy_pp);
|
1999-05-14 06:53:40 +08:00
|
|
|
copy_pp = NULL;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_set_menu_sensitivity ();
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
/* Now fudge the drawing....*/
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_sel = path_to_beziersel (bzp);
|
1999-05-14 06:53:40 +08:00
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = row;
|
1999-10-30 18:39:48 +08:00
|
|
|
gdisp = gdisplays_check_valid (paths_dialog->current_path_list->gdisp,
|
|
|
|
paths_dialog->gimage);
|
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bezier_sel);
|
|
|
|
paths_update_preview (bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-05-14 06:53:40 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_copy_path_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-05-14 06:53:40 +08:00
|
|
|
gint row = paths_dialog->selected_row_num;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-05-14 06:53:40 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!bzp->path_details || g_slist_length (bzp->path_details) <= 5)
|
1999-05-14 06:53:40 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* And store in static array */
|
1999-10-30 18:39:48 +08:00
|
|
|
copy_pp = path_copy (paths_dialog->gimage, bzp);
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
/* All paths that are in the cut buffer must be closed */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!copy_pp->closed)
|
|
|
|
path_close (copy_pp);
|
|
|
|
|
|
|
|
paths_dialog_set_menu_sensitivity ();
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_dup_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierSelect * bezier_sel;
|
1999-10-19 04:55:25 +08:00
|
|
|
gint row;
|
1999-03-06 07:50:24 +08:00
|
|
|
gint tmprow;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-19 04:55:25 +08:00
|
|
|
row = paths_dialog->current_path_list->last_selected_row;
|
1999-03-06 07:50:24 +08:00
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Insert at the current position */
|
1999-10-30 18:39:48 +08:00
|
|
|
bzp = path_copy (paths_dialog->gimage, bzp);
|
|
|
|
plp->bz_paths = g_slist_insert (plp->bz_paths, bzp, row);
|
|
|
|
paths_add_path (bzp, row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Now fudge the drawing....*/
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_sel = path_to_beziersel (bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = row;
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_update_preview (bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
}
|
|
|
|
|
1999-10-25 04:16:48 +08:00
|
|
|
static void
|
|
|
|
paths_dialog_advanced_to_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-07-10 05:52:00 +08:00
|
|
|
{
|
|
|
|
ProcRecord *proc_rec;
|
|
|
|
Argument *args;
|
|
|
|
GimpImage *gimage;
|
|
|
|
|
|
|
|
/* find the sel2path PDB record */
|
|
|
|
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path_advanced")) == NULL)
|
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_message ("paths_dialog_adavanced_to_path_callback(): selection to path (advanced) procedure lookup failed");
|
1999-07-10 05:52:00 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimage = paths_dialog->gimage;
|
|
|
|
|
|
|
|
/* plug-in arguments as if called by <Image>/Filters/... */
|
|
|
|
args = g_new (Argument, 3);
|
|
|
|
args[0].arg_type = PDB_INT32;
|
|
|
|
args[0].value.pdb_int = RUN_INTERACTIVE;
|
|
|
|
args[1].arg_type = PDB_IMAGE;
|
|
|
|
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
|
|
|
|
args[2].arg_type = PDB_DRAWABLE;
|
|
|
|
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
plug_in_run (proc_rec, args, 3, FALSE, TRUE,
|
|
|
|
(gimage_active_drawable (gimage))->ID);
|
1999-07-10 05:52:00 +08:00
|
|
|
|
|
|
|
g_free (args);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-10-25 04:16:48 +08:00
|
|
|
static void
|
|
|
|
paths_dialog_null_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-07-10 05:52:00 +08:00
|
|
|
{
|
|
|
|
/* Maybe some more here later? */
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_sel_to_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-07-10 05:52:00 +08:00
|
|
|
{
|
|
|
|
ProcRecord *proc_rec;
|
|
|
|
Argument *args;
|
2000-06-05 02:33:01 +08:00
|
|
|
GimpImage *gimage;
|
|
|
|
GDisplay *gdisp;
|
1999-07-10 05:52:00 +08:00
|
|
|
|
|
|
|
/* find the sel2path PDB record */
|
|
|
|
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path")) == NULL)
|
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_message ("paths_dialog_sel_to_path_callback(): selection to path procedure lookup failed");
|
1999-07-10 05:52:00 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimage = paths_dialog->gimage;
|
|
|
|
|
|
|
|
/* plug-in arguments as if called by <Image>/Filters/... */
|
|
|
|
args = g_new (Argument, 3);
|
|
|
|
args[0].arg_type = PDB_INT32;
|
|
|
|
args[0].value.pdb_int = RUN_INTERACTIVE;
|
|
|
|
args[1].arg_type = PDB_IMAGE;
|
|
|
|
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
|
|
|
|
args[2].arg_type = PDB_DRAWABLE;
|
|
|
|
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
|
|
|
|
|
2000-06-05 02:33:01 +08:00
|
|
|
/* get the display by asking the current context */
|
|
|
|
gdisp = gimp_context_get_display (gimp_context_get_user ());
|
1999-10-30 18:39:48 +08:00
|
|
|
plug_in_run (proc_rec, args, 3, FALSE, TRUE,
|
2000-06-05 02:33:01 +08:00
|
|
|
gdisp? gdisp->ID : 0);
|
1999-07-10 05:52:00 +08:00
|
|
|
|
|
|
|
g_free (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_path_to_sel_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
GDisplay * gdisp;
|
|
|
|
gint row = paths_dialog->selected_row_num;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-06-06 21:24:26 +08:00
|
|
|
/* Return if no point list */
|
|
|
|
if (!bzp->path_details)
|
|
|
|
return;
|
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
/* Now do the selection....*/
|
1999-10-30 18:39:48 +08:00
|
|
|
gdisp = gdisplays_check_valid (paths_dialog->current_path_list->gdisp,
|
|
|
|
paths_dialog->gimage);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!bzp->closed)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzpcopy = path_copy (paths_dialog->gimage,bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
/* Close it */
|
1999-10-30 18:39:48 +08:00
|
|
|
path_close (bzpcopy);
|
|
|
|
bezier_sel = path_to_beziersel (bzpcopy);
|
2000-02-16 09:47:22 +08:00
|
|
|
path_free (bzpcopy);
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_to_selection (bezier_sel, gdisp);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
|
|
|
/* Force display to show no closed curve */
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_sel = path_to_beziersel (bzp);
|
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_sel = path_to_beziersel (bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_to_selection (bezier_sel, gdisp);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_stroke_path_callback (GtkWidget *widget,
|
1999-10-30 18:39:48 +08:00
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-03-06 07:50:24 +08:00
|
|
|
gint row = paths_dialog->selected_row_num;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
g_return_if_fail (paths_dialog->current_path_list != NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->selected_row_num < 0)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*) g_slist_nth_data (plp->bz_paths, row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Now do the stroke....*/
|
2000-02-16 09:47:22 +08:00
|
|
|
path_stroke (paths_dialog->gimage, paths_dialog->current_path_list, bzp);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
2000-02-01 06:59:22 +08:00
|
|
|
void
|
|
|
|
paths_dialog_edit_path_attributes_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
if (paths_dialog && paths_dialog->paths_list)
|
|
|
|
paths_dialog_edit_path_query (paths_dialog->paths_list);
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_map_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
if (!paths_dialog)
|
|
|
|
return;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
gtk_window_add_accel_group (GTK_WINDOW (lc_dialog->shell),
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->accel_group);
|
|
|
|
|
|
|
|
paths_dialog_preview_extents ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_unmap_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
if (!paths_dialog)
|
|
|
|
return;
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
gtk_window_remove_accel_group (GTK_WINDOW (lc_dialog->shell),
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->accel_group);
|
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
void
|
|
|
|
paths_dialog_destroy_cb (GtkObject *object,
|
|
|
|
gpointer data)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
GimpImage *gimage = (GimpImage *)object;
|
|
|
|
PathList* new_path_list;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!paths_dialog)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog->current_path_list &&
|
|
|
|
gimage == paths_dialog->current_path_list->gimage)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* showing could be last so remove here.. might get
|
|
|
|
done again if not the last one
|
|
|
|
*/
|
|
|
|
paths_dialog->current_path_list = NULL;
|
|
|
|
paths_dialog->been_selected = FALSE;
|
1999-10-30 18:39:48 +08:00
|
|
|
|
|
|
|
gtk_clist_freeze (GTK_CLIST (paths_dialog->paths_list));
|
|
|
|
gtk_clist_clear (GTK_CLIST (paths_dialog->paths_list));
|
|
|
|
gtk_clist_thaw (GTK_CLIST (paths_dialog->paths_list));
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find bz list */
|
2000-02-16 09:47:22 +08:00
|
|
|
new_path_list = (PathList*) gimp_image_get_paths (gimage);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
if (!new_path_list)
|
|
|
|
return; /* Already removed - signal handler just left in the air */
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
path_list_free (new_path_list);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gimp_image_set_paths (gimage, NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Functions used from the bezier code .. tie in with this code */
|
|
|
|
static GSList *
|
1999-10-25 04:16:48 +08:00
|
|
|
pathpoints_create (BezierSelect *sel)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
GSList *list = NULL;
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint *pathpoint;
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierPoint *pts = (BezierPoint *) sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *start_pnt = pts;
|
|
|
|
gint need_move = 0;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
for (i=0; i< sel->num_points; i++)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
pathpoint = path_point_new ((need_move)?BEZIER_MOVE:pts->type,
|
|
|
|
(gdouble)pts->x,(gdouble)pts->y);
|
1999-05-14 06:53:40 +08:00
|
|
|
need_move = 0;
|
2000-02-16 09:47:22 +08:00
|
|
|
list = g_slist_append (list, pathpoint);
|
1999-05-14 06:53:40 +08:00
|
|
|
if(pts->next_curve)
|
2000-02-16 09:47:22 +08:00
|
|
|
{
|
|
|
|
/* The curve must loop back on itself */
|
|
|
|
if(start_pnt != pts->next)
|
|
|
|
g_warning("Curve of of sync");
|
|
|
|
|
|
|
|
need_move = 1;
|
|
|
|
pts = pts->next_curve;
|
|
|
|
start_pnt = pts;
|
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
else
|
2000-02-16 09:47:22 +08:00
|
|
|
{
|
|
|
|
pts = pts->next;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
2000-02-16 21:52:33 +08:00
|
|
|
return (list);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
GSList *
|
1999-10-25 04:16:48 +08:00
|
|
|
pathpoints_copy (GSList *list)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
GSList *slcopy = NULL;
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint* pdata;
|
|
|
|
PathPoint* pathpoint;
|
1999-03-06 07:50:24 +08:00
|
|
|
while(list)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
pathpoint = g_new0(PathPoint,1);
|
|
|
|
pdata = (PathPoint*)list->data;
|
1999-03-22 08:51:30 +08:00
|
|
|
pathpoint->type = pdata->type;
|
|
|
|
pathpoint->x = pdata->x;
|
|
|
|
pathpoint->y = pdata->y;
|
|
|
|
slcopy = g_slist_append(slcopy,pathpoint);
|
1999-03-06 07:50:24 +08:00
|
|
|
list = g_slist_next(list);
|
|
|
|
}
|
|
|
|
return slcopy;
|
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
void
|
|
|
|
pathpoints_free (GSList *list)
|
|
|
|
{
|
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_slist_foreach (list, (GFunc)path_point_free, NULL);
|
|
|
|
g_slist_free (list);
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static void
|
2000-02-16 21:52:33 +08:00
|
|
|
paths_update_bzpath (PathList *plp,
|
|
|
|
BezierSelect *bezier_sel)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* p;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
p = (Path*)g_slist_nth_data(plp->bz_paths,plp->last_selected_row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-22 08:51:30 +08:00
|
|
|
if(p->path_details)
|
2000-02-16 09:47:22 +08:00
|
|
|
pathpoints_free (p->path_details);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-22 08:51:30 +08:00
|
|
|
p->path_details = pathpoints_create(bezier_sel);
|
|
|
|
p->closed = bezier_sel->closed;
|
|
|
|
p->state = bezier_sel->state;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2000-02-16 21:52:33 +08:00
|
|
|
paths_replaced_current (PathList *plp,
|
|
|
|
BezierSelect *bezier_sel)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* Is there a currently selected path in this image? */
|
1999-03-13 06:04:30 +08:00
|
|
|
/* ALT if(paths_dialog && plp && */
|
|
|
|
if(plp &&
|
1999-03-06 07:50:24 +08:00
|
|
|
plp->last_selected_row >= 0)
|
|
|
|
{
|
|
|
|
paths_update_bzpath(plp,bezier_sel);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
static gint
|
1999-10-25 04:16:48 +08:00
|
|
|
number_curves_in_path (GSList *plist)
|
1999-05-14 06:53:40 +08:00
|
|
|
{
|
|
|
|
gint count = 0;
|
|
|
|
while(plist)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
if(((PathPoint*)(plist->data))->type == BEZIER_MOVE &&
|
1999-05-14 06:53:40 +08:00
|
|
|
g_slist_next(plist))
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
plist = g_slist_next(plist);
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_draw_segment_points (BezierSelect *bezier_sel,
|
|
|
|
GdkPoint *pnt,
|
|
|
|
int npoints,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* hopefully the image points are already in image space co-ords.
|
|
|
|
* so just scale by ratio factor and draw 'em
|
|
|
|
*/
|
|
|
|
gint loop;
|
|
|
|
gint pcount = 0;
|
|
|
|
GdkPoint * copy_pnt = g_new(GdkPoint,npoints);
|
|
|
|
GdkPoint * cur_pnt = copy_pnt;
|
|
|
|
GdkPoint * last_pnt = NULL;
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
1999-03-06 07:50:24 +08:00
|
|
|
gint row;
|
1999-10-30 18:39:48 +08:00
|
|
|
PathCounts *curve_count = (PathCounts *) udata;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* we could remove duplicate points here */
|
|
|
|
|
|
|
|
for(loop = 0; loop < npoints; loop++)
|
|
|
|
{
|
|
|
|
/* The "2" is because we have a boarder */
|
|
|
|
cur_pnt->x = 2+(int) (paths_dialog->ratio * pnt->x);
|
|
|
|
cur_pnt->y = 2+(int) (paths_dialog->ratio * pnt->y);
|
|
|
|
pnt++;
|
|
|
|
if(last_pnt &&
|
|
|
|
last_pnt->x == cur_pnt->x &&
|
|
|
|
last_pnt->y == cur_pnt->y)
|
|
|
|
{
|
|
|
|
/* same as last ... don't need this one */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* printf("converting %d [%d,%d] => [%d,%d]\n", */
|
|
|
|
/* pcount,(int)pnt->x,(int)pnt->y,(int)cur_pnt->x,(int)cur_pnt->y); */
|
|
|
|
last_pnt = cur_pnt;
|
|
|
|
pcount++;
|
|
|
|
cur_pnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
row = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
pwidget = (PathWidget *)
|
|
|
|
gtk_clist_get_row_data (GTK_CLIST (paths_dialog->paths_list), row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-07-15 00:02:32 +08:00
|
|
|
if(pcount < 2)
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
g_return_if_fail(pwidget != NULL);
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(curve_count->c_count.count < curve_count->total_count ||
|
|
|
|
bezier_sel->closed)
|
|
|
|
paths_set_dash_line(paths_dialog->gc,FALSE);
|
|
|
|
else
|
|
|
|
paths_set_dash_line(paths_dialog->gc,TRUE);
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
gdk_draw_lines (pwidget->paths_pixmap,
|
|
|
|
paths_dialog->gc, copy_pnt, pcount);
|
|
|
|
|
|
|
|
g_free(copy_pnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_update_preview (BezierSelect *bezier_sel)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
gint row;
|
1999-10-30 18:39:48 +08:00
|
|
|
PathCounts curve_count;
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if(paths_dialog &&
|
|
|
|
paths_dialog->current_path_list &&
|
|
|
|
(row = paths_dialog->current_path_list->last_selected_row) >= 0 &&
|
|
|
|
preview_size)
|
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
PathWidget *pwidget;
|
|
|
|
|
|
|
|
pwidget = (PathWidget *)
|
|
|
|
gtk_clist_get_row_data (GTK_CLIST (paths_dialog->paths_list), row);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Clear pixmap */
|
1999-10-30 18:39:48 +08:00
|
|
|
clear_pixmap_preview (pwidget);
|
|
|
|
|
|
|
|
curve_count.total_count =
|
|
|
|
number_curves_in_path (pwidget->bzp->path_details);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* update .. */
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_draw_curve (bezier_sel, paths_draw_segment_points,
|
|
|
|
IMAGE_COORDS, &curve_count);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* update the pixmap */
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_set_pixtext (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
row,
|
|
|
|
1,
|
2000-02-16 09:47:22 +08:00
|
|
|
pwidget->bzp->name,
|
1999-10-30 18:39:48 +08:00
|
|
|
2,
|
|
|
|
pwidget->paths_pixmap,
|
|
|
|
NULL);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_new_point_callback (GtkWidget *widget,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_select_mode (EXTEND_NEW);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_add_point_callback (GtkWidget *widget,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_select_mode (EXTEND_ADD);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_delete_point_callback (GtkWidget *widget,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_select_mode (EXTEND_REMOVE);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_dialog_edit_point_callback (GtkWidget *widget,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
bezier_select_mode (EXTEND_EDIT);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-05-15 07:16:58 +08:00
|
|
|
void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_flush (void)
|
1999-05-15 07:16:58 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
GimpImage *gimage;
|
1999-05-15 07:16:58 +08:00
|
|
|
|
|
|
|
if (!paths_dialog)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(gimage = paths_dialog->gimage))
|
|
|
|
return;
|
|
|
|
|
|
|
|
gimage = paths_dialog->gimage;
|
|
|
|
|
1999-07-07 05:19:34 +08:00
|
|
|
/* Check current_path_list since we might not have a valid preview.
|
|
|
|
* which means it should be removed.. Or if we have one
|
|
|
|
* created it!
|
|
|
|
*/
|
|
|
|
if ((paths_dialog->current_path_list == NULL) ||
|
|
|
|
(gimage->width != paths_dialog->gimage_width) ||
|
1999-05-15 07:16:58 +08:00
|
|
|
(gimage->height != paths_dialog->gimage_height))
|
|
|
|
{
|
|
|
|
paths_dialog->gimage = NULL;
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_update (gimage);
|
1999-05-15 07:16:58 +08:00
|
|
|
}
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_first_button_press (BezierSelect *bezier_sel,
|
|
|
|
GDisplay *gdisp)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* First time a button is pressed in this display */
|
|
|
|
/* We have two choices here
|
|
|
|
Either:-
|
|
|
|
1) We already have a paths item in the list.
|
|
|
|
=> In this case the new one replaces the current entry. We
|
|
|
|
need a callback into the bezier code to free things up.
|
|
|
|
2) We don't have an entry.
|
|
|
|
=> Create a new one and add this curve.
|
|
|
|
|
|
|
|
In either case we need to update the preview widget..
|
|
|
|
|
|
|
|
All this of course depends on the fact that gdisp is the same
|
|
|
|
as before.
|
|
|
|
*/
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
|
|
|
PathList* plp;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
if(paths_dialog)
|
|
|
|
{
|
|
|
|
paths_dialog->been_selected = FALSE;
|
|
|
|
/*ALT return;*/
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Button not pressed in this image...
|
|
|
|
* find which one it was pressed in if any.
|
|
|
|
*/
|
2000-02-16 09:47:22 +08:00
|
|
|
plp = (PathList*)gimp_image_get_paths(gdisp->gimage);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Since beziers are part of the save format.. make the image dirty */
|
Honest, guv, it's not a feature - it's a tightly integrated package of
Mon Sep 20 12:51:30 EDT 1999 Austin Donnelly <austin@gimp.org>
Honest, guv, it's not a feature - it's a tightly integrated
package of undo system cleanups and fixes.
NEW FILES:
* app/undo_history.c: window showing recent undo (and redo) steps
available.
* app/undo_types.h: broken out of undo.h to fix circular includes.
MODIFIED FILES:
* app/Makefile.am: compile undo_history.c
* app/channel.h: use enum for channel undo type, not just magic
numbers.
* app/layer.h: same for layer undos.
* app/commands.c: edit_show_undo_history_cmd_callback() function to
pull up undo history window.
* app/commands.h: prototype for above.
* app/gdisplay.c: make undo / redo menu items sensitive according
to whether they would do anything. Would be easy to change
the text to say what would be undone/redone, but I don't know
the GTK.
* app/gimpimage.c: new signal emitted by gimage:
UNDO_EVENT. gimp_image_undo_event() function to emit it.
* app/gimpimage.h: prototype for above.
* app/gimpimageP.h: pushing_undo_group member is now an undo_type,
not an int. Keep undo history widget here too (if created).
* app/menus.c: add "Edit/Undo history..." to image menu.
* app/undo.c: new types: enums undo_type and undo_state rather than
ints and magic numbers. All undo_pop_* and undo_free_*
functions made static. New static function
undo_type_to_name(). Issue undo event signals on various
important events (eg undo pushed, undo popped etc).
undo_push() now takes a "dirties_image" arg to say whether
image should be dirtied. Layer moves now dirty the image. A
couple of g_return_if_fails () on undo_pop and undo_redo to
assert we're not in the middle of an undo group.
undo_get_{undo,redo}_name() to peek at names of top items on
undo and redo stacks resp. undo_map_over_{undo,redo}_stack()
to run a function for each item or group on stack. Layer and
channel undos use symbolic names rather than 0 or 1. Array
mapping undo types to names.
* app/undo.h: split out undo types to undo_types.h. Prototypes
for functions described above. undo_event_t enum.
undo_history_new() prototype lives here too.
Random other fixes:
* app/gimpdrawable.c
* app/image_render.c: default labels in switches to keep egcs happy.
* app/nav_window.c: some fixes to (sort of) cope with image res !=
screen res. Still needs work to handle non-square pixels
properly.
* app/paths_dialog.c: bad idea to call gimp_image_dirty()
directly. Even though it's currently commented out.
1999-09-21 01:15:20 +08:00
|
|
|
/* undo_push_cantundo(gdisp->gimage, _("path modification")); */
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
if(!paths_replaced_current(plp,bezier_sel))
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = paths_dialog_new_path (&plp, pathpoints_create(bezier_sel),gdisp->gimage,-1);
|
1999-03-06 07:50:24 +08:00
|
|
|
bzp->closed = bezier_sel->closed;
|
|
|
|
bzp->state = bezier_sel->state;
|
1999-03-13 06:04:30 +08:00
|
|
|
if(paths_dialog && paths_dialog->gimage == gdisp->gimage)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
paths_dialog->current_path_list = plp;
|
|
|
|
paths_add_path(bzp,-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-10-25 04:16:48 +08:00
|
|
|
paths_newpoint_current (BezierSelect *bezier_sel,
|
|
|
|
GDisplay *gdisp)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
/* Check if currently showing the paths we are updating */
|
|
|
|
if (paths_dialog &&
|
|
|
|
gdisp->gimage == paths_dialog->gimage)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_set_menu_sensitivity ();
|
|
|
|
|
|
|
|
paths_update_preview (bezier_sel);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_first_button_press (bezier_sel, gdisp);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_new_bezier_select_tool (void)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog)
|
1999-03-06 07:50:24 +08:00
|
|
|
paths_dialog->been_selected = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/**************************************************************/
|
|
|
|
/* Code to save/load from filesystem */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
static GtkWidget *file_dlg = 0;
|
|
|
|
static int load_store;
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
static void
|
|
|
|
path_write_current_to_file (FILE *f,
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-03-22 08:51:30 +08:00
|
|
|
GSList *list = bzp->path_details;
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint* pdata;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
fprintf(f, "Name: %s\n", bzp->name);
|
1999-03-22 08:51:30 +08:00
|
|
|
fprintf(f, "#POINTS: %d\n", g_slist_length(bzp->path_details));
|
1999-03-13 06:04:30 +08:00
|
|
|
fprintf(f, "CLOSED: %d\n", bzp->closed==1?1:0);
|
|
|
|
fprintf(f, "DRAW: %d\n", 0);
|
|
|
|
fprintf(f, "STATE: %d\n", bzp->state);
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
while (list)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
pdata = (PathPoint*)list->data;
|
1999-03-22 08:51:30 +08:00
|
|
|
fprintf(f,"TYPE: %d X: %d Y: %d\n", pdata->type, (gint)pdata->x, (gint)pdata->y);
|
1999-03-13 06:04:30 +08:00
|
|
|
list = g_slist_next(list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
static void
|
|
|
|
file_ok_callback (GtkWidget *widget,
|
|
|
|
gpointer client_data)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
|
|
|
GtkFileSelection *fs;
|
|
|
|
FILE *f;
|
|
|
|
char* filename;
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzpath;
|
|
|
|
PathList* plp;
|
1999-03-13 06:04:30 +08:00
|
|
|
gint row = paths_dialog->selected_row_num;
|
1999-07-07 05:19:34 +08:00
|
|
|
gint this_path_count = 0;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
fs = GTK_FILE_SELECTION (file_dlg);
|
|
|
|
filename = gtk_file_selection_get_filename (fs);
|
|
|
|
|
|
|
|
if (load_store)
|
|
|
|
{
|
|
|
|
f = fopen(filename, "rb");
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
if(!f)
|
|
|
|
{
|
|
|
|
g_message(_("Unable to open file %s"),filename);
|
|
|
|
return;
|
|
|
|
}
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
while(!feof(f))
|
|
|
|
{
|
2000-10-04 17:25:18 +08:00
|
|
|
GSList * pts_list = NULL;
|
1999-03-13 06:04:30 +08:00
|
|
|
gchar *txt = g_new(gchar,512);
|
|
|
|
gchar *txtstart = txt;
|
|
|
|
gint readfields = 0;
|
1999-05-14 06:53:40 +08:00
|
|
|
int val, type, closed, i, draw, state;
|
|
|
|
double x,y;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
if(!fgets(txt,512,f) || strlen(txt) < 7)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
g_message(_("Failed to read from %s"),filename);
|
1999-03-13 06:04:30 +08:00
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
txt += 6; /* Miss out 'Name: ' bit */
|
|
|
|
txt[strlen(txt)-1] = '\0';
|
|
|
|
|
|
|
|
readfields += fscanf(f, "#POINTS: %d\n", &val);
|
|
|
|
readfields += fscanf(f, "CLOSED: %d\n", &closed);
|
|
|
|
readfields += fscanf(f, "DRAW: %d\n", &draw);
|
|
|
|
readfields += fscanf(f, "STATE: %d\n", &state);
|
|
|
|
|
|
|
|
if(readfields != 4)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
g_message(_("Failed to read path from %s"),filename);
|
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(val <= 0)
|
|
|
|
{
|
|
|
|
g_message(_("No points specified in path file %s"),filename);
|
1999-03-13 06:04:30 +08:00
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=0; i< val; i++)
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint* bpt;
|
1999-05-14 06:53:40 +08:00
|
|
|
readfields = fscanf(f,"TYPE: %d X: %lg Y: %lg\n", &type, &x, &y);
|
1999-03-13 06:04:30 +08:00
|
|
|
if(readfields != 3)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
g_message(_("Failed to read path points from %s"),filename);
|
1999-03-13 06:04:30 +08:00
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
1999-07-07 05:19:34 +08:00
|
|
|
this_path_count++;
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case BEZIER_ANCHOR:
|
|
|
|
case BEZIER_CONTROL:
|
|
|
|
break;
|
|
|
|
case BEZIER_MOVE:
|
|
|
|
if(this_path_count < 6)
|
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_warning("Invalid single point in path\n");
|
1999-07-07 05:19:34 +08:00
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this_path_count = 0;
|
|
|
|
break;
|
|
|
|
default:
|
1999-09-23 19:49:16 +08:00
|
|
|
g_warning("Invalid point type passed\n");
|
1999-07-07 05:19:34 +08:00
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
bpt = path_point_new (type, (gdouble)x, (gdouble)y);
|
1999-03-13 06:04:30 +08:00
|
|
|
pts_list = g_slist_append(pts_list,bpt);
|
|
|
|
}
|
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
bzpath = path_new(paths_dialog->gimage,
|
|
|
|
BEZIER,
|
1999-03-22 08:51:30 +08:00
|
|
|
pts_list,
|
|
|
|
closed,
|
|
|
|
state,
|
|
|
|
0, /* Can't be locked */
|
1999-04-06 07:33:50 +08:00
|
|
|
0, /* No tattoo assigned */
|
1999-03-22 08:51:30 +08:00
|
|
|
txt);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
g_free(txtstart);
|
|
|
|
|
|
|
|
paths_dialog->current_path_list =
|
1999-03-22 08:51:30 +08:00
|
|
|
path_add_to_current(paths_dialog->current_path_list,
|
1999-03-13 06:04:30 +08:00
|
|
|
bzpath,
|
|
|
|
paths_dialog->gimage,
|
|
|
|
row);
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_add_path (bzpath, row);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
1999-04-14 05:50:28 +08:00
|
|
|
1);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_dialog_set_menu_sensitivity ();
|
|
|
|
|
|
|
|
if (!val)
|
|
|
|
paths_dialog_set_default_op ();
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
1999-10-30 18:39:48 +08:00
|
|
|
fclose (f);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
Path* bzp;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
/* Get current selection... ignore if none */
|
|
|
|
if(paths_dialog->selected_row_num < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
|
|
|
plp = paths_dialog->current_path_list;
|
2000-02-16 09:47:22 +08:00
|
|
|
bzp = (Path*)g_slist_nth_data(plp->bz_paths,row);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
f = fopen(filename, "wb");
|
|
|
|
if (NULL == f)
|
|
|
|
{
|
|
|
|
g_message (_("open failed on %s: %s\n"), filename, g_strerror(errno));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the current selection out. */
|
1999-10-04 16:40:33 +08:00
|
|
|
path_write_current_to_file (f,bzp);
|
|
|
|
|
|
|
|
fclose (f);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
}
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
static void
|
|
|
|
file_cancel_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
|
|
|
gtk_widget_hide (file_dlg);
|
|
|
|
}
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
static void
|
|
|
|
make_file_dlg (gpointer data)
|
|
|
|
{
|
|
|
|
file_dlg = gtk_file_selection_new (_("Load/Store Bezier Curves"));
|
1999-12-31 04:16:58 +08:00
|
|
|
gtk_window_set_wmclass (GTK_WINDOW (file_dlg), "load_save_path", "Gimp");
|
1999-10-04 16:40:33 +08:00
|
|
|
gtk_window_set_position (GTK_WINDOW (file_dlg), GTK_WIN_POS_MOUSE);
|
1999-12-31 04:16:58 +08:00
|
|
|
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (file_dlg), 2);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (GTK_FILE_SELECTION (file_dlg)->button_area), 2);
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
gtk_signal_connect
|
|
|
|
(GTK_OBJECT (GTK_FILE_SELECTION (file_dlg)->cancel_button), "clicked",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (file_cancel_callback),
|
1999-10-04 16:40:33 +08:00
|
|
|
data);
|
|
|
|
gtk_signal_connect
|
|
|
|
(GTK_OBJECT (GTK_FILE_SELECTION (file_dlg)->ok_button), "clicked",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (file_ok_callback),
|
1999-10-04 16:40:33 +08:00
|
|
|
data);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (file_dlg), "delete_event",
|
1999-10-30 18:39:48 +08:00
|
|
|
GTK_SIGNAL_FUNC (gtk_widget_hide),
|
|
|
|
NULL);
|
1999-10-04 16:40:33 +08:00
|
|
|
|
|
|
|
/* Connect the "F1" help key */
|
1999-11-03 17:58:46 +08:00
|
|
|
gimp_help_connect_help_accel (file_dlg, gimp_standard_help_func, NULL);
|
1999-10-04 16:40:33 +08:00
|
|
|
}
|
1999-03-13 06:04:30 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
void
|
|
|
|
paths_dialog_import_path_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
/* Read and add at current position */
|
1999-03-13 06:04:30 +08:00
|
|
|
if (!file_dlg)
|
|
|
|
{
|
1999-10-04 16:40:33 +08:00
|
|
|
make_file_dlg (NULL);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-04 16:40:33 +08:00
|
|
|
if (GTK_WIDGET_VISIBLE (file_dlg))
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-04 16:40:33 +08:00
|
|
|
|
1999-11-03 17:58:46 +08:00
|
|
|
gimp_help_set_help_data (file_dlg, NULL, "paths/dialogs/import_path.html");
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
gtk_window_set_title (GTK_WINDOW (file_dlg), _("Load Path"));
|
1999-03-13 06:04:30 +08:00
|
|
|
load_store = 1;
|
|
|
|
gtk_widget_show (file_dlg);
|
|
|
|
}
|
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
void
|
|
|
|
paths_dialog_export_path_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-10-30 18:39:48 +08:00
|
|
|
/* Export the path to a file */
|
1999-03-13 06:04:30 +08:00
|
|
|
if (!file_dlg)
|
|
|
|
{
|
1999-10-04 16:40:33 +08:00
|
|
|
make_file_dlg (NULL);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-04 16:40:33 +08:00
|
|
|
if (GTK_WIDGET_VISIBLE (file_dlg))
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-11-03 17:58:46 +08:00
|
|
|
gimp_help_set_help_data (file_dlg, NULL, "paths/dialogs/export_path.html");
|
|
|
|
|
1999-10-04 16:40:33 +08:00
|
|
|
gtk_window_set_title (GTK_WINDOW (file_dlg), _("Store Path"));
|
1999-03-13 06:04:30 +08:00
|
|
|
load_store = 0;
|
|
|
|
gtk_widget_show (file_dlg);
|
|
|
|
}
|
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
/*************************************/
|
|
|
|
/* Function for transforming paths */
|
|
|
|
/*************************************/
|
|
|
|
|
|
|
|
/* These functions are the undo functions for the paths
|
|
|
|
* that have undergone transformations.
|
|
|
|
*
|
|
|
|
* Generally speaking paths do not belong with the undo
|
|
|
|
* structures. However when a path undergoes a transformation
|
|
|
|
* then THIS path transformation should be part of the undo.
|
|
|
|
* We do have a problem here since a point could have been
|
|
|
|
* added to the path after the transformation. This
|
|
|
|
* point will be lost if the undo stuff is performed. It would
|
|
|
|
* then appear that this point is part of the undo structure.
|
|
|
|
* I think it is fair that this happens since the user is telling
|
|
|
|
* us to restore the state before the transformation took place.
|
|
|
|
* Note tattoos are used to find which paths have been stored in the
|
|
|
|
* undo buffer. So deleted paths will not suddenly reappear. (I did say
|
|
|
|
* generally paths are not part of the undo structures).
|
|
|
|
*/
|
2000-02-16 21:52:33 +08:00
|
|
|
PathUndo *
|
|
|
|
path_transform_start_undo (GimpImage *gimage)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
|
|
|
/* Save only the locked paths away */
|
2000-02-16 21:52:33 +08:00
|
|
|
PathList *plp;
|
|
|
|
GSList *plist;
|
|
|
|
Path* p;
|
|
|
|
Path* p_copy;
|
|
|
|
GSList *undo_list = NULL;
|
1999-04-14 05:50:28 +08:00
|
|
|
|
|
|
|
/* Get bzpath structure */
|
2000-02-16 21:52:33 +08:00
|
|
|
plp = (PathList*) gimp_image_get_paths (gimage);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
2000-02-16 21:52:33 +08:00
|
|
|
if (!plp)
|
1999-04-14 05:50:28 +08:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
plist = plp->bz_paths;
|
|
|
|
|
2000-02-16 21:52:33 +08:00
|
|
|
for (plist = plp->bz_paths; plist; plist = g_slist_next (plist))
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
p = (Path*)plist->data;
|
2000-02-16 21:52:33 +08:00
|
|
|
if (p->locked)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
/* save away for a rainy day */
|
|
|
|
p_copy = path_copy (NULL, p); /* NULL means dont want new tattoo */
|
|
|
|
undo_list = g_slist_append (undo_list, p_copy);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
}
|
2000-02-16 21:52:33 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
return (PathUndo *) undo_list;
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_free_undo (PathUndo *pundo)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
GSList *pundolist = (GSList*)pundo;
|
|
|
|
Path *p;
|
1999-04-14 05:50:28 +08:00
|
|
|
/* free data associated with the transform path undo */
|
|
|
|
|
2000-02-16 21:52:33 +08:00
|
|
|
while (pundolist)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
p = (Path*)pundolist->data;
|
|
|
|
path_free (p);
|
2000-02-16 21:52:33 +08:00
|
|
|
pundolist = g_slist_next (pundolist);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
|
2000-02-16 21:52:33 +08:00
|
|
|
g_slist_free (pundolist);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_do_undo (GimpImage *gimage,
|
|
|
|
PathUndo *pundo)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
GSList *pundolist;
|
1999-04-14 05:50:28 +08:00
|
|
|
/* Restore the paths as they were before this transform took place. */
|
2000-02-16 09:47:22 +08:00
|
|
|
Path *p_undo;
|
|
|
|
Path *p;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
gint tmprow;
|
|
|
|
gint loop;
|
|
|
|
gboolean preview_update = FALSE;
|
|
|
|
PathList *plp;
|
|
|
|
GSList *plist;
|
1999-04-14 05:50:28 +08:00
|
|
|
|
|
|
|
/* free data associated with the transform path undo */
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (pundolist = pundo; pundolist; pundolist = g_slist_next(pundolist))
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
p_undo = (Path*)pundolist->data;
|
1999-04-14 05:50:28 +08:00
|
|
|
/* Find the old path and replace it */
|
2000-02-16 09:47:22 +08:00
|
|
|
p = path_get_path_by_tattoo (gimage, p_undo->tattoo);
|
2000-02-24 20:35:25 +08:00
|
|
|
if (p)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
|
|
|
/* Path is still around... undo the transform stuff */
|
2000-02-24 20:35:25 +08:00
|
|
|
pathpoints_free (p->path_details);
|
1999-04-14 05:50:28 +08:00
|
|
|
p->closed = p_undo->closed;
|
|
|
|
p->state = p_undo->state;
|
|
|
|
p->pathtype = p_undo->pathtype;
|
2000-02-16 09:47:22 +08:00
|
|
|
p->path_details = pathpoints_copy (p_undo->path_details);
|
1999-04-14 05:50:28 +08:00
|
|
|
preview_update = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2000-02-24 20:35:25 +08:00
|
|
|
|
|
|
|
if (preview_update && paths_dialog)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
|
|
|
/* Heck the previews need updating...*/
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gimage);
|
1999-04-14 05:50:28 +08:00
|
|
|
plist = plp->bz_paths;
|
|
|
|
loop = 0;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
while (plist &&
|
|
|
|
g_slist_length (plist) &&
|
|
|
|
paths_dialog->current_path_list)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
bezier_sel = path_to_beziersel (plist->data);
|
1999-04-14 05:50:28 +08:00
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = loop;
|
2000-02-24 20:35:25 +08:00
|
|
|
paths_update_preview (bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-04-14 05:50:28 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
paths_dialog->selected_row_num = tmprow;
|
|
|
|
loop++;
|
2000-02-24 20:35:25 +08:00
|
|
|
plist = g_slist_next (plist);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Force selection .. it may have changed */
|
1999-10-30 21:01:15 +08:00
|
|
|
if (bezier_tool_selected () && paths_dialog->current_path_list)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
1999-10-30 21:01:15 +08:00
|
|
|
gtk_clist_select_row (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
|
|
|
1);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-19 04:55:25 +08:00
|
|
|
static void
|
1999-10-25 04:16:48 +08:00
|
|
|
transform_func (GimpImage *gimage,
|
|
|
|
int flip,
|
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
PathList *plp;
|
|
|
|
Path *p;
|
|
|
|
Path *p_copy;
|
1999-10-19 04:55:25 +08:00
|
|
|
GSList *points_list;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
GSList *plist;
|
|
|
|
gint loop;
|
|
|
|
gint tmprow;
|
|
|
|
|
|
|
|
/* As a first off lets just translate the current path */
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gimage);
|
1999-10-19 04:55:25 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plp)
|
1999-10-19 04:55:25 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
loop = 0;
|
2000-02-24 20:35:25 +08:00
|
|
|
for (plist = plp->bz_paths; plist; plist = g_slist_next (plist))
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
p = (Path *) plist->data;
|
|
|
|
|
|
|
|
if (p->locked)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
|
|
|
p_copy = p;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (points_list = p_copy->path_details; points_list;
|
|
|
|
points_list = g_slist_next (points_list))
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
PathPoint *ppoint = points_list->data;
|
|
|
|
|
|
|
|
if (flip)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
if (x > 0.0)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
|
|
|
ppoint->y = gimage->height - ppoint->y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ppoint->x = gimage->width - ppoint->x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ppoint->y += y;
|
|
|
|
ppoint->x += x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only update if we have a dialog, we have a currently
|
|
|
|
* selected path and its the showing the same image.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if(paths_dialog &&
|
|
|
|
paths_dialog->current_path_list &&
|
|
|
|
paths_dialog->gimage == gimage)
|
|
|
|
{
|
|
|
|
/* Now fudge the drawing....*/
|
|
|
|
bezier_sel = path_to_beziersel(p_copy);
|
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = loop;
|
|
|
|
paths_update_preview(bezier_sel);
|
2000-02-16 09:47:22 +08:00
|
|
|
bezier_select_free(bezier_sel);
|
1999-10-19 04:55:25 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
paths_dialog->selected_row_num = tmprow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
loop++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_flip_horz (GimpImage *gimage)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
transform_func (gimage, TRUE, 0.0, 0);
|
1999-10-19 04:55:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_flip_vert (GimpImage *gimage)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
transform_func (gimage, TRUE, 1.0, 0);
|
1999-10-19 04:55:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_xy (GimpImage *gimage,
|
1999-10-25 04:16:48 +08:00
|
|
|
gint x,
|
|
|
|
gint y)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
transform_func (gimage, FALSE, (gdouble) x, (gdouble) y);
|
1999-10-19 04:55:25 +08:00
|
|
|
}
|
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_current_path (GimpImage *gimage,
|
|
|
|
GimpMatrix3 transform,
|
|
|
|
gboolean forpreview)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
PathList *plp;
|
|
|
|
Path *p;
|
|
|
|
Path *p_copy;
|
1999-04-14 05:50:28 +08:00
|
|
|
GSList *points_list;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
GSList *plist;
|
|
|
|
gint loop;
|
|
|
|
gint tmprow;
|
|
|
|
|
|
|
|
/* As a first off lets just translate the current path */
|
|
|
|
|
|
|
|
/* Get bzpath structure */
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gimage);
|
1999-04-14 05:50:28 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plp)
|
1999-04-14 05:50:28 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
loop = 0;
|
2000-02-24 20:35:25 +08:00
|
|
|
for (plist = plp->bz_paths; plist; plist = g_slist_next (plist))
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
p = (Path *) plist->data;
|
|
|
|
|
|
|
|
if (p->locked)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
if (forpreview)
|
|
|
|
p_copy = path_copy (NULL, p); /* NULL means dont want new tattoo */
|
1999-04-14 05:50:28 +08:00
|
|
|
else
|
|
|
|
p_copy = p;
|
2000-02-24 20:35:25 +08:00
|
|
|
|
|
|
|
for (points_list = p_copy->path_details; points_list;
|
|
|
|
points_list = g_slist_next (points_list))
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
|
|
|
gdouble newx,newy;
|
2000-02-24 20:35:25 +08:00
|
|
|
PathPoint *ppoint = points_list->data;
|
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
/* printf("[x,y] = [%g,%g]\n",ppoint->x, ppoint->y); */
|
2000-02-24 20:35:25 +08:00
|
|
|
|
2000-02-15 00:29:41 +08:00
|
|
|
gimp_matrix3_transform_point (transform,
|
|
|
|
ppoint->x,
|
|
|
|
ppoint->y,
|
|
|
|
&newx,&newy);
|
2000-02-24 20:35:25 +08:00
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
/* printf("->[x,y] = [%g,%g]\n", newx, newy); */
|
2000-02-24 20:35:25 +08:00
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
ppoint->x = newx;
|
|
|
|
ppoint->y = newy;
|
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* Only update if we have a dialog, we have a currently
|
|
|
|
* selected path and its the showing the same image.
|
|
|
|
*/
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (paths_dialog &&
|
|
|
|
paths_dialog->current_path_list &&
|
|
|
|
paths_dialog->gimage == gimage)
|
1999-04-14 05:50:28 +08:00
|
|
|
{
|
|
|
|
/* Now fudge the drawing....*/
|
2000-02-24 20:35:25 +08:00
|
|
|
bezier_sel = path_to_beziersel (p_copy);
|
1999-04-14 05:50:28 +08:00
|
|
|
tmprow = paths_dialog->current_path_list->last_selected_row;
|
|
|
|
paths_dialog->current_path_list->last_selected_row = loop;
|
2000-02-24 20:35:25 +08:00
|
|
|
paths_update_preview (bezier_sel);
|
|
|
|
bezier_select_free (bezier_sel);
|
1999-04-14 05:50:28 +08:00
|
|
|
paths_dialog->current_path_list->last_selected_row = tmprow;
|
|
|
|
paths_dialog->selected_row_num = tmprow;
|
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (forpreview)
|
2000-02-16 09:47:22 +08:00
|
|
|
path_free (p_copy);
|
1999-04-14 05:50:28 +08:00
|
|
|
}
|
|
|
|
loop++;
|
|
|
|
}
|
|
|
|
}
|
1999-03-22 08:51:30 +08:00
|
|
|
|
1999-05-27 04:36:33 +08:00
|
|
|
void
|
2000-02-16 21:52:33 +08:00
|
|
|
path_transform_draw_current (GDisplay *gdisp,
|
|
|
|
DrawCore *core,
|
|
|
|
GimpMatrix3 transform)
|
1999-05-27 04:36:33 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
PathList *plp;
|
|
|
|
Path *bzp;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
Path *p_copy;
|
|
|
|
GSList *points_list;
|
|
|
|
GSList *plist;
|
1999-05-27 04:36:33 +08:00
|
|
|
|
|
|
|
/* Get bzpath structure */
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gdisp->gimage);
|
1999-05-27 04:36:33 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plp)
|
1999-05-27 04:36:33 +08:00
|
|
|
return;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (plist = plp->bz_paths; plist; plist = g_slist_next (plist))
|
1999-05-27 04:36:33 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
bzp = (Path *) plist->data;
|
|
|
|
/* This image path is locked */
|
|
|
|
if (bzp->locked)
|
1999-05-27 04:36:33 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
p_copy = path_copy (NULL, bzp); /* NULL means dont want new tattoo */
|
1999-05-27 04:36:33 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (points_list = p_copy->path_details; points_list;
|
|
|
|
points_list = g_slist_next (points_list))
|
|
|
|
{
|
|
|
|
gdouble newx,newy;
|
|
|
|
PathPoint *ppoint = points_list->data;
|
|
|
|
|
|
|
|
/* printf("[x,y] = [%g,%g]\n",ppoint->x, ppoint->y); */
|
|
|
|
|
|
|
|
gimp_matrix3_transform_point (transform,
|
|
|
|
ppoint->x,
|
|
|
|
ppoint->y,
|
|
|
|
&newx,&newy);
|
|
|
|
|
|
|
|
/* printf("->[x,y] = [%g,%g]\n", newx, newy); */
|
|
|
|
|
|
|
|
ppoint->x = newx;
|
|
|
|
ppoint->y = newy;
|
|
|
|
}
|
|
|
|
|
|
|
|
bezier_sel = path_to_beziersel (p_copy);
|
|
|
|
bezier_sel->core = core; /* A bit hacky */
|
|
|
|
bezier_draw (gdisp, bezier_sel);
|
|
|
|
bezier_select_free (bezier_sel);
|
|
|
|
path_free (p_copy);
|
|
|
|
}
|
1999-10-14 04:53:30 +08:00
|
|
|
}
|
1999-05-27 04:36:33 +08:00
|
|
|
}
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
|
1999-03-22 08:51:30 +08:00
|
|
|
/*************************************/
|
|
|
|
/* PDB function aids */
|
|
|
|
/*************************************/
|
|
|
|
|
|
|
|
/* Return TRUE if setting the path worked, else false */
|
|
|
|
|
|
|
|
gboolean
|
2000-02-16 21:52:33 +08:00
|
|
|
path_set_path (GimpImage *gimage,
|
|
|
|
gchar *pname)
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
gint row = 0;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
GSList *tlist;
|
|
|
|
PathList *plp;
|
1999-03-22 08:51:30 +08:00
|
|
|
|
|
|
|
/* Get bzpath structure */
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gimage);
|
1999-03-22 08:51:30 +08:00
|
|
|
|
|
|
|
if(!plp)
|
|
|
|
return FALSE;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (tlist = plp->bz_paths; tlist; tlist = g_slist_next (tlist))
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
gchar *test_str = ((Path*)(tlist->data))->name;
|
2000-02-24 20:35:25 +08:00
|
|
|
if (strcmp (pname, test_str) == 0)
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!found)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if(paths_dialog)
|
|
|
|
{
|
|
|
|
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
|
|
|
|
row,
|
1999-04-14 05:50:28 +08:00
|
|
|
1);
|
1999-03-22 08:51:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
plp->last_selected_row = row;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set a path with the given set of points. */
|
|
|
|
/* We assume that there are enough points */
|
|
|
|
/* Return TRUE if path created OK. */
|
|
|
|
|
|
|
|
gboolean
|
2000-02-16 21:52:33 +08:00
|
|
|
path_set_path_points (GimpImage *gimage,
|
|
|
|
gchar *pname,
|
|
|
|
gint ptype,
|
|
|
|
gint pclosed,
|
|
|
|
gint num_pnts,
|
|
|
|
gdouble *pnts)
|
|
|
|
{
|
|
|
|
PathList *plist = gimp_image_get_paths(gimage);
|
|
|
|
GSList *pts_list = NULL;
|
|
|
|
Path *bzpath;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
gint pcount = 0;
|
|
|
|
gint this_path_count = 0;
|
1999-03-22 08:51:30 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (num_pnts < 6 ||
|
|
|
|
(pclosed && ((num_pnts/3) % 3)) ||
|
|
|
|
(!pclosed && ((num_pnts/3) % 3) != 2))
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
g_warning ("wrong number of points\n");
|
1999-03-22 08:51:30 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (ptype != BEZIER)
|
1999-03-22 08:51:30 +08:00
|
|
|
ptype = BEZIER;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
while (num_pnts)
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
2000-02-16 09:47:22 +08:00
|
|
|
PathPoint *bpt;
|
1999-03-22 08:51:30 +08:00
|
|
|
gint type;
|
|
|
|
gdouble x;
|
|
|
|
gdouble y;
|
|
|
|
|
1999-07-07 05:19:34 +08:00
|
|
|
/* if((pcount/2)%3) */
|
|
|
|
/* type = BEZIER_CONTROL; */
|
|
|
|
/* else */
|
|
|
|
/* type = BEZIER_ANCHOR; */
|
|
|
|
|
1999-03-22 08:51:30 +08:00
|
|
|
x = pnts[pcount++];
|
|
|
|
y = pnts[pcount++];
|
1999-07-07 05:19:34 +08:00
|
|
|
type = (gint)pnts[pcount++];
|
|
|
|
this_path_count++;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
switch (type)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
|
|
|
case BEZIER_ANCHOR:
|
|
|
|
case BEZIER_CONTROL:
|
|
|
|
break;
|
|
|
|
case BEZIER_MOVE:
|
2000-02-24 20:35:25 +08:00
|
|
|
if (this_path_count < 6)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
g_warning ("Invalid single point in path\n");
|
1999-07-07 05:19:34 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
this_path_count = 0;
|
|
|
|
break;
|
|
|
|
default:
|
2000-02-24 20:35:25 +08:00
|
|
|
g_warning ("Invalid point type passed\n");
|
1999-07-07 05:19:34 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
1999-03-22 08:51:30 +08:00
|
|
|
|
|
|
|
/* printf("New point type = %s, x = %d y= %d\n", */
|
|
|
|
/* (type==BEZIER_CONTROL)?"CNTL":"ANCH", */
|
|
|
|
/* (int)x, */
|
|
|
|
/* (int)y); */
|
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
bpt = path_point_new (type, (gdouble)x, (gdouble)y);
|
1999-03-22 08:51:30 +08:00
|
|
|
pts_list = g_slist_append(pts_list,bpt);
|
|
|
|
|
1999-07-07 05:19:34 +08:00
|
|
|
num_pnts -= 3;
|
1999-03-22 08:51:30 +08:00
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
bzpath = path_new (gimage,
|
|
|
|
ptype,
|
|
|
|
pts_list,
|
|
|
|
pclosed,
|
|
|
|
(pclosed) ? BEZIER_EDIT : BEZIER_ADD, /* state */
|
|
|
|
0, /* Can't be locked */
|
|
|
|
0, /* No tattoo assigned */
|
|
|
|
pname);
|
1999-03-22 08:51:30 +08:00
|
|
|
|
1999-07-14 05:55:39 +08:00
|
|
|
bezier_sel = path_to_beziersel(bzpath);
|
|
|
|
|
1999-07-20 06:42:49 +08:00
|
|
|
/* Only add if paths dialog showing this window */
|
1999-10-30 18:39:48 +08:00
|
|
|
if (paths_dialog && paths_dialog->gimage == gimage)
|
1999-03-22 08:51:30 +08:00
|
|
|
{
|
|
|
|
paths_dialog->current_path_list =
|
1999-10-30 18:39:48 +08:00
|
|
|
path_add_to_current (paths_dialog->current_path_list,
|
|
|
|
bzpath,
|
|
|
|
paths_dialog->gimage,
|
|
|
|
0);
|
|
|
|
|
|
|
|
paths_add_path (bzpath, 0);
|
1999-03-22 08:51:30 +08:00
|
|
|
|
1999-07-07 05:19:34 +08:00
|
|
|
/* Update the preview */
|
|
|
|
paths_dialog->current_path_list->last_selected_row = 0;
|
1999-10-30 18:39:48 +08:00
|
|
|
paths_update_preview (bezier_sel);
|
1999-07-07 05:19:34 +08:00
|
|
|
|
1999-10-30 18:39:48 +08:00
|
|
|
gtk_clist_select_row (GTK_CLIST (paths_dialog->paths_list),
|
|
|
|
paths_dialog->current_path_list->last_selected_row,
|
|
|
|
1);
|
|
|
|
|
|
|
|
paths_dialog_set_menu_sensitivity ();
|
1999-03-22 08:51:30 +08:00
|
|
|
}
|
1999-07-07 05:19:34 +08:00
|
|
|
else
|
|
|
|
{
|
1999-07-14 05:55:39 +08:00
|
|
|
GDisplay *gdisp;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plist)
|
1999-07-20 06:42:49 +08:00
|
|
|
{
|
|
|
|
/* If we haven't got a paths dialog */
|
|
|
|
GSList *bzp_list = NULL;
|
2000-02-24 20:35:25 +08:00
|
|
|
|
|
|
|
bzp_list = g_slist_append (bzp_list, bzpath);
|
|
|
|
plist = path_list_new (gimage, 0, bzp_list);
|
|
|
|
gimp_image_set_paths (gimage, plist);
|
1999-07-20 06:42:49 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
path_add_to_current (plist, bzpath, gimage, 0);
|
1999-07-20 06:42:49 +08:00
|
|
|
}
|
|
|
|
|
1999-07-14 05:55:39 +08:00
|
|
|
/* This is a little HACK.. we need to find a display
|
|
|
|
* to put the path image on.
|
|
|
|
*/
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
gdisp = gdisplays_check_valid (NULL, gimage);
|
1999-07-14 05:55:39 +08:00
|
|
|
|
1999-07-07 05:19:34 +08:00
|
|
|
/* Mark this path as selected */
|
|
|
|
plist->last_selected_row = 0;
|
2000-02-02 08:41:11 +08:00
|
|
|
|
|
|
|
/* Only paste if we have an image to paste to! */
|
2000-02-24 20:35:25 +08:00
|
|
|
if (gdisp)
|
|
|
|
bezier_paste_bezierselect_to_current (gdisp, bezier_sel);
|
1999-07-07 05:19:34 +08:00
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
bezier_select_free (bezier_sel);
|
1999-04-06 07:33:50 +08:00
|
|
|
|
2000-02-16 09:47:22 +08:00
|
|
|
return TRUE;
|
1999-04-06 07:33:50 +08:00
|
|
|
}
|
1999-07-07 05:19:34 +08:00
|
|
|
|
|
|
|
gboolean
|
2000-02-16 21:52:33 +08:00
|
|
|
path_delete_path (GimpImage *gimage,
|
|
|
|
gchar *pname)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
2000-02-16 21:52:33 +08:00
|
|
|
gint row = 0;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
GSList *tlist;
|
2000-02-16 09:47:22 +08:00
|
|
|
PathList *plp;
|
1999-07-07 05:19:34 +08:00
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!pname || !gimage)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
g_warning ("paths_delete_path: invalid path");
|
1999-10-30 18:39:48 +08:00
|
|
|
return FALSE;
|
1999-07-07 05:19:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Removed the named path ... */
|
|
|
|
/* Get bzpath structure */
|
2000-02-24 20:35:25 +08:00
|
|
|
plp = (PathList *) gimp_image_get_paths (gimage);
|
1999-07-07 05:19:34 +08:00
|
|
|
|
|
|
|
if(!plp)
|
|
|
|
return FALSE;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
for (tlist = plp->bz_paths; tlist; tlist = g_slist_next (tlist))
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
2000-02-24 20:35:25 +08:00
|
|
|
gchar *test_str = ((Path *) (tlist->data))->name;
|
|
|
|
if (strcmp (pname, test_str) == 0)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!found)
|
1999-07-07 05:19:34 +08:00
|
|
|
return FALSE;
|
|
|
|
|
2000-02-24 20:35:25 +08:00
|
|
|
plp->bz_paths = g_slist_remove (plp->bz_paths, tlist->data);
|
1999-07-07 05:19:34 +08:00
|
|
|
/* If now empty free everything up */
|
2000-02-24 20:35:25 +08:00
|
|
|
if (!plp->bz_paths || g_slist_length (plp->bz_paths) == 0)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
1999-10-30 21:01:15 +08:00
|
|
|
gtk_signal_disconnect (GTK_OBJECT (plp->gimage), plp->sig_id);
|
|
|
|
gimp_image_set_paths (plp->gimage, NULL);
|
2000-02-16 09:47:22 +08:00
|
|
|
path_list_free (plp);
|
1999-07-07 05:19:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Redisplay if required */
|
1999-10-30 21:01:15 +08:00
|
|
|
if (paths_dialog && paths_dialog->gimage == gimage)
|
1999-07-07 05:19:34 +08:00
|
|
|
{
|
|
|
|
paths_dialog->current_path_list = NULL;
|
1999-10-30 21:01:15 +08:00
|
|
|
paths_dialog_flush ();
|
1999-07-07 05:19:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|