1 /*
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This is a plug-in for GIMP.
5 *
6 * Generates images containing vector type drawings.
7 *
8 * Copyright (C) 1997 Andy Thomas alt@picnic.demon.co.uk
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24 #include "config.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33
34 #include <glib.h>
35
36 #ifdef G_OS_WIN32
37 #include <libgimpbase/gimpwin32-io.h>
38 #endif
39
40 #include <libgimp/gimp.h>
41 #include <libgimp/gimpui.h>
42
43 #include "libgimp/stdplugins-intl.h"
44
45 #include "gfig.h"
46 #include "gfig-style.h"
47 #include "gfig-dialog.h"
48 #include "gfig-arc.h"
49 #include "gfig-bezier.h"
50 #include "gfig-circle.h"
51 #include "gfig-dobject.h"
52 #include "gfig-ellipse.h"
53 #include "gfig-grid.h"
54 #include "gfig-line.h"
55 #include "gfig-poly.h"
56 #include "gfig-preview.h"
57 #include "gfig-rectangle.h"
58 #include "gfig-spiral.h"
59 #include "gfig-star.h"
60 #include "gfig-stock.h"
61
62 #define SEL_BUTTON_WIDTH 100
63 #define SEL_BUTTON_HEIGHT 20
64
65 #define GRID_TYPE_MENU 1
66 #define GRID_RENDER_MENU 2
67
68 #define PAINT_BGS_MENU 2
69 #define PAINT_TYPE_MENU 3
70
71 #define OBJ_SELECT_GT 1
72 #define OBJ_SELECT_LT 2
73 #define OBJ_SELECT_EQ 4
74
75 #define UPDATE_DELAY 300 /* From GtkRange in GTK+ 2.22 */
76
77 /* Globals */
78 gint undo_level; /* Last slot filled in -1 = no undo */
79 GList *undo_table[MAX_UNDO];
80
81 /* Values when first invoked */
82 SelectItVals selvals =
83 {
84 {
85 MIN_GRID + (MAX_GRID - MIN_GRID)/2, /* Gridspacing */
86 RECT_GRID, /* Default to rectangle type */
87 FALSE, /* drawgrid */
88 FALSE, /* snap2grid */
89 FALSE, /* lockongrid */
90 TRUE, /* show control points */
91 0.0, /* grid_radius_min */
92 10.0, /* grid_radius_interval */
93 0.0, /* grid_rotation */
94 5.0, /* grid_granularity */
95 120 /* grid_sectors_desired */
96 },
97 FALSE, /* show image */
98 MIN_UNDO + (MAX_UNDO - MIN_UNDO)/2, /* Max level of undos */
99 TRUE, /* Show pos updates */
100 0.0, /* Brush fade */
101 0.0, /* Brush gradient */
102 20.0, /* Air brush pressure */
103 ORIGINAL_LAYER, /* Draw all objects on one layer */
104 LAYER_TRANS_BG, /* New layers background */
105 PAINT_BRUSH_TYPE, /* Default to use brushes */
106 FALSE, /* reverse lines */
107 TRUE, /* Scale to image when painting */
108 1.0, /* Scale to image fp */
109 BRUSH_BRUSH_TYPE, /* Default to use a brush */
110 LINE /* Initial object type */
111 };
112
113 selection_option selopt =
114 {
115 ADD, /* type */
116 FALSE, /* Antia */
117 FALSE, /* Feather */
118 10.0, /* feather radius */
119 ARC_SEGMENT, /* Arc as a segment */
120 FILL_PATTERN, /* Fill as pattern */
121 100.0, /* Max opacity */
122 };
123
124 /* Should be kept in sync with GfigOpts */
125 typedef struct
126 {
127 GtkAdjustment *gridspacing;
128 GtkAdjustment *grid_sectors_desired;
129 GtkAdjustment *grid_radius_interval;
130 GtkWidget *gridtypemenu;
131 GtkWidget *drawgrid;
132 GtkWidget *snap2grid;
133 GtkWidget *lockongrid;
134 GtkWidget *showcontrol;
135 } GfigOptWidgets;
136
137 static GfigOptWidgets gfig_opt_widget = { NULL, NULL, NULL, NULL, NULL, NULL };
138 static gchar *gfig_path = NULL;
139 static GtkWidget *page_menu_bg;
140 static GtkWidget *tool_options_notebook;
141 static GtkWidget *fill_type_notebook;
142 static guint paint_timeout = 0;
143
144 static GtkActionGroup *gfig_actions = NULL;
145
146
147 static void gfig_response (GtkWidget *widget,
148 gint response_id,
149 gpointer data);
150 static void gfig_load_action_callback (GtkAction *action,
151 gpointer data);
152 static void gfig_save_action_callback (GtkAction *action,
153 gpointer data);
154 static void gfig_list_load_all (const gchar *path);
155 static void gfig_list_free_all (void);
156 static void create_notebook_pages (GtkWidget *notebook);
157 static void select_filltype_callback (GtkWidget *widget);
158 static void gfig_grid_action_callback (GtkAction *action,
159 gpointer data);
160 static void gfig_prefs_action_callback (GtkAction *action,
161 gpointer data);
162 static void toggle_show_image (void);
163 static void gridtype_combo_callback (GtkWidget *widget,
164 gpointer data);
165
166 static void load_file_chooser_response (GtkFileChooser *chooser,
167 gint response_id,
168 gpointer data);
169 static void save_file_chooser_response (GtkFileChooser *chooser,
170 gint response_id,
171 GFigObj *obj);
172 static void paint_combo_callback (GtkWidget *widget,
173 gpointer data);
174
175 static void select_button_clicked (gint type);
176 static void select_button_clicked_lt (void);
177 static void select_button_clicked_gt (void);
178 static void select_button_clicked_eq (void);
179 static void raise_selected_obj_to_top (GtkWidget *widget,
180 gpointer data);
181 static void lower_selected_obj_to_bottom (GtkWidget *widget,
182 gpointer data);
183 static void raise_selected_obj (GtkWidget *widget,
184 gpointer data);
185 static void lower_selected_obj (GtkWidget *widget,
186 gpointer data);
187
188 static void toggle_obj_type (GtkRadioAction *action,
189 GtkRadioAction *current,
190 gpointer data);
191
192 static GtkUIManager *create_ui_manager (GtkWidget *window);
193
194
195 gboolean
gfig_dialog(void)196 gfig_dialog (void)
197 {
198 GtkWidget *main_hbox;
199 GtkWidget *vbox;
200 GFigObj *gfig;
201 GimpParasite *parasite;
202 gint newlayer;
203 GtkWidget *menubar;
204 GtkWidget *toolbar;
205 GtkWidget *combo;
206 GtkWidget *frame;
207 gint img_width;
208 gint img_height;
209 GimpImageType img_type;
210 GtkWidget *toggle;
211 GtkWidget *right_vbox;
212 GtkWidget *hbox;
213 GtkUIManager *ui_manager;
214 GtkWidget *empty_label;
215 gchar *path;
216
217 gimp_ui_init (PLUG_IN_BINARY, TRUE);
218
219 img_width = gimp_drawable_width (gfig_context->drawable_id);
220 img_height = gimp_drawable_height (gfig_context->drawable_id);
221 img_type = gimp_drawable_type_with_alpha (gfig_context->drawable_id);
222
223 /*
224 * See if there is a "gfig" parasite. If so, this is a gfig layer,
225 * and we start by clearing it to transparent.
226 * If not, we create a new transparent layer.
227 */
228 gfig_list = NULL;
229 undo_level = -1;
230 parasite = gimp_item_get_parasite (gfig_context->drawable_id, "gfig");
231 gfig_context->enable_repaint = FALSE;
232
233 /* debug */
234 gfig_context->debug_styles = FALSE;
235
236 /* initial default style */
237 gfig_read_gimp_style (&gfig_context->default_style, "Base");
238 gfig_context->default_style.paint_type = selvals.painttype;
239
240 if (parasite)
241 {
242 gimp_drawable_fill (gfig_context->drawable_id, GIMP_FILL_TRANSPARENT);
243 gfig_context->using_new_layer = FALSE;
244 gimp_parasite_free (parasite);
245 }
246 else
247 {
248 newlayer = gimp_layer_new (gfig_context->image_id, "GFig",
249 img_width, img_height,
250 img_type,
251 100.0,
252 gimp_image_get_default_new_layer_mode (gfig_context->image_id));
253 gimp_drawable_fill (newlayer, GIMP_FILL_TRANSPARENT);
254 gimp_image_insert_layer (gfig_context->image_id, newlayer, -1, -1);
255 gfig_context->drawable_id = newlayer;
256 gfig_context->using_new_layer = TRUE;
257 }
258
259 gfig_stock_init ();
260
261 path = gimp_gimprc_query ("gfig-path");
262
263 if (path)
264 {
265 gfig_path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
266 g_free (path);
267 }
268 else
269 {
270 gchar *gimprc = gimp_personal_rc_file ("gimprc");
271 gchar *full_path = gimp_config_build_data_path ("gfig");
272 gchar *esc_path = g_strescape (full_path, NULL);
273 g_free (full_path);
274
275 g_message (_("No %s in gimprc:\n"
276 "You need to add an entry like\n"
277 "(%s \"%s\")\n"
278 "to your %s file."),
279 "gfig-path", "gfig-path", esc_path,
280 gimp_filename_to_utf8 (gimprc));
281
282 g_free (gimprc);
283 g_free (esc_path);
284 }
285
286 /* Start building the dialog up */
287 top_level_dlg = gimp_dialog_new (_("Gfig"), PLUG_IN_ROLE,
288 NULL, 0,
289 gimp_standard_help_func, PLUG_IN_PROC,
290
291 _("_Cancel"), GTK_RESPONSE_CANCEL,
292 _("_Close"), GTK_RESPONSE_OK,
293
294 NULL);
295
296 gtk_dialog_set_alternative_button_order (GTK_DIALOG (top_level_dlg),
297 GTK_RESPONSE_OK,
298 GTK_RESPONSE_CANCEL,
299 -1);
300
301 g_signal_connect (top_level_dlg, "response",
302 G_CALLBACK (gfig_response),
303 top_level_dlg);
304
305 /* build the menu */
306 ui_manager = create_ui_manager (top_level_dlg);
307 menubar = gtk_ui_manager_get_widget (ui_manager, "/ui/gfig-menubar");
308 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (top_level_dlg))),
309 menubar, FALSE, FALSE, 0);
310 gtk_widget_show (menubar);
311 toolbar = gtk_ui_manager_get_widget (ui_manager, "/ui/gfig-toolbar");
312 gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
313 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (top_level_dlg))),
314 toolbar, FALSE, FALSE, 0);
315 gtk_widget_show (toolbar);
316
317 gfig_dialog_action_set_sensitive ("undo", undo_level >= 0);
318
319 /* Main box */
320 main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
321 gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
322 gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (top_level_dlg))),
323 main_hbox, TRUE, TRUE, 0);
324
325 /* Preview itself */
326 gtk_box_pack_start (GTK_BOX (main_hbox), make_preview (), FALSE, FALSE, 0);
327
328 gtk_widget_show (gfig_context->preview);
329
330 right_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
331 gtk_box_pack_start (GTK_BOX (main_hbox), right_vbox, FALSE, FALSE, 0);
332 gtk_widget_show (right_vbox);
333
334 /* Tool options notebook */
335 frame = gimp_frame_new ( _("Tool Options"));
336 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, FALSE, 0);
337 gtk_widget_show (frame);
338
339 tool_options_notebook = gtk_notebook_new ();
340 gtk_container_add (GTK_CONTAINER (frame), tool_options_notebook);
341 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (tool_options_notebook), FALSE);
342 gtk_notebook_set_show_border (GTK_NOTEBOOK (tool_options_notebook), FALSE);
343 gtk_widget_show (tool_options_notebook);
344 create_notebook_pages (tool_options_notebook);
345
346 /* Stroke frame on right side */
347 frame = gimp_frame_new (NULL);
348 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, FALSE, 0);
349 gtk_widget_show (frame);
350
351 gfig_context->paint_type_toggle =
352 toggle = gtk_check_button_new_with_mnemonic (_("_Stroke"));
353
354 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), selvals.painttype);
355 gtk_frame_set_label_widget (GTK_FRAME (frame), toggle);
356 gtk_widget_show (toggle);
357
358 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
359 gtk_container_add (GTK_CONTAINER (frame), hbox);
360 gtk_widget_show (hbox);
361
362 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
363 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
364 gtk_widget_show (vbox);
365
366 gtk_widget_set_sensitive (vbox, selvals.painttype);
367 g_signal_connect (toggle, "toggled",
368 G_CALLBACK (set_paint_type_callback),
369 vbox);
370
371 /* foreground color button in Stroke frame*/
372 gfig_context->fg_color = g_new0 (GimpRGB, 1);
373 gfig_context->fg_color_button = gimp_color_button_new ("Foreground",
374 SEL_BUTTON_WIDTH,
375 SEL_BUTTON_HEIGHT,
376 gfig_context->fg_color,
377 GIMP_COLOR_AREA_SMALL_CHECKS);
378 g_signal_connect (gfig_context->fg_color_button, "color-changed",
379 G_CALLBACK (set_foreground_callback),
380 gfig_context->fg_color);
381 gimp_color_button_set_color (GIMP_COLOR_BUTTON (gfig_context->fg_color_button),
382 &gfig_context->default_style.foreground);
383 gtk_box_pack_start (GTK_BOX (vbox), gfig_context->fg_color_button,
384 FALSE, FALSE, 0);
385 gtk_widget_show (gfig_context->fg_color_button);
386
387 /* brush selector in Stroke frame */
388 gfig_context->brush_select
389 = gimp_brush_select_button_new ("Brush",
390 gfig_context->default_style.brush_name,
391 -1.0, -1, -1);
392 g_signal_connect (gfig_context->brush_select, "brush-set",
393 G_CALLBACK (gfig_brush_changed_callback), NULL);
394 gtk_box_pack_start (GTK_BOX (vbox), gfig_context->brush_select,
395 FALSE, FALSE, 0);
396 gtk_widget_show (gfig_context->brush_select);
397
398 /* Fill frame on right side */
399 frame = gimp_frame_new (_("Fill"));
400 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, FALSE, 0);
401 gtk_widget_show (frame);
402
403 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
404 gtk_container_add (GTK_CONTAINER (frame), hbox);
405 gtk_widget_show (hbox);
406
407 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
408 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
409 gtk_widget_show (vbox);
410
411 /* fill style combo box in Style frame */
412 gfig_context->fillstyle_combo = combo
413 = gimp_int_combo_box_new (_("No fill"), FILL_NONE,
414 _("Color fill"), FILL_COLOR,
415 _("Pattern fill"), FILL_PATTERN,
416 _("Shape gradient"), FILL_GRADIENT,
417 _("Vertical gradient"), FILL_VERTICAL,
418 _("Horizontal gradient"), FILL_HORIZONTAL,
419 NULL);
420 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), 0);
421 g_signal_connect (combo, "changed",
422 G_CALLBACK (select_filltype_callback),
423 NULL);
424 gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
425 gtk_widget_show (combo);
426
427 fill_type_notebook = gtk_notebook_new ();
428 gtk_box_pack_start (GTK_BOX (vbox), fill_type_notebook, FALSE, FALSE, 0);
429 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (fill_type_notebook), FALSE);
430 gtk_notebook_set_show_border (GTK_NOTEBOOK (fill_type_notebook), FALSE);
431 gtk_widget_show (fill_type_notebook);
432
433 /* An empty page for "No fill" */
434 empty_label = gtk_label_new ("");
435 gtk_widget_show (empty_label);
436 gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
437 empty_label, NULL);
438
439 /* A page for the fill color button */
440 gfig_context->bg_color = g_new0 (GimpRGB, 1);
441 gfig_context->bg_color_button = gimp_color_button_new ("Background",
442 SEL_BUTTON_WIDTH, SEL_BUTTON_HEIGHT,
443 gfig_context->bg_color,
444 GIMP_COLOR_AREA_SMALL_CHECKS);
445 g_signal_connect (gfig_context->bg_color_button, "color-changed",
446 G_CALLBACK (set_background_callback),
447 gfig_context->bg_color);
448 gimp_color_button_set_color (GIMP_COLOR_BUTTON (gfig_context->bg_color_button),
449 &gfig_context->default_style.background);
450 gtk_widget_show (gfig_context->bg_color_button);
451 gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
452 gfig_context->bg_color_button, NULL);
453
454 /* A page for the pattern selector */
455 gfig_context->pattern_select
456 = gimp_pattern_select_button_new ("Pattern", gfig_context->default_style.pattern);
457 g_signal_connect (gfig_context->pattern_select, "pattern-set",
458 G_CALLBACK (gfig_pattern_changed_callback), NULL);
459 gtk_widget_show (gfig_context->pattern_select);
460 gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
461 gfig_context->pattern_select, NULL);
462
463 /* A page for the gradient selector */
464 gfig_context->gradient_select
465 = gimp_gradient_select_button_new ("Gradient", gfig_context->default_style.gradient);
466 g_signal_connect (gfig_context->gradient_select, "gradient-set",
467 G_CALLBACK (gfig_gradient_changed_callback), NULL);
468 gtk_widget_show (gfig_context->gradient_select);
469 gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
470 gfig_context->gradient_select, NULL);
471
472
473 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
474 gtk_box_pack_start (GTK_BOX (right_vbox), vbox, FALSE, FALSE, 0);
475 gtk_widget_show (vbox);
476
477 /* "show image" checkbutton at bottom of style frame */
478 toggle = gtk_check_button_new_with_label (_("Show image"));
479 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
480 gfig_context->show_background);
481 gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
482 g_signal_connect (toggle, "toggled",
483 G_CALLBACK (gimp_toggle_button_update),
484 &gfig_context->show_background);
485 g_signal_connect_swapped (toggle, "toggled",
486 G_CALLBACK (gtk_widget_queue_draw),
487 gfig_context->preview);
488 gtk_widget_show (toggle);
489
490 /* "snap to grid" checkbutton at bottom of style frame */
491 toggle = gtk_check_button_new_with_label (C_("checkbutton", "Snap to grid"));
492 gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
493 g_signal_connect (toggle, "toggled",
494 G_CALLBACK (gimp_toggle_button_update),
495 &selvals.opts.snap2grid);
496 gtk_widget_show (toggle);
497 gfig_opt_widget.snap2grid = toggle;
498
499 /* "show grid" checkbutton at bottom of style frame */
500 toggle = gtk_check_button_new_with_label (_("Show grid"));
501 gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
502 g_signal_connect (toggle, "toggled",
503 G_CALLBACK (gimp_toggle_button_update),
504 &selvals.opts.drawgrid);
505 g_signal_connect (toggle, "toggled",
506 G_CALLBACK (draw_grid_clear),
507 NULL);
508 gtk_widget_show (toggle);
509 gfig_opt_widget.drawgrid = toggle;
510
511 /* Load saved objects */
512 gfig_list_load_all (gfig_path);
513
514 /* Setup initial brush settings */
515 gfig_context->bdesc.name = gimp_context_get_brush ();
516 mygimp_brush_info (&gfig_context->bdesc.width, &gfig_context->bdesc.height);
517
518 gtk_widget_show (main_hbox);
519
520 gtk_widget_show (top_level_dlg);
521
522 gfig = gfig_load_from_parasite ();
523 if (gfig)
524 {
525 gfig_list_insert (gfig);
526 new_obj_2edit (gfig);
527 gfig_style_set_context_from_style (&gfig_context->default_style);
528 gfig_style_apply (&gfig_context->default_style);
529 }
530
531 gfig_context->enable_repaint = TRUE;
532 gfig_paint_callback ();
533
534 gtk_main ();
535
536 /* FIXME */
537 return TRUE;
538 }
539
540 static void
gfig_response(GtkWidget * widget,gint response_id,gpointer data)541 gfig_response (GtkWidget *widget,
542 gint response_id,
543 gpointer data)
544 {
545 GFigObj *gfig;
546
547 switch (response_id)
548 {
549 case GTK_RESPONSE_DELETE_EVENT:
550 case GTK_RESPONSE_CANCEL:
551 /* if we created a new layer, delete it */
552 if (gfig_context->using_new_layer)
553 {
554 gimp_image_remove_layer (gfig_context->image_id,
555 gfig_context->drawable_id);
556 }
557 else /* revert back to the original figure */
558 {
559 free_all_objs (gfig_context->current_obj->obj_list);
560 gfig_context->current_obj->obj_list = NULL;
561 gfig = gfig_load_from_parasite ();
562 if (gfig)
563 {
564 gfig_list_insert (gfig);
565 new_obj_2edit (gfig);
566 }
567 gfig_context->enable_repaint = TRUE;
568 gfig_paint_callback ();
569 }
570 break;
571
572 case GTK_RESPONSE_OK: /* Close button */
573 gfig_save_as_parasite ();
574 break;
575
576 default:
577 break;
578 }
579
580 gtk_widget_destroy (widget);
581 gtk_main_quit ();
582 }
583
584 void
gfig_dialog_action_set_sensitive(const gchar * name,gboolean sensitive)585 gfig_dialog_action_set_sensitive (const gchar *name,
586 gboolean sensitive)
587 {
588 g_return_if_fail (name != NULL);
589
590 if (gfig_actions)
591 {
592 GtkAction *action = gtk_action_group_get_action (gfig_actions, name);
593
594 if (! action)
595 {
596 g_warning ("%s: Unable to set sensitivity of action "
597 "which doesn't exist: %s",
598 G_STRFUNC, name);
599 return;
600 }
601
602 g_object_set (action, "sensitive", sensitive ? TRUE : FALSE, NULL);
603 }
604 }
605
606 static gchar *
gfig_get_user_writable_dir(void)607 gfig_get_user_writable_dir (void)
608 {
609 if (gfig_path)
610 {
611 GList *list;
612 gchar *dir;
613
614 list = gimp_path_parse (gfig_path, 256, FALSE, NULL);
615 dir = gimp_path_get_user_writable_dir (list);
616 gimp_path_free (list);
617
618 return dir;
619 }
620
621 return g_strdup (gimp_directory ());
622 }
623
624 static void
gfig_load_action_callback(GtkAction * action,gpointer data)625 gfig_load_action_callback (GtkAction *action,
626 gpointer data)
627 {
628 static GtkWidget *dialog = NULL;
629
630 if (! dialog)
631 {
632 gchar *dir;
633
634 dialog =
635 gtk_file_chooser_dialog_new (_("Load Gfig Object Collection"),
636 GTK_WINDOW (data),
637 GTK_FILE_CHOOSER_ACTION_OPEN,
638
639 _("_Cancel"), GTK_RESPONSE_CANCEL,
640 _("_Open"), GTK_RESPONSE_OK,
641
642 NULL);
643
644 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
645 GTK_RESPONSE_OK,
646 GTK_RESPONSE_CANCEL,
647 -1);
648
649 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
650
651 g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
652
653 g_signal_connect (dialog, "response",
654 G_CALLBACK (load_file_chooser_response),
655 NULL);
656
657 dir = gfig_get_user_writable_dir ();
658 if (dir)
659 {
660 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
661 dir);
662 g_free (dir);
663 }
664
665 gtk_widget_show (dialog);
666 }
667 else
668 {
669 gtk_window_present (GTK_WINDOW (dialog));
670 }
671 }
672
673 static void
gfig_save_action_callback(GtkAction * action,gpointer data)674 gfig_save_action_callback (GtkAction *action,
675 gpointer data)
676 {
677 static GtkWidget *dialog = NULL;
678
679 if (!dialog)
680 {
681 gchar *dir;
682
683 dialog =
684 gtk_file_chooser_dialog_new (_("Save Gfig Drawing"),
685 GTK_WINDOW (data),
686 GTK_FILE_CHOOSER_ACTION_SAVE,
687
688 _("_Cancel"), GTK_RESPONSE_CANCEL,
689 _("_Save"), GTK_RESPONSE_OK,
690
691 NULL);
692
693 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
694 GTK_RESPONSE_OK,
695 GTK_RESPONSE_CANCEL,
696 -1);
697 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
698
699 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
700 TRUE);
701
702 g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
703
704 /* FIXME: GFigObj should be a GObject and g_signal_connect_object()
705 * should be used here.
706 */
707 g_signal_connect (dialog, "response",
708 G_CALLBACK (save_file_chooser_response),
709 gfig_context->current_obj);
710
711 dir = gfig_get_user_writable_dir ();
712 if (dir)
713 {
714 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dir);
715 g_free (dir);
716 }
717
718 gtk_widget_show (dialog);
719 }
720 else
721 {
722 gtk_window_present (GTK_WINDOW (dialog));
723 }
724 }
725
726 static void
gfig_close_action_callback(GtkAction * action,gpointer data)727 gfig_close_action_callback (GtkAction *action,
728 gpointer data)
729 {
730 gtk_dialog_response (GTK_DIALOG (data), GTK_RESPONSE_OK);
731 }
732
733 static void
gfig_undo_action_callback(GtkAction * action,gpointer data)734 gfig_undo_action_callback (GtkAction *action,
735 gpointer data)
736 {
737 if (undo_level >= 0)
738 {
739 /* Free current objects an reinstate previous */
740 free_all_objs (gfig_context->current_obj->obj_list);
741 gfig_context->current_obj->obj_list = NULL;
742 tmp_bezier = tmp_line = obj_creating = NULL;
743 gfig_context->current_obj->obj_list = undo_table[undo_level];
744 undo_level--;
745 /* Update the screen */
746 gtk_widget_queue_draw (gfig_context->preview);
747 /* And preview */
748 gfig_context->current_obj->obj_status |= GFIG_MODIFIED;
749 if (gfig_context->current_obj->obj_list)
750 gfig_context->selected_obj = gfig_context->current_obj->obj_list->data;
751 else
752 gfig_context->selected_obj = NULL;
753 }
754
755 gfig_dialog_action_set_sensitive ("undo", undo_level >= 0);
756 gfig_paint_callback ();
757 }
758
759 static void
gfig_clear_action_callback(GtkWidget * widget,gpointer data)760 gfig_clear_action_callback (GtkWidget *widget,
761 gpointer data)
762 {
763 /* Make sure we can get back - if we have some objects to get back to */
764 if (!gfig_context->current_obj->obj_list)
765 return;
766
767 setup_undo ();
768 /* Free all objects */
769 free_all_objs (gfig_context->current_obj->obj_list);
770 gfig_context->current_obj->obj_list = NULL;
771 gfig_context->selected_obj = NULL;
772 obj_creating = NULL;
773 tmp_line = NULL;
774 tmp_bezier = NULL;
775 gtk_widget_queue_draw (gfig_context->preview);
776 gfig_paint_callback ();
777 }
778
779 void
draw_item(cairo_t * cr,gboolean fill)780 draw_item (cairo_t *cr, gboolean fill)
781 {
782 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
783
784 if (fill)
785 {
786 cairo_fill_preserve (cr);
787 }
788 else
789 {
790 cairo_set_line_width (cr, 3.0);
791 cairo_stroke_preserve (cr);
792 }
793
794 cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
795 cairo_set_line_width (cr, 1.0);
796 cairo_stroke (cr);
797 }
798
799 /* Given a point x, y draw a circle */
800 void
draw_circle(GdkPoint * p,gboolean selected,cairo_t * cr)801 draw_circle (GdkPoint *p,
802 gboolean selected,
803 cairo_t *cr)
804 {
805 if (!selvals.opts.showcontrol)
806 return;
807
808 cairo_arc (cr,
809 gfig_scale_x (p->x) + .5,
810 gfig_scale_y (p->y) + .5,
811 SQ_SIZE / 2,
812 0, 2 * G_PI);
813
814 draw_item (cr, selected);
815 }
816
817 /* Given a point x, y draw a square around it */
818 void
draw_sqr(GdkPoint * p,gboolean selected,cairo_t * cr)819 draw_sqr (GdkPoint *p,
820 gboolean selected,
821 cairo_t *cr)
822 {
823 if (!selvals.opts.showcontrol)
824 return;
825
826 cairo_rectangle (cr,
827 gfig_scale_x (p->x) + .5 - SQ_SIZE / 2,
828 gfig_scale_y (p->y) + .5 - SQ_SIZE / 2,
829 SQ_SIZE,
830 SQ_SIZE);
831
832 draw_item (cr, selected);
833 }
834
835 static void
gfig_list_load_all(const gchar * path)836 gfig_list_load_all (const gchar *path)
837 {
838 /* Make sure to clear any existing gfigs */
839 gfig_context->current_obj = NULL;
840 gfig_list_free_all ();
841
842 if (! gfig_list)
843 {
844 GFigObj *gfig;
845
846 /* lets have at least one! */
847 gfig = gfig_new ();
848 gfig->draw_name = g_strdup (_("First Gfig"));
849 gfig_list_insert (gfig);
850 }
851
852 gfig_context->current_obj = gfig_list->data; /* set to first entry */
853 }
854
855 static void
gfig_list_free_all(void)856 gfig_list_free_all (void)
857 {
858 g_list_free_full (gfig_list, (GDestroyNotify) gfig_free);
859 gfig_list = NULL;
860 }
861
862 static GtkUIManager *
create_ui_manager(GtkWidget * window)863 create_ui_manager (GtkWidget *window)
864 {
865 static GtkActionEntry actions[] =
866 {
867 { "gfig-menubar", NULL, "GFig Menu" },
868
869 { "gfig-file-menu", NULL, "_File" },
870
871 { "open", GIMP_ICON_DOCUMENT_OPEN,
872 N_("_Open..."), "<control>O", NULL,
873 G_CALLBACK (gfig_load_action_callback) },
874
875 { "save", GIMP_ICON_DOCUMENT_SAVE,
876 N_("_Save..."), "<control>S", NULL,
877 G_CALLBACK (gfig_save_action_callback) },
878
879 { "close", GIMP_ICON_CLOSE,
880 N_("_Close"), "<control>C", NULL,
881 G_CALLBACK (gfig_close_action_callback) },
882
883 { "gfig-edit-menu", NULL, "_Edit" },
884
885 { "undo", GIMP_ICON_EDIT_UNDO,
886 N_("_Undo"), "<control>Z", NULL,
887 G_CALLBACK (gfig_undo_action_callback) },
888
889 { "clear", GIMP_ICON_EDIT_CLEAR,
890 N_("_Clear"), NULL, NULL,
891 G_CALLBACK (gfig_clear_action_callback) },
892
893 { "grid", GIMP_ICON_GRID,
894 N_("_Grid"), "<control>G", NULL,
895 G_CALLBACK (gfig_grid_action_callback) },
896
897 { "prefs", GIMP_ICON_PREFERENCES_SYSTEM,
898 N_("_Preferences..."), "<control>P", NULL,
899 G_CALLBACK (gfig_prefs_action_callback) },
900
901 { "raise", GIMP_ICON_GO_UP,
902 N_("_Raise"), "<control>U", N_("Raise selected object"),
903 G_CALLBACK (raise_selected_obj) },
904
905 { "lower", GIMP_ICON_GO_DOWN,
906 N_("_Lower"), "<control>D", N_("Lower selected object"),
907 G_CALLBACK (lower_selected_obj) },
908
909 { "top", GIMP_ICON_GO_TOP,
910 N_("Raise to _top"), "<control>T", N_("Raise selected object to top"),
911 G_CALLBACK (raise_selected_obj_to_top) },
912
913 { "bottom", GIMP_ICON_GO_BOTTOM,
914 N_("Lower to _bottom"), "<control>B", N_("Lower selected object to bottom"),
915 G_CALLBACK (lower_selected_obj_to_bottom) },
916
917 { "show_previous", GIMP_ICON_GO_PREVIOUS,
918 N_("_Previous"), "<control>H", N_("Show previous object"),
919 G_CALLBACK (select_button_clicked_lt) },
920
921 { "show_next", GIMP_ICON_GO_NEXT,
922 N_("_Next"), "<control>L", N_("Show next object"),
923 G_CALLBACK (select_button_clicked_gt) },
924
925 { "show_all", GFIG_STOCK_SHOW_ALL,
926 N_("Show _all"), "<control>A", N_("Show all objects"),
927 G_CALLBACK (select_button_clicked_eq) }
928 };
929 static GtkRadioActionEntry radio_actions[] =
930 {
931 { "line", GFIG_STOCK_LINE,
932 NULL, "L", N_("Create line"), LINE },
933
934 { "rectangle", GFIG_STOCK_RECTANGLE,
935 NULL, "R", N_("Create rectangle"), RECTANGLE },
936
937 { "circle", GFIG_STOCK_CIRCLE,
938 NULL, "C", N_("Create circle"), CIRCLE },
939
940 { "ellipse", GFIG_STOCK_ELLIPSE,
941 NULL, "E", N_("Create ellipse"), ELLIPSE },
942
943 { "arc", GFIG_STOCK_CURVE,
944 NULL, "A", N_("Create arc"), ARC },
945
946 { "polygon", GFIG_STOCK_POLYGON,
947 NULL, "P", N_("Create reg polygon"), POLY },
948
949 { "star", GFIG_STOCK_STAR,
950 NULL, "S", N_("Create star"), STAR },
951
952 { "spiral", GFIG_STOCK_SPIRAL,
953 NULL, "I", N_("Create spiral"), SPIRAL },
954
955 { "bezier", GFIG_STOCK_BEZIER,
956 NULL, "B", N_("Create bezier curve. "
957 "Shift + Button ends object creation."), BEZIER },
958
959 { "move_obj", GFIG_STOCK_MOVE_OBJECT,
960 NULL, "M", N_("Move an object"), MOVE_OBJ },
961
962 { "move_point", GFIG_STOCK_MOVE_POINT,
963 NULL, "V", N_("Move a single point"), MOVE_POINT },
964
965 { "copy", GFIG_STOCK_COPY_OBJECT,
966 NULL, "Y", N_("Copy an object"), COPY_OBJ },
967
968 { "delete", GFIG_STOCK_DELETE_OBJECT,
969 NULL, "D", N_("Delete an object"), DEL_OBJ },
970
971 { "select", GFIG_STOCK_SELECT_OBJECT,
972 NULL, "A", N_("Select an object"), SELECT_OBJ }
973 };
974
975 GtkUIManager *ui_manager = gtk_ui_manager_new ();
976
977 gfig_actions = gtk_action_group_new ("Actions");
978
979 gtk_action_group_set_translation_domain (gfig_actions, NULL);
980
981 gtk_action_group_add_actions (gfig_actions,
982 actions,
983 G_N_ELEMENTS (actions),
984 window);
985 gtk_action_group_add_radio_actions (gfig_actions,
986 radio_actions,
987 G_N_ELEMENTS (radio_actions),
988 LINE,
989 G_CALLBACK (toggle_obj_type),
990 window);
991
992 gtk_window_add_accel_group (GTK_WINDOW (window),
993 gtk_ui_manager_get_accel_group (ui_manager));
994 gtk_accel_group_lock (gtk_ui_manager_get_accel_group (ui_manager));
995
996 gtk_ui_manager_insert_action_group (ui_manager, gfig_actions, -1);
997 g_object_unref (gfig_actions);
998
999 gtk_ui_manager_add_ui_from_string (ui_manager,
1000 "<ui>"
1001 " <menubar name=\"gfig-menubar\">"
1002 " <menu name=\"File\" action=\"gfig-file-menu\">"
1003 " <menuitem action=\"open\" />"
1004 " <menuitem action=\"save\" />"
1005 " <menuitem action=\"close\" />"
1006 " </menu>"
1007 " <menu name=\"Edit\" action=\"gfig-edit-menu\">"
1008 " <menuitem action=\"undo\" />"
1009 " <menuitem action=\"clear\" />"
1010 " <menuitem action=\"grid\" />"
1011 " <menuitem action=\"prefs\" />"
1012 " </menu>"
1013 " </menubar>"
1014 "</ui>",
1015 -1, NULL);
1016 gtk_ui_manager_add_ui_from_string (ui_manager,
1017 "<ui>"
1018 " <toolbar name=\"gfig-toolbar\">"
1019 " <toolitem action=\"line\" />"
1020 " <toolitem action=\"rectangle\" />"
1021 " <toolitem action=\"circle\" />"
1022 " <toolitem action=\"ellipse\" />"
1023 " <toolitem action=\"arc\" />"
1024 " <toolitem action=\"polygon\" />"
1025 " <toolitem action=\"star\" />"
1026 " <toolitem action=\"spiral\" />"
1027 " <toolitem action=\"bezier\" />"
1028 " <toolitem action=\"move_obj\" />"
1029 " <toolitem action=\"move_point\" />"
1030 " <toolitem action=\"copy\" />"
1031 " <toolitem action=\"delete\" />"
1032 " <toolitem action=\"select\" />"
1033 " <separator />"
1034 " <toolitem action=\"raise\" />"
1035 " <toolitem action=\"lower\" />"
1036 " <toolitem action=\"top\" />"
1037 " <toolitem action=\"bottom\" />"
1038 " <separator />"
1039 " <toolitem action=\"show_previous\" />"
1040 " <toolitem action=\"show_next\" />"
1041 " <toolitem action=\"show_all\" />"
1042 " </toolbar>"
1043 "</ui>",
1044 -1, NULL);
1045
1046 return ui_manager;
1047 }
1048
1049 static void
tool_option_no_option(GtkWidget * notebook)1050 tool_option_no_option (GtkWidget *notebook)
1051 {
1052 GtkWidget *label;
1053
1054 label = gtk_label_new (_("This tool has no options"));
1055 gtk_widget_show (label);
1056 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label, NULL);
1057 }
1058
1059 static void
create_notebook_pages(GtkWidget * notebook)1060 create_notebook_pages (GtkWidget *notebook)
1061 {
1062 tool_option_no_option (notebook); /* Line */
1063 tool_option_no_option (notebook); /* Rectangle */
1064 tool_option_no_option (notebook); /* Circle */
1065 tool_option_no_option (notebook); /* Ellipse */
1066 tool_option_no_option (notebook); /* Arc */
1067 tool_options_poly (notebook); /* Polygon */
1068 tool_options_star (notebook); /* Star */
1069 tool_options_spiral (notebook); /* Spiral */
1070 tool_options_bezier (notebook); /* Bezier */
1071 tool_option_no_option (notebook); /* Dummy */
1072 tool_option_no_option (notebook); /* Move Object */
1073 tool_option_no_option (notebook); /* Move Point */
1074 tool_option_no_option (notebook); /* Copy Object */
1075 tool_option_no_option (notebook); /* Delete Object */
1076 }
1077
1078 static void
raise_selected_obj_to_top(GtkWidget * widget,gpointer data)1079 raise_selected_obj_to_top (GtkWidget *widget,
1080 gpointer data)
1081 {
1082 if (!gfig_context->selected_obj)
1083 return;
1084
1085 if (g_list_find (gfig_context->current_obj->obj_list,
1086 gfig_context->selected_obj))
1087 {
1088 gfig_context->current_obj->obj_list =
1089 g_list_remove (gfig_context->current_obj->obj_list,
1090 gfig_context->selected_obj);
1091 gfig_context->current_obj->obj_list =
1092 g_list_append (gfig_context->current_obj->obj_list,
1093 gfig_context->selected_obj);
1094 }
1095 else
1096 {
1097 g_message ("Trying to raise object that does not exist.");
1098 return;
1099 }
1100
1101 gfig_paint_callback ();
1102 }
1103
1104 static void
lower_selected_obj_to_bottom(GtkWidget * widget,gpointer data)1105 lower_selected_obj_to_bottom (GtkWidget *widget,
1106 gpointer data)
1107 {
1108 if (!gfig_context->selected_obj)
1109 return;
1110
1111 if (g_list_find (gfig_context->current_obj->obj_list,
1112 gfig_context->selected_obj))
1113 {
1114 gfig_context->current_obj->obj_list =
1115 g_list_remove (gfig_context->current_obj->obj_list,
1116 gfig_context->selected_obj);
1117 gfig_context->current_obj->obj_list =
1118 g_list_prepend (gfig_context->current_obj->obj_list,
1119 gfig_context->selected_obj);
1120 }
1121 else
1122 {
1123 g_message ("Trying to lower object that does not exist.");
1124 return;
1125 }
1126
1127 gfig_paint_callback ();
1128 }
1129
1130 static void
raise_selected_obj(GtkWidget * widget,gpointer data)1131 raise_selected_obj (GtkWidget *widget,
1132 gpointer data)
1133 {
1134 if (!gfig_context->selected_obj)
1135 return;
1136
1137 if (g_list_find (gfig_context->current_obj->obj_list,
1138 gfig_context->selected_obj))
1139 {
1140 int position;
1141
1142 position = g_list_index (gfig_context->current_obj->obj_list,
1143 gfig_context->selected_obj);
1144 gfig_context->current_obj->obj_list =
1145 g_list_remove (gfig_context->current_obj->obj_list,
1146 gfig_context->selected_obj);
1147 gfig_context->current_obj->obj_list =
1148 g_list_insert (gfig_context->current_obj->obj_list,
1149 gfig_context->selected_obj,
1150 position + 1);
1151 }
1152 else
1153 {
1154 g_message ("Trying to raise object that does not exist.");
1155 return;
1156 }
1157
1158 gfig_paint_callback ();
1159 }
1160
1161
1162 static void
lower_selected_obj(GtkWidget * widget,gpointer data)1163 lower_selected_obj (GtkWidget *widget,
1164 gpointer data)
1165 {
1166 if (!gfig_context->selected_obj)
1167 return;
1168
1169 if (g_list_find (gfig_context->current_obj->obj_list,
1170 gfig_context->selected_obj))
1171 {
1172 int position;
1173
1174 position = g_list_index (gfig_context->current_obj->obj_list,
1175 gfig_context->selected_obj);
1176 gfig_context->current_obj->obj_list =
1177 g_list_remove (gfig_context->current_obj->obj_list,
1178 gfig_context->selected_obj);
1179 gfig_context->current_obj->obj_list =
1180 g_list_insert (gfig_context->current_obj->obj_list,
1181 gfig_context->selected_obj,
1182 MAX (0, position - 1));
1183 }
1184 else
1185 {
1186 g_message ("Trying to lower object that does not exist.");
1187 return;
1188 }
1189
1190 gfig_paint_callback ();
1191 }
1192
1193
1194 static void
select_filltype_callback(GtkWidget * widget)1195 select_filltype_callback (GtkWidget *widget)
1196 {
1197 gint value;
1198
1199 gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value);
1200 gtk_notebook_set_current_page (GTK_NOTEBOOK (fill_type_notebook),
1201 MIN (value, FILL_GRADIENT));
1202
1203 gfig_context_get_current_style ()->fill_type = (FillType) value;
1204
1205 gfig_paint_callback ();
1206 }
1207
1208 static gboolean
gfig_paint_timeout(gpointer data)1209 gfig_paint_timeout (gpointer data)
1210 {
1211 gfig_paint_callback ();
1212
1213 paint_timeout = 0;
1214
1215 return FALSE;
1216 }
1217
1218 static void
gfig_paint_delayed(void)1219 gfig_paint_delayed (void)
1220 {
1221 if (paint_timeout)
1222 g_source_remove (paint_timeout);
1223
1224 paint_timeout =
1225 g_timeout_add (UPDATE_DELAY, gfig_paint_timeout, NULL);
1226 }
1227
1228 static void
gfig_prefs_action_callback(GtkAction * widget,gpointer data)1229 gfig_prefs_action_callback (GtkAction *widget,
1230 gpointer data)
1231 {
1232 static GtkWidget *dialog = NULL;
1233
1234 if (!dialog)
1235 {
1236 GtkWidget *main_vbox;
1237 GtkWidget *table;
1238 GtkWidget *toggle;
1239 GtkObject *size_data;
1240 GtkWidget *scale;
1241 GtkAdjustment *scale_data;
1242
1243 dialog = gimp_dialog_new (_("Options"), "gimp-gfig-options",
1244 GTK_WIDGET (data), 0, NULL, NULL,
1245
1246 _("_Close"), GTK_RESPONSE_CLOSE,
1247
1248 NULL);
1249
1250 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
1251
1252 g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
1253
1254 g_signal_connect (dialog, "response",
1255 G_CALLBACK (gtk_widget_destroy),
1256 NULL);
1257
1258 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1259 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
1260 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
1261 main_vbox, TRUE, TRUE, 0);
1262 gtk_widget_show (main_vbox);
1263
1264 /* Put buttons in */
1265 toggle = gtk_check_button_new_with_label (_("Show position"));
1266 gtk_box_pack_start (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 6);
1267 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
1268 selvals.showpos);
1269 g_signal_connect (toggle, "toggled",
1270 G_CALLBACK (gimp_toggle_button_update),
1271 &selvals.showpos);
1272 g_signal_connect_after (toggle, "toggled",
1273 G_CALLBACK (gfig_pos_enable),
1274 NULL);
1275 gtk_widget_show (toggle);
1276
1277 toggle = gtk_check_button_new_with_label (_("Show control points"));
1278 gtk_box_pack_start (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 6);
1279 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
1280 selvals.opts.showcontrol);
1281 g_signal_connect (toggle, "toggled",
1282 G_CALLBACK (gimp_toggle_button_update),
1283 &selvals.opts.showcontrol);
1284 g_signal_connect (toggle, "toggled",
1285 G_CALLBACK (toggle_show_image),
1286 NULL);
1287 gtk_widget_show (toggle);
1288
1289 gfig_opt_widget.showcontrol = toggle;
1290 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.showcontrol),
1291 (gpointer) &gfig_opt_widget.showcontrol);
1292
1293 toggle = gtk_check_button_new_with_label (_("Antialiasing"));
1294 gtk_box_pack_start (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 6);
1295 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), selopt.antia);
1296 g_signal_connect (toggle, "toggled",
1297 G_CALLBACK (gimp_toggle_button_update),
1298 &selopt.antia);
1299 g_signal_connect (toggle, "toggled",
1300 G_CALLBACK (gfig_paint_callback),
1301 NULL);
1302 gtk_widget_show (toggle);
1303
1304 table = gtk_table_new (4, 4, FALSE);
1305 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1306 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1307 gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 6);
1308 gtk_widget_show (table);
1309
1310 size_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
1311 _("Max undo:"), 100, 50,
1312 selvals.maxundo,
1313 MIN_UNDO, MAX_UNDO, 1, 2, 0,
1314 TRUE, 0, 0,
1315 NULL, NULL);
1316 g_signal_connect (size_data, "value-changed",
1317 G_CALLBACK (gimp_int_adjustment_update),
1318 &selvals.maxundo);
1319
1320 page_menu_bg = gimp_int_combo_box_new (_("Transparent"), LAYER_TRANS_BG,
1321 _("Background"), LAYER_BG_BG,
1322 _("Foreground"), LAYER_FG_BG,
1323 _("White"), LAYER_WHITE_BG,
1324 _("Copy"), LAYER_COPY_BG,
1325 NULL);
1326 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (page_menu_bg), selvals.onlayerbg);
1327
1328 g_signal_connect (page_menu_bg, "changed",
1329 G_CALLBACK (paint_combo_callback),
1330 GINT_TO_POINTER (PAINT_BGS_MENU));
1331
1332 gimp_help_set_help_data (page_menu_bg,
1333 _("Layer background type. Copy causes the "
1334 "previous layer to be copied before the "
1335 "draw is performed."),
1336 NULL);
1337
1338 gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
1339 _("Background:"), 0.0, 0.5,
1340 page_menu_bg, 2, FALSE);
1341
1342 toggle = gtk_check_button_new_with_label (_("Feather"));
1343 gtk_table_attach (GTK_TABLE (table), toggle, 2, 3, 2, 3,
1344 GTK_FILL, GTK_FILL, 0, 0);
1345 g_signal_connect (toggle, "toggled",
1346 G_CALLBACK (gimp_toggle_button_update),
1347 &selopt.feather);
1348 g_signal_connect (toggle, "toggled",
1349 G_CALLBACK (gfig_paint_callback),
1350 NULL);
1351 gtk_widget_show (toggle);
1352
1353 scale_data = (GtkAdjustment *)
1354 gtk_adjustment_new (selopt.feather_radius, 0.0, 100.0, 1.0, 1.0, 0.0);
1355 scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_data);
1356 gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
1357
1358 g_signal_connect (scale_data, "value-changed",
1359 G_CALLBACK (gimp_double_adjustment_update),
1360 &selopt.feather_radius);
1361 g_signal_connect (scale_data, "value-changed",
1362 G_CALLBACK (gfig_paint_delayed),
1363 NULL);
1364 gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
1365 _("Radius:"), 0.0, 1.0, scale, 1, FALSE);
1366
1367 gtk_widget_show (dialog);
1368 }
1369 else
1370 {
1371 gtk_window_present (GTK_WINDOW (dialog));
1372 }
1373 }
1374
1375 static void
gfig_grid_action_callback(GtkAction * action,gpointer data)1376 gfig_grid_action_callback (GtkAction *action,
1377 gpointer data)
1378 {
1379 static GtkWidget *dialog = NULL;
1380
1381 if (!dialog)
1382 {
1383 GtkWidget *main_vbox;
1384 GtkWidget *hbox;
1385 GtkWidget *table;
1386 GtkWidget *combo;
1387 GtkObject *size_data;
1388 GtkObject *sectors_data;
1389 GtkObject *radius_data;
1390
1391 dialog = gimp_dialog_new (_("Grid"), "gimp-gfig-grid",
1392 GTK_WIDGET (data), 0, NULL, NULL,
1393
1394 _("_Close"), GTK_RESPONSE_CLOSE,
1395
1396 NULL);
1397
1398 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
1399
1400 g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
1401
1402 g_signal_connect (dialog, "response",
1403 G_CALLBACK (gtk_widget_destroy),
1404 NULL);
1405
1406 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1407 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
1408 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
1409 main_vbox, TRUE, TRUE, 0);
1410 gtk_widget_show (main_vbox);
1411
1412 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1413 gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
1414 gtk_widget_show (hbox);
1415
1416 table = gtk_table_new (3, 3, FALSE);
1417 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1418 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1419 gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
1420 gtk_widget_show (table);
1421
1422 size_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
1423 _("Grid spacing:"), 100, 50,
1424 selvals.opts.gridspacing,
1425 MIN_GRID, MAX_GRID, 1, 10, 0,
1426 TRUE, 0, 0,
1427 NULL, NULL);
1428 g_signal_connect (size_data, "value-changed",
1429 G_CALLBACK (gimp_int_adjustment_update),
1430 &selvals.opts.gridspacing);
1431 g_signal_connect (size_data, "value-changed",
1432 G_CALLBACK (draw_grid_clear),
1433 NULL);
1434
1435 gfig_opt_widget.gridspacing = GTK_ADJUSTMENT (size_data);
1436 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.gridspacing),
1437 (gpointer) &gfig_opt_widget.gridspacing);
1438
1439 sectors_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 3,
1440 _("Polar grid sectors desired:"), 1, 5,
1441 selvals.opts.grid_sectors_desired,
1442 5, 360, 5, 1, 0,
1443 TRUE, 0, 0,
1444 NULL, NULL);
1445 g_signal_connect (sectors_data, "value-changed",
1446 G_CALLBACK (gimp_int_adjustment_update),
1447 &selvals.opts.grid_sectors_desired);
1448 g_signal_connect (sectors_data, "value-changed",
1449 G_CALLBACK (draw_grid_clear),
1450 NULL);
1451
1452 gfig_opt_widget.grid_sectors_desired = GTK_ADJUSTMENT (sectors_data);
1453 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.grid_sectors_desired),
1454 (gpointer) &gfig_opt_widget.grid_sectors_desired);
1455
1456
1457 gfig_opt_widget.gridspacing = GTK_ADJUSTMENT (size_data);
1458 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.gridspacing),
1459 (gpointer) &gfig_opt_widget.gridspacing);
1460
1461 radius_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 4,
1462 _("Polar grid radius interval:"), 1, 5,
1463 selvals.opts.grid_radius_interval,
1464 5, 50, 5, 1, 0,
1465 TRUE, 0, 0,
1466 NULL, NULL);
1467 g_signal_connect (radius_data, "value-changed",
1468 G_CALLBACK (gimp_double_adjustment_update),
1469 &selvals.opts.grid_radius_interval);
1470 g_signal_connect (radius_data, "value-changed",
1471 G_CALLBACK (draw_grid_clear),
1472 NULL);
1473
1474 gfig_opt_widget.grid_radius_interval = GTK_ADJUSTMENT (radius_data);
1475 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.grid_radius_interval),
1476 (gpointer) &gfig_opt_widget.grid_radius_interval);
1477
1478 combo = gimp_int_combo_box_new (_("Rectangle"), RECT_GRID,
1479 _("Polar"), POLAR_GRID,
1480 _("Isometric"), ISO_GRID,
1481 NULL);
1482 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), selvals.opts.gridtype);
1483
1484 g_signal_connect (combo, "changed",
1485 G_CALLBACK (gridtype_combo_callback),
1486 GINT_TO_POINTER (GRID_TYPE_MENU));
1487
1488 gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
1489 _("Grid type:"), 0.0, 0.5,
1490 combo, 2, FALSE);
1491
1492 gfig_opt_widget.gridtypemenu = combo;
1493 g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.gridtypemenu),
1494 (gpointer) &gfig_opt_widget.gridtypemenu);
1495
1496 combo = gimp_int_combo_box_new (_("Normal"), GFIG_NORMAL_GC,
1497 _("Black"), GFIG_BLACK_GC,
1498 _("White"), GFIG_WHITE_GC,
1499 _("Grey"), GFIG_GREY_GC,
1500 _("Darker"), GFIG_DARKER_GC,
1501 _("Lighter"), GFIG_LIGHTER_GC,
1502 _("Very dark"), GFIG_VERY_DARK_GC,
1503 NULL);
1504 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), grid_gc_type);
1505
1506 g_signal_connect (combo, "changed",
1507 G_CALLBACK (gridtype_combo_callback),
1508 GINT_TO_POINTER (GRID_RENDER_MENU));
1509
1510 gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
1511 _("Grid color:"), 0.0, 0.5,
1512 combo, 2, FALSE);
1513
1514 gtk_widget_show (dialog);
1515 }
1516 else
1517 {
1518 gtk_window_present (GTK_WINDOW (dialog));
1519 }
1520 }
1521
1522 void
options_update(GFigObj * old_obj)1523 options_update (GFigObj *old_obj)
1524 {
1525 /* Save old vals */
1526 if (selvals.opts.gridspacing != old_obj->opts.gridspacing)
1527 {
1528 old_obj->opts.gridspacing = selvals.opts.gridspacing;
1529 }
1530 if (selvals.opts.grid_sectors_desired != old_obj->opts.grid_sectors_desired)
1531 {
1532 old_obj->opts.grid_sectors_desired = selvals.opts.grid_sectors_desired;
1533 }
1534 if (selvals.opts.grid_radius_interval != old_obj->opts.grid_radius_interval)
1535 {
1536 old_obj->opts.grid_radius_interval = selvals.opts.grid_radius_interval;
1537 }
1538 if (selvals.opts.gridtype != old_obj->opts.gridtype)
1539 {
1540 old_obj->opts.gridtype = selvals.opts.gridtype;
1541 }
1542 if (selvals.opts.drawgrid != old_obj->opts.drawgrid)
1543 {
1544 old_obj->opts.drawgrid = selvals.opts.drawgrid;
1545 }
1546 if (selvals.opts.snap2grid != old_obj->opts.snap2grid)
1547 {
1548 old_obj->opts.snap2grid = selvals.opts.snap2grid;
1549 }
1550 if (selvals.opts.lockongrid != old_obj->opts.lockongrid)
1551 {
1552 old_obj->opts.lockongrid = selvals.opts.lockongrid;
1553 }
1554 if (selvals.opts.showcontrol != old_obj->opts.showcontrol)
1555 {
1556 old_obj->opts.showcontrol = selvals.opts.showcontrol;
1557 }
1558
1559 /* New vals */
1560 if (selvals.opts.gridspacing != gfig_context->current_obj->opts.gridspacing)
1561 {
1562 if (gfig_opt_widget.gridspacing)
1563 gtk_adjustment_set_value (gfig_opt_widget.gridspacing,
1564 gfig_context->current_obj->opts.gridspacing);
1565 }
1566 if (selvals.opts.grid_sectors_desired != gfig_context->current_obj->opts.grid_sectors_desired)
1567 {
1568 if (gfig_opt_widget.grid_sectors_desired)
1569 gtk_adjustment_set_value (gfig_opt_widget.grid_sectors_desired,
1570 gfig_context->current_obj->opts.grid_sectors_desired);
1571 }
1572 if (selvals.opts.grid_radius_interval != gfig_context->current_obj->opts.grid_radius_interval)
1573 {
1574 if (gfig_opt_widget.grid_radius_interval)
1575 gtk_adjustment_set_value (gfig_opt_widget.grid_radius_interval,
1576 gfig_context->current_obj->opts.grid_radius_interval);
1577 }
1578 if (selvals.opts.gridtype != gfig_context->current_obj->opts.gridtype)
1579 {
1580 if (gfig_opt_widget.gridtypemenu)
1581 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (gfig_opt_widget.gridtypemenu),
1582 gfig_context->current_obj->opts.gridtype);
1583 }
1584 if (selvals.opts.drawgrid != gfig_context->current_obj->opts.drawgrid)
1585 {
1586 if (gfig_opt_widget.drawgrid)
1587 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gfig_opt_widget.drawgrid),
1588 gfig_context->current_obj->opts.drawgrid);
1589 }
1590 if (selvals.opts.snap2grid != gfig_context->current_obj->opts.snap2grid)
1591 {
1592 if (gfig_opt_widget.snap2grid)
1593 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gfig_opt_widget.snap2grid),
1594 gfig_context->current_obj->opts.snap2grid);
1595 }
1596 if (selvals.opts.lockongrid != gfig_context->current_obj->opts.lockongrid)
1597 {
1598 if (gfig_opt_widget.lockongrid)
1599 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gfig_opt_widget.lockongrid),
1600 gfig_context->current_obj->opts.lockongrid);
1601 }
1602 if (selvals.opts.showcontrol != gfig_context->current_obj->opts.showcontrol)
1603 {
1604 if (gfig_opt_widget.showcontrol)
1605 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gfig_opt_widget.showcontrol),
1606 gfig_context->current_obj->opts.showcontrol);
1607 }
1608 }
1609
1610 static void
save_file_chooser_response(GtkFileChooser * chooser,gint response_id,GFigObj * obj)1611 save_file_chooser_response (GtkFileChooser *chooser,
1612 gint response_id,
1613 GFigObj *obj)
1614 {
1615 if (response_id == GTK_RESPONSE_OK)
1616 {
1617 gchar *filename;
1618
1619 filename = gtk_file_chooser_get_filename (chooser);
1620
1621 obj->filename = filename;
1622
1623 gfig_context->current_obj = obj;
1624 gfig_save_callbk ();
1625 }
1626
1627 gtk_widget_destroy (GTK_WIDGET (chooser));
1628 }
1629
1630 static GfigObject *
gfig_select_obj_by_number(gint count)1631 gfig_select_obj_by_number (gint count)
1632 {
1633 GList *objs;
1634 GfigObject *object = NULL;
1635 gint k;
1636
1637 gfig_context->selected_obj = NULL;
1638
1639 for (objs = gfig_context->current_obj->obj_list, k = 0;
1640 objs;
1641 objs = g_list_next (objs), k++)
1642 {
1643 if (k == obj_show_single)
1644 {
1645 object = objs->data;
1646 gfig_context->selected_obj = object;
1647 gfig_style_set_context_from_style (&object->style);
1648 break;
1649 }
1650 }
1651
1652 return object;
1653 }
1654
1655 static void
select_button_clicked(gint type)1656 select_button_clicked (gint type)
1657 {
1658 gint count = 0;
1659
1660 if (gfig_context->current_obj)
1661 {
1662 count = g_list_length (gfig_context->current_obj->obj_list);
1663 }
1664
1665 switch (type)
1666 {
1667 case OBJ_SELECT_LT:
1668 obj_show_single--;
1669 if (obj_show_single < 0)
1670 obj_show_single = count - 1;
1671 break;
1672
1673 case OBJ_SELECT_GT:
1674 obj_show_single++;
1675 if (obj_show_single >= count)
1676 obj_show_single = 0;
1677 break;
1678
1679 case OBJ_SELECT_EQ:
1680 obj_show_single = -1; /* Reset to show all */
1681 break;
1682
1683 default:
1684 break;
1685 }
1686
1687 if (obj_show_single >= 0)
1688 gfig_select_obj_by_number (obj_show_single);
1689
1690 draw_grid_clear ();
1691 gfig_paint_callback ();
1692 }
1693
1694 static void
select_button_clicked_lt(void)1695 select_button_clicked_lt (void)
1696 {
1697 select_button_clicked (OBJ_SELECT_LT);
1698 }
1699
1700 static void
select_button_clicked_gt(void)1701 select_button_clicked_gt (void)
1702 {
1703 select_button_clicked (OBJ_SELECT_GT);
1704 }
1705
1706 static void
select_button_clicked_eq(void)1707 select_button_clicked_eq (void)
1708 {
1709 select_button_clicked (OBJ_SELECT_EQ);
1710 }
1711
1712 /* Special case for now - options on poly/star/spiral button */
1713
1714 GtkWidget *
num_sides_widget(const gchar * d_title,gint * num_sides,gint * which_way,gint adj_min,gint adj_max)1715 num_sides_widget (const gchar *d_title,
1716 gint *num_sides,
1717 gint *which_way,
1718 gint adj_min,
1719 gint adj_max)
1720 {
1721 GtkWidget *table;
1722 GtkObject *size_data;
1723
1724 table = gtk_table_new (which_way ? 2 : 1, 3, FALSE);
1725 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1726 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1727 gtk_container_set_border_width (GTK_CONTAINER (table), 12);
1728 gtk_widget_show (table);
1729
1730 size_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
1731 _("Sides:"), 0, 0,
1732 *num_sides, adj_min, adj_max, 1, 10, 0,
1733 TRUE, 0, 0,
1734 NULL, NULL);
1735 g_signal_connect (size_data, "value-changed",
1736 G_CALLBACK (gimp_int_adjustment_update),
1737 num_sides);
1738
1739 if (which_way)
1740 {
1741 GtkWidget *combo = gimp_int_combo_box_new (_("Right"), 0,
1742 _("Left"), 1,
1743 NULL);
1744
1745 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), *which_way);
1746
1747 g_signal_connect (combo, "changed",
1748 G_CALLBACK (gimp_int_combo_box_get_active),
1749 which_way);
1750
1751 gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
1752 _("Orientation:"), 0.0, 0.5,
1753 combo, 1, FALSE);
1754 }
1755 return table;
1756 }
1757
1758 void
gfig_paint(BrushType brush_type,gint32 drawable_ID,gint seg_count,gdouble line_pnts[])1759 gfig_paint (BrushType brush_type,
1760 gint32 drawable_ID,
1761 gint seg_count,
1762 gdouble line_pnts[])
1763 {
1764 switch (brush_type)
1765 {
1766 case BRUSH_BRUSH_TYPE:
1767 gimp_paintbrush (drawable_ID,
1768 selvals.brushfade,
1769 seg_count, line_pnts,
1770 GIMP_PAINT_CONSTANT,
1771 selvals.brushgradient);
1772 break;
1773
1774 case BRUSH_PENCIL_TYPE:
1775 gimp_pencil (drawable_ID,
1776 seg_count, line_pnts);
1777 break;
1778
1779 case BRUSH_AIRBRUSH_TYPE:
1780 gimp_airbrush (drawable_ID,
1781 selvals.airbrushpressure,
1782 seg_count, line_pnts);
1783 break;
1784
1785 case BRUSH_PATTERN_TYPE:
1786 gimp_clone (drawable_ID,
1787 drawable_ID,
1788 GIMP_CLONE_PATTERN,
1789 0.0, 0.0,
1790 seg_count, line_pnts);
1791 break;
1792 }
1793 }
1794
1795
1796 static void
paint_combo_callback(GtkWidget * widget,gpointer data)1797 paint_combo_callback (GtkWidget *widget,
1798 gpointer data)
1799 {
1800 gint mtype = GPOINTER_TO_INT (data);
1801 gint value;
1802
1803 gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value);
1804
1805 switch (mtype)
1806 {
1807 case PAINT_BGS_MENU:
1808 selvals.onlayerbg = (LayersBGType) value;
1809 break;
1810
1811 default:
1812 g_return_if_reached ();
1813 break;
1814 }
1815
1816 gfig_paint_callback ();
1817 }
1818
1819
1820 static void
gridtype_combo_callback(GtkWidget * widget,gpointer data)1821 gridtype_combo_callback (GtkWidget *widget,
1822 gpointer data)
1823 {
1824 gint mtype = GPOINTER_TO_INT (data);
1825 gint value;
1826
1827 gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value);
1828
1829 switch (mtype)
1830 {
1831 case GRID_TYPE_MENU:
1832 selvals.opts.gridtype = value;
1833 break;
1834
1835 case GRID_RENDER_MENU:
1836 grid_gc_type = value;
1837 break;
1838
1839 default:
1840 g_return_if_reached ();
1841 break;
1842 }
1843
1844 draw_grid_clear ();
1845 }
1846
1847 /*
1848 * The edit gfig name attributes dialog
1849 * Modified from Gimp source - layer edit.
1850 */
1851
1852 typedef struct _GfigListOptions
1853 {
1854 GtkWidget *query_box;
1855 GtkWidget *name_entry;
1856 GtkWidget *list_entry;
1857 GFigObj *obj;
1858 gboolean created;
1859 } GfigListOptions;
1860
1861 static void
load_file_chooser_response(GtkFileChooser * chooser,gint response_id,gpointer data)1862 load_file_chooser_response (GtkFileChooser *chooser,
1863 gint response_id,
1864 gpointer data)
1865 {
1866 if (response_id == GTK_RESPONSE_OK)
1867 {
1868 gchar *filename;
1869 GFigObj *gfig;
1870 GFigObj *current_saved;
1871
1872 filename = gtk_file_chooser_get_filename (chooser);
1873
1874 if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
1875 {
1876 /* Hack - current object MUST be NULL to prevent setup_undo ()
1877 * from kicking in.
1878 */
1879 current_saved = gfig_context->current_obj;
1880 gfig_context->current_obj = NULL;
1881 gfig = gfig_load (filename, filename);
1882 gfig_context->current_obj = current_saved;
1883
1884 if (gfig)
1885 {
1886 /* Read only ?*/
1887 if (access (filename, W_OK))
1888 gfig->obj_status |= GFIG_READONLY;
1889
1890 gfig_list_insert (gfig);
1891 new_obj_2edit (gfig);
1892 }
1893 }
1894
1895 g_free (filename);
1896 }
1897
1898 gtk_widget_destroy (GTK_WIDGET (chooser));
1899 gfig_paint_callback ();
1900 }
1901
1902 void
paint_layer_fill(gdouble x1,gdouble y1,gdouble x2,gdouble y2)1903 paint_layer_fill (gdouble x1, gdouble y1, gdouble x2, gdouble y2)
1904 {
1905 GimpFillType fill_type = GIMP_FILL_FOREGROUND;
1906 Style *current_style;
1907
1908 current_style = gfig_context_get_current_style ();
1909
1910 gimp_context_push ();
1911
1912 gimp_context_set_paint_mode (GIMP_LAYER_MODE_NORMAL_LEGACY);
1913 gimp_context_set_opacity (100.0);
1914 gimp_context_set_gradient_repeat_mode (GIMP_REPEAT_NONE);
1915 gimp_context_set_gradient_reverse (FALSE);
1916
1917 switch (current_style->fill_type)
1918 {
1919 case FILL_NONE:
1920 return;
1921
1922 case FILL_COLOR:
1923 fill_type = GIMP_FILL_BACKGROUND;
1924 break;
1925
1926 case FILL_PATTERN:
1927 fill_type = GIMP_FILL_PATTERN;
1928 break;
1929
1930 case FILL_GRADIENT:
1931 gimp_drawable_edit_gradient_fill (gfig_context->drawable_id,
1932 GIMP_GRADIENT_SHAPEBURST_DIMPLED,
1933 0.0, /* offset */
1934 FALSE, /* supersampling */
1935 0, /* max_depth */
1936 0.0, /* threshold */
1937 FALSE, /* dither */
1938 0.0, 0.0, /* (x1, y1) - ignored */
1939 0.0, 0.0); /* (x2, y2) - ignored */
1940 return;
1941 case FILL_VERTICAL:
1942 gimp_drawable_edit_gradient_fill (gfig_context->drawable_id,
1943 GIMP_GRADIENT_LINEAR,
1944 0.0,
1945 FALSE,
1946 0,
1947 0.0,
1948 FALSE,
1949 x1, y1,
1950 x1, y2);
1951 return;
1952 case FILL_HORIZONTAL:
1953 gimp_drawable_edit_gradient_fill (gfig_context->drawable_id,
1954 GIMP_GRADIENT_LINEAR,
1955 0.0,
1956 FALSE,
1957 0,
1958 0.0,
1959 FALSE,
1960 x1, y1,
1961 x2, y1);
1962 return;
1963 }
1964
1965 gimp_context_set_opacity (current_style->fill_opacity);
1966
1967 gimp_drawable_edit_fill (gfig_context->drawable_id,
1968 fill_type);
1969
1970 gimp_context_pop ();
1971 }
1972
1973 void
gfig_paint_callback(void)1974 gfig_paint_callback (void)
1975 {
1976 GList *objs;
1977 gint ccount = 0;
1978 GfigObject *object;
1979
1980 if (!gfig_context->enable_repaint || !gfig_context->current_obj)
1981 return;
1982
1983 objs = gfig_context->current_obj->obj_list;
1984
1985 gimp_drawable_fill (gfig_context->drawable_id, GIMP_FILL_TRANSPARENT);
1986
1987 while (objs)
1988 {
1989 if (ccount == obj_show_single || obj_show_single == -1)
1990 {
1991 FillType saved_filltype;
1992
1993 object = objs->data;
1994
1995 gfig_style_apply (&object->style);
1996
1997 saved_filltype = gfig_context_get_current_style ()->fill_type;
1998 gfig_context_get_current_style ()->fill_type = object->style.fill_type;
1999 object->class->paintfunc (object);
2000 gfig_context_get_current_style ()->fill_type = saved_filltype;
2001 }
2002
2003 objs = g_list_next (objs);
2004
2005 ccount++;
2006 }
2007
2008 gimp_displays_flush ();
2009
2010 if (back_pixbuf)
2011 {
2012 g_object_unref (back_pixbuf);
2013 back_pixbuf = NULL;
2014 }
2015
2016 gtk_widget_queue_draw (gfig_context->preview);
2017 }
2018
2019 /* Draw the grid on the screen
2020 */
2021
2022 void
draw_grid_clear(void)2023 draw_grid_clear (void)
2024 {
2025 /* wipe slate and start again */
2026 gtk_widget_queue_draw (gfig_context->preview);
2027 }
2028
2029 static void
toggle_show_image(void)2030 toggle_show_image (void)
2031 {
2032 /* wipe slate and start again */
2033 draw_grid_clear ();
2034 }
2035
2036 static void
toggle_obj_type(GtkRadioAction * action,GtkRadioAction * current,gpointer data)2037 toggle_obj_type (GtkRadioAction *action,
2038 GtkRadioAction *current,
2039 gpointer data)
2040 {
2041 static GdkCursor *p_cursors[DEL_OBJ + 1];
2042 GdkCursorType ctype = GDK_LAST_CURSOR;
2043 DobjType new_type;
2044
2045 new_type = gtk_radio_action_get_current_value (action);
2046 if (selvals.otype != new_type)
2047 {
2048 /* Mem leak */
2049 obj_creating = NULL;
2050 tmp_line = NULL;
2051 tmp_bezier = NULL;
2052
2053 if (new_type < MOVE_OBJ) /* Eeeeek */
2054 {
2055 obj_show_single = -1; /* Cancel select preview */
2056 }
2057 /* Update draw areas */
2058 gtk_widget_queue_draw (gfig_context->preview);
2059 }
2060
2061 selvals.otype = new_type;
2062 gtk_notebook_set_current_page (GTK_NOTEBOOK (tool_options_notebook),
2063 new_type - 1);
2064
2065 switch (selvals.otype)
2066 {
2067 case LINE:
2068 case RECTANGLE:
2069 case CIRCLE:
2070 case ELLIPSE:
2071 case ARC:
2072 case POLY:
2073 case STAR:
2074 case SPIRAL:
2075 case BEZIER:
2076 default:
2077 ctype = GDK_CROSSHAIR;
2078 break;
2079 case MOVE_OBJ:
2080 case MOVE_POINT:
2081 case COPY_OBJ:
2082 case MOVE_COPY_OBJ:
2083 ctype = GDK_DIAMOND_CROSS;
2084 break;
2085 case DEL_OBJ:
2086 ctype = GDK_PIRATE;
2087 break;
2088 }
2089
2090 if (!p_cursors[selvals.otype])
2091 {
2092 GdkDisplay *display = gtk_widget_get_display (gfig_context->preview);
2093
2094 p_cursors[selvals.otype] = gdk_cursor_new_for_display (display, ctype);
2095 }
2096
2097 gdk_window_set_cursor (gtk_widget_get_window (gfig_context->preview),
2098 p_cursors[selvals.otype]);
2099 }
2100
2101 /* This could belong in a separate file ... but makes it easier to lump into
2102 * one when compiling the plugin.
2103 */
2104
2105 /* Given a number of float co-ords adjust for scaling back to org size */
2106 /* Size is number of PAIRS of points */
2107 /* FP + int variants */
2108
2109 static void
scale_to_orginal_x(gdouble * list)2110 scale_to_orginal_x (gdouble *list)
2111 {
2112 *list *= scale_x_factor;
2113 }
2114
2115 gint
gfig_scale_x(gint x)2116 gfig_scale_x (gint x)
2117 {
2118 if (!selvals.scaletoimage)
2119 return (gint) (x * (1 / scale_x_factor));
2120 else
2121 return x;
2122 }
2123
2124 static void
scale_to_orginal_y(gdouble * list)2125 scale_to_orginal_y (gdouble *list)
2126 {
2127 *list *= scale_y_factor;
2128 }
2129
2130 gint
gfig_scale_y(gint y)2131 gfig_scale_y (gint y)
2132 {
2133 if (!selvals.scaletoimage)
2134 return (gint) (y * (1 / scale_y_factor));
2135 else
2136 return y;
2137 }
2138
2139 /* Pairs x followed by y */
2140 void
scale_to_original_xy(gdouble * list,gint size)2141 scale_to_original_xy (gdouble *list,
2142 gint size)
2143 {
2144 gint i;
2145
2146 for (i = 0; i < size * 2; i += 2)
2147 {
2148 scale_to_orginal_x (&list[i]);
2149 scale_to_orginal_y (&list[i + 1]);
2150 }
2151 }
2152
2153 /* Pairs x followed by y */
2154 void
scale_to_xy(gdouble * list,gint size)2155 scale_to_xy (gdouble *list,
2156 gint size)
2157 {
2158 gint i;
2159
2160 for (i = 0; i < size * 2; i += 2)
2161 {
2162 list[i] *= (org_scale_x_factor / scale_x_factor);
2163 list[i + 1] *= (org_scale_y_factor / scale_y_factor);
2164 }
2165 }
2166
2167 void
gfig_draw_arc(gint x,gint y,gint width,gint height,gint angle1,gint angle2,cairo_t * cr)2168 gfig_draw_arc (gint x, gint y, gint width, gint height, gint angle1,
2169 gint angle2, cairo_t *cr)
2170 {
2171 cairo_save (cr);
2172
2173 cairo_translate (cr, gfig_scale_x (x), gfig_scale_y (y));
2174 cairo_scale (cr, gfig_scale_x (width), gfig_scale_y (height));
2175
2176 if (angle1 < angle2)
2177 cairo_arc (cr, 0., 0., 1., angle1 * G_PI / 180, angle2 * G_PI / 180);
2178 else
2179 cairo_arc_negative (cr, 0., 0., 1., angle1 * G_PI / 180, angle2 * G_PI / 180);
2180
2181 cairo_restore (cr);
2182
2183 draw_item (cr, FALSE);
2184 }
2185
2186 void
gfig_draw_line(gint x0,gint y0,gint x1,gint y1,cairo_t * cr)2187 gfig_draw_line (gint x0, gint y0, gint x1, gint y1, cairo_t *cr)
2188 {
2189 cairo_move_to (cr, gfig_scale_x (x0) + .5, gfig_scale_y (y0) + .5);
2190 cairo_line_to (cr, gfig_scale_x (x1) + .5, gfig_scale_y (y1) + .5);
2191
2192 draw_item (cr, FALSE);
2193 }
2194