using dia-manual.chm instead of dia.chm
[dia.git] / app / lineprops_area.c
blob6ff6d84562b3f6f440b7099d3e2ec08387373e11
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * lineprops_area.h -- Copyright (C) 1999 James Henstridge.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include "intl.h"
26 #include "widgets.h"
27 #include "lineprops_area.h"
28 #include "interface.h"
29 #include "render_pixmap.h"
31 #include <gtk/gtk.h>
33 /* --------------- DiaArrowPreview -------------------------------- */
34 typedef struct _DiaArrowPreview DiaArrowPreview;
35 typedef struct _DiaArrowPreviewClass DiaArrowPreviewClass;
37 static GtkType dia_arrow_preview_get_type (void);
38 static GtkWidget *dia_arrow_preview_new (ArrowType atype, gboolean left);
39 static void dia_arrow_preview_set(DiaArrowPreview *arrow,
40 ArrowType atype, gboolean left);
42 #define DIA_ARROW_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_arrow_preview_get_type(), DiaArrowPreview))
43 #define DIA_ARROW_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_preview_get_type(), DiaArrowPreviewClass))
45 struct _DiaArrowPreview
47 GtkMisc misc;
48 ArrowType atype;
49 gboolean left;
51 struct _DiaArrowPreviewClass
53 GtkMiscClass parent_class;
56 static void dia_arrow_preview_class_init (DiaArrowPreviewClass *klass);
57 static void dia_arrow_preview_init (DiaArrowPreview *arrow);
58 static gint dia_arrow_preview_expose (GtkWidget *widget,
59 GdkEventExpose *event);
61 static GtkType
62 dia_arrow_preview_get_type (void)
64 static GtkType arrow_type = 0;
66 if (!arrow_type) {
67 static const GtkTypeInfo arrow_info = {
68 "DiaArrowPreview",
69 sizeof (DiaArrowPreview),
70 sizeof (DiaArrowPreviewClass),
71 (GtkClassInitFunc) dia_arrow_preview_class_init,
72 (GtkObjectInitFunc) dia_arrow_preview_init,
73 /* reserved_1 */ NULL,
74 /* reserved_2 */ NULL,
75 (GtkClassInitFunc) NULL,
77 arrow_type = gtk_type_unique (GTK_TYPE_MISC, &arrow_info);
79 return arrow_type;
82 static void
83 dia_arrow_preview_class_init (DiaArrowPreviewClass *class)
85 GtkWidgetClass *widget_class;
87 widget_class = (GtkWidgetClass *)class;
88 widget_class->expose_event = dia_arrow_preview_expose;
91 static void
92 dia_arrow_preview_init (DiaArrowPreview *arrow)
94 GTK_WIDGET_SET_FLAGS (arrow, GTK_NO_WINDOW);
96 GTK_WIDGET (arrow)->requisition.width = 30 + GTK_MISC (arrow)->xpad * 2;
97 GTK_WIDGET (arrow)->requisition.height = 20 + GTK_MISC (arrow)->ypad * 2;
99 arrow->atype = ARROW_NONE;
100 arrow->left = TRUE;
103 static GtkWidget *
104 dia_arrow_preview_new (ArrowType atype, gboolean left)
106 DiaArrowPreview *arrow = gtk_type_new (dia_arrow_preview_get_type());
108 arrow->atype = atype;
109 arrow->left = left;
110 return GTK_WIDGET(arrow);
113 static void
114 dia_arrow_preview_set(DiaArrowPreview *arrow, ArrowType atype, gboolean left)
116 if (arrow->atype != atype || arrow->left != left) {
117 arrow->atype = atype;
118 arrow->left = left;
119 if (GTK_WIDGET_DRAWABLE(arrow))
120 gtk_widget_queue_clear(GTK_WIDGET(arrow));
124 static gint
125 dia_arrow_preview_expose(GtkWidget *widget, GdkEventExpose *event)
127 if (GTK_WIDGET_DRAWABLE(widget)) {
128 Point from, to;
129 DiaRenderer *renderer;
130 DiaArrowPreview *arrow = DIA_ARROW_PREVIEW(widget);
131 GtkMisc *misc = GTK_MISC(widget);
132 gint width, height;
133 gint x, y;
134 GdkWindow *win;
135 int linewidth = 2;
136 DiaRendererClass *renderer_ops;
138 width = widget->allocation.width - misc->xpad * 2;
139 height = widget->allocation.height - misc->ypad * 2;
140 x = (widget->allocation.x + misc->xpad);
141 y = (widget->allocation.y + misc->ypad);
143 win = widget->window;
145 to.y = from.y = height/2;
146 if (arrow->left) {
147 from.x = width-linewidth;
148 to.x = 0;
149 } else {
150 from.x = 0;
151 to.x = width-linewidth;
153 renderer = new_pixmap_renderer(win, width, height);
154 renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
155 renderer_pixmap_set_pixmap(renderer, win, x, y, width, height);
156 renderer_ops->begin_render(renderer);
157 renderer_ops->set_linewidth(renderer, linewidth);
158 renderer_ops->draw_line(renderer, &to, &from, &color_black);
159 arrow_draw (renderer, arrow->atype,
160 &to, &from, (real)height-linewidth, (real)height-linewidth,
161 linewidth, &color_black, &color_white);
162 renderer_ops->end_render(renderer);
163 g_object_unref(renderer);
166 return TRUE;
169 /* --------------- DiaLinePreview -------------------------------- */
170 typedef struct _DiaLinePreview DiaLinePreview;
171 typedef struct _DiaLinePreviewClass DiaLinePreviewClass;
173 static GtkType dia_line_preview_get_type (void);
174 static void dia_line_preview_set(DiaLinePreview *line, LineStyle lstyle);
175 static GtkWidget *dia_line_preview_new (LineStyle lstyle);
177 #define DIA_LINE_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_line_preview_get_type(), DiaLinePreview))
178 #define DIA_LINE_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_preview_get_type(), DiaLinePreviewClass))
180 struct _DiaLinePreview
182 GtkMisc misc;
183 LineStyle lstyle;
185 struct _DiaLinePreviewClass
187 GtkMiscClass parent_class;
190 static void dia_line_preview_class_init (DiaLinePreviewClass *klass);
191 static void dia_line_preview_init (DiaLinePreview *arrow);
192 static gint dia_line_preview_expose (GtkWidget *widget,
193 GdkEventExpose *event);
195 static GtkType
196 dia_line_preview_get_type (void)
198 static GtkType line_type = 0;
200 if (!line_type) {
201 static const GtkTypeInfo line_info = {
202 "DiaLinePreview",
203 sizeof (DiaLinePreview),
204 sizeof (DiaLinePreviewClass),
205 (GtkClassInitFunc) dia_line_preview_class_init,
206 (GtkObjectInitFunc) dia_line_preview_init,
207 /* reserved_1 */ NULL,
208 /* reserved_2 */ NULL,
209 (GtkClassInitFunc) NULL,
211 line_type = gtk_type_unique (GTK_TYPE_MISC, &line_info);
213 return line_type;
216 static void
217 dia_line_preview_class_init (DiaLinePreviewClass *class)
219 GtkWidgetClass *widget_class;
221 widget_class = (GtkWidgetClass *)class;
222 widget_class->expose_event = dia_line_preview_expose;
225 static void
226 dia_line_preview_init (DiaLinePreview *line)
228 GTK_WIDGET_SET_FLAGS (line, GTK_NO_WINDOW);
230 GTK_WIDGET (line)->requisition.width = 40 + GTK_MISC (line)->xpad * 2;
231 GTK_WIDGET (line)->requisition.height = 15 + GTK_MISC (line)->ypad * 2;
234 line->lstyle = LINESTYLE_SOLID;
237 static GtkWidget *
238 dia_line_preview_new (LineStyle lstyle)
240 DiaLinePreview *line = gtk_type_new (dia_line_preview_get_type());
242 line->lstyle = lstyle;
243 return GTK_WIDGET(line);
246 static void
247 dia_line_preview_set(DiaLinePreview *line, LineStyle lstyle)
249 if (line->lstyle != lstyle) {
250 line->lstyle = lstyle;
251 if (GTK_WIDGET_DRAWABLE(line))
252 gtk_widget_queue_clear(GTK_WIDGET(line));
256 static gint
257 dia_line_preview_expose(GtkWidget *widget, GdkEventExpose *event)
259 DiaLinePreview *line = DIA_LINE_PREVIEW(widget);
260 GtkMisc *misc = GTK_MISC(widget);
261 gint width, height;
262 gint x, y;
263 gint extent;
264 GdkWindow *win;
265 GdkGC *gc;
266 GdkGCValues gcvalues;
267 char dash_list[6];
269 if (GTK_WIDGET_DRAWABLE(widget)) {
270 width = widget->allocation.width - misc->xpad * 2;
271 height = widget->allocation.height - misc->ypad * 2;
272 extent = MIN(width, height);
273 x = (widget->allocation.x + misc->xpad);
274 y = (widget->allocation.y + misc->ypad);
276 win = widget->window;
277 gc = widget->style->fg_gc[widget->state];
279 /* increase line width */
280 gdk_gc_get_values(gc, &gcvalues);
281 switch (line->lstyle) {
282 case LINESTYLE_SOLID:
283 gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID,
284 gcvalues.cap_style, gcvalues.join_style);
285 break;
286 case LINESTYLE_DASHED:
287 gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH,
288 gcvalues.cap_style, gcvalues.join_style);
289 dash_list[0] = 10;
290 dash_list[1] = 10;
291 gdk_gc_set_dashes(gc, 0, dash_list, 2);
292 break;
293 case LINESTYLE_DASH_DOT:
294 gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH,
295 gcvalues.cap_style, gcvalues.join_style);
296 dash_list[0] = 10;
297 dash_list[1] = 4;
298 dash_list[2] = 2;
299 dash_list[3] = 4;
300 gdk_gc_set_dashes(gc, 0, dash_list, 4);
301 break;
302 case LINESTYLE_DASH_DOT_DOT:
303 gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH,
304 gcvalues.cap_style, gcvalues.join_style);
305 dash_list[0] = 10;
306 dash_list[1] = 2;
307 dash_list[2] = 2;
308 dash_list[3] = 2;
309 dash_list[4] = 2;
310 dash_list[5] = 2;
311 gdk_gc_set_dashes(gc, 0, dash_list, 6);
312 break;
313 case LINESTYLE_DOTTED:
314 gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH,
315 gcvalues.cap_style, gcvalues.join_style);
316 dash_list[0] = 2;
317 dash_list[1] = 2;
318 gdk_gc_set_dashes(gc, 0, dash_list, 2);
319 break;
321 gdk_draw_line(win, gc, x, y+height/2, x+width, y+height/2);
322 gdk_gc_set_line_attributes(gc, gcvalues.line_width, gcvalues.line_style,
323 gcvalues.cap_style, gcvalues.join_style);
325 return TRUE;
328 /* ------- Code for DiaArrowChooser ----------------------- */
329 static GtkType dia_arrow_chooser_get_type (void);
331 static gint close_and_hide(GtkWidget *wid, GdkEventAny *event) {
332 gtk_widget_hide(wid);
333 return TRUE;
335 static const char *button_menu_key = "dia-button-menu";
336 static const char *menuitem_enum_key = "dia-menuitem-value";
339 #define DIA_ARROW_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_arrow_chooser_get_type(), DiaArrowChooser))
340 #define DIA_ARROW_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_chooser_get_type(), DiaArrowChooserClass))
342 typedef struct _DiaArrowChooser DiaArrowChooser;
343 typedef struct _DiaArrowChooserClass DiaArrowChooserClass;
345 struct _DiaArrowChooser
347 GtkButton button;
348 DiaArrowPreview *preview;
349 Arrow arrow;
350 gboolean left;
352 DiaChangeArrowCallback callback;
353 gpointer user_data;
355 GtkWidget *dialog;
356 DiaArrowSelector *selector;
358 struct _DiaArrowChooserClass
360 GtkButtonClass parent_class;
363 static void dia_arrow_chooser_class_init (DiaArrowChooserClass *klass);
364 static void dia_arrow_chooser_init (DiaArrowChooser *arrow);
365 static gint dia_arrow_chooser_event (GtkWidget *widget,
366 GdkEvent *event);
367 static void dia_arrow_chooser_dialog_ok (DiaArrowChooser *arrow);
368 static void dia_arrow_chooser_dialog_cancel (DiaArrowChooser *arrow);
369 static void dia_arrow_chooser_dialog_destroy (DiaArrowChooser *arrow);
370 static void dia_arrow_chooser_change_arrow_type (GtkMenuItem *mi,
371 DiaArrowChooser *arrow);
373 static GtkType
374 dia_arrow_chooser_get_type (void)
376 static GtkType arrow_type = 0;
378 if (!arrow_type) {
379 static const GtkTypeInfo arrow_info = {
380 "DiaArrowChooser",
381 sizeof (DiaArrowChooser),
382 sizeof (DiaArrowChooserClass),
383 (GtkClassInitFunc) dia_arrow_chooser_class_init,
384 (GtkObjectInitFunc) dia_arrow_chooser_init,
385 /* reserved_1 */ NULL,
386 /* reserved_2 */ NULL,
387 (GtkClassInitFunc) NULL,
389 arrow_type = gtk_type_unique (GTK_TYPE_BUTTON, &arrow_info);
391 return arrow_type;
394 static void
395 dia_arrow_chooser_class_init (DiaArrowChooserClass *class)
397 GtkWidgetClass *widget_class;
399 widget_class = (GtkWidgetClass *)class;
400 widget_class->event = dia_arrow_chooser_event;
403 static void
404 dia_arrow_chooser_init (DiaArrowChooser *arrow)
406 GtkWidget *wid;
408 arrow->left = FALSE;
409 arrow->arrow.type = ARROW_NONE;
410 arrow->arrow.length = DEFAULT_ARROW_LENGTH;
411 arrow->arrow.width = DEFAULT_ARROW_WIDTH;
413 wid = dia_arrow_preview_new(ARROW_NONE, arrow->left);
414 gtk_container_add(GTK_CONTAINER(arrow), wid);
415 gtk_widget_show(wid);
416 arrow->preview = DIA_ARROW_PREVIEW(wid);
418 arrow->dialog = NULL;
421 /* Creating the dialog separately so we can handle destroy */
422 void
423 dia_arrow_chooser_dialog_new(GtkWidget *widget, gpointer userdata)
425 DiaArrowChooser *chooser = DIA_ARROW_CHOOSER(userdata);
426 if (chooser->dialog == NULL) {
427 GtkWidget *wid;
428 chooser->dialog = wid = gtk_dialog_new();
429 gtk_window_set_title(GTK_WINDOW(wid), _("Arrow Properties"));
430 gtk_signal_connect(GTK_OBJECT(wid), "delete_event",
431 GTK_SIGNAL_FUNC(close_and_hide), NULL);
432 gtk_signal_connect(GTK_OBJECT(wid), "destroy",
433 GTK_SIGNAL_FUNC(gtk_widget_destroyed),
434 &chooser->dialog);
436 wid = dia_arrow_selector_new();
437 gtk_container_set_border_width(GTK_CONTAINER(wid), 5);
438 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(chooser->dialog)->vbox), wid,
439 TRUE, TRUE, 0);
440 gtk_widget_show(wid);
441 chooser->selector = DIAARROWSELECTOR(wid);
442 dia_arrow_selector_set_arrow(chooser->selector, chooser->arrow);
444 wid = gtk_button_new_with_label(_("OK"));
445 GTK_WIDGET_SET_FLAGS(wid, GTK_CAN_DEFAULT);
446 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(chooser->dialog)->action_area),wid);
447 gtk_widget_grab_default(wid);
448 gtk_signal_connect_object(GTK_OBJECT(wid), "clicked",
449 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_ok),
450 GTK_OBJECT(chooser));
451 gtk_widget_show(wid);
453 wid = gtk_button_new_with_label(_("Cancel"));
454 GTK_WIDGET_SET_FLAGS(wid, GTK_CAN_DEFAULT);
455 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(chooser->dialog)->action_area),wid);
456 gtk_signal_connect_object(GTK_OBJECT(wid), "clicked",
457 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_cancel),
458 GTK_OBJECT(chooser));
459 gtk_widget_show(wid);
463 void
464 dia_arrow_chooser_dialog_show(GtkWidget *widget, gpointer userdata)
466 DiaArrowChooser *chooser = DIA_ARROW_CHOOSER(userdata);
467 dia_arrow_chooser_dialog_new(widget, chooser);
468 dia_arrow_selector_set_arrow(chooser->selector, chooser->arrow);
469 gtk_widget_show(chooser->dialog);
472 GtkWidget *
473 dia_arrow_chooser_new(gboolean left, DiaChangeArrowCallback callback,
474 gpointer user_data)
476 DiaArrowChooser *chooser = gtk_type_new(dia_arrow_chooser_get_type());
477 GtkWidget *menu, *mi, *ar;
478 gint i;
480 chooser->left = left;
481 dia_arrow_preview_set(chooser->preview, chooser->preview->atype, left);
482 chooser->callback = callback;
483 chooser->user_data = user_data;
485 dia_arrow_chooser_dialog_new(NULL, chooser);
487 menu = gtk_menu_new();
488 gtk_object_set_data_full(GTK_OBJECT(chooser), button_menu_key, menu,
489 (GtkDestroyNotify)gtk_widget_unref);
490 for (i = 0; arrow_types[i].name != NULL; i++) {
491 mi = gtk_menu_item_new();
492 gtk_object_set_data(GTK_OBJECT(mi), menuitem_enum_key,
493 GINT_TO_POINTER(arrow_types[i].enum_value));
494 gtk_tooltips_set_tip(tool_tips, mi, arrow_types[i].name, NULL);
495 ar = dia_arrow_preview_new(arrow_types[i].enum_value, left);
497 gtk_container_add(GTK_CONTAINER(mi), ar);
498 gtk_widget_show(ar);
499 gtk_signal_connect(GTK_OBJECT(mi), "activate",
500 GTK_SIGNAL_FUNC(dia_arrow_chooser_change_arrow_type),
501 chooser);
502 gtk_container_add(GTK_CONTAINER(menu), mi);
503 gtk_widget_show(mi);
505 mi = gtk_menu_item_new_with_label(_("Details..."));
506 gtk_signal_connect(GTK_OBJECT(mi), "activate",
507 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_show),
508 GTK_OBJECT(chooser));
509 gtk_container_add(GTK_CONTAINER(menu), mi);
510 gtk_widget_show(mi);
512 return GTK_WIDGET(chooser);
515 static gint
516 dia_arrow_chooser_event(GtkWidget *widget, GdkEvent *event)
518 if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) {
519 GtkMenu *menu = gtk_object_get_data(GTK_OBJECT(widget), button_menu_key);
520 gtk_menu_popup(menu, NULL, NULL, NULL, NULL,
521 event->button.button, event->button.time);
522 return TRUE;
524 return FALSE;
527 static void
528 dia_arrow_chooser_dialog_ok (DiaArrowChooser *arrow)
530 Arrow new_arrow = dia_arrow_selector_get_arrow(arrow->selector);
532 if (new_arrow.type != arrow->arrow.type ||
533 new_arrow.length != arrow->arrow.length ||
534 new_arrow.width != arrow->arrow.width) {
535 arrow->arrow = new_arrow;
536 dia_arrow_preview_set(arrow->preview, new_arrow.type, arrow->left);
537 if (arrow->callback)
538 (* arrow->callback)(arrow->arrow, arrow->user_data);
540 gtk_widget_hide(arrow->dialog);
543 static void
544 dia_arrow_chooser_dialog_cancel (DiaArrowChooser *arrow)
546 if (arrow->dialog != NULL)
547 dia_arrow_selector_set_arrow(arrow->selector, arrow->arrow);
548 gtk_widget_hide(arrow->dialog);
551 static void
552 dia_arrow_chooser_dialog_destroy (DiaArrowChooser *chooser)
554 /* dia_arrow_selector_set_arrow(arrow->selector, arrow->arrow);*/
555 chooser->dialog = NULL;
556 chooser->selector = NULL;
559 static void
560 dia_arrow_chooser_change_arrow_type(GtkMenuItem *mi, DiaArrowChooser *arrow)
562 ArrowType atype = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi),
563 menuitem_enum_key));
565 if (arrow->arrow.type != atype) {
566 dia_arrow_preview_set(arrow->preview, atype, arrow->left);
567 arrow->arrow.type = atype;
568 if (arrow->dialog != NULL)
569 dia_arrow_selector_set_arrow(arrow->selector, arrow->arrow);
570 if (arrow->callback)
571 (* arrow->callback)(arrow->arrow, arrow->user_data);
576 /* ------- Code for DiaLineChooser ---------------------- */
577 static GtkType dia_line_chooser_get_type (void);
579 #define DIA_LINE_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_line_chooser_get_type(), DiaLineChooser))
580 #define DIA_LINE_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_chooser_get_type(), DiaLineChooserClass))
582 typedef struct _DiaLineChooser DiaLineChooser;
583 typedef struct _DiaLineChooserClass DiaLineChooserClass;
585 struct _DiaLineChooser
587 GtkButton button;
588 DiaLinePreview *preview;
589 LineStyle lstyle;
590 real dash_length;
592 DiaChangeLineCallback callback;
593 gpointer user_data;
595 GtkWidget *dialog;
596 DiaLineStyleSelector *selector;
598 struct _DiaLineChooserClass
600 GtkButtonClass parent_class;
603 static void dia_line_chooser_class_init (DiaLineChooserClass *klass);
604 static void dia_line_chooser_init (DiaLineChooser *arrow);
605 static gint dia_line_chooser_event (GtkWidget *widget,
606 GdkEvent *event);
607 static void dia_line_chooser_dialog_ok (DiaLineChooser *lchooser);
608 static void dia_line_chooser_dialog_cancel (DiaLineChooser *lchooser);
609 static void dia_line_chooser_change_line_style (GtkMenuItem *mi,
610 DiaLineChooser *lchooser);
612 static GtkType
613 dia_line_chooser_get_type (void)
615 static GtkType arrow_type = 0;
617 if (!arrow_type) {
618 static const GtkTypeInfo arrow_info = {
619 "DiaLineChooser",
620 sizeof (DiaLineChooser),
621 sizeof (DiaLineChooserClass),
622 (GtkClassInitFunc) dia_line_chooser_class_init,
623 (GtkObjectInitFunc) dia_line_chooser_init,
624 /* reserved_1 */ NULL,
625 /* reserved_2 */ NULL,
626 (GtkClassInitFunc) NULL,
628 arrow_type = gtk_type_unique (GTK_TYPE_BUTTON, &arrow_info);
630 return arrow_type;
633 static void
634 dia_line_chooser_class_init (DiaLineChooserClass *class)
636 GtkWidgetClass *widget_class;
638 widget_class = (GtkWidgetClass *)class;
639 widget_class->event = dia_line_chooser_event;
642 static void
643 dia_line_chooser_init (DiaLineChooser *lchooser)
645 GtkWidget *wid;
646 GtkWidget *menu, *mi, *ln;
647 gint i;
649 lchooser->lstyle = LINESTYLE_SOLID;
650 lchooser->dash_length = DEFAULT_LINESTYLE_DASHLEN;
652 wid = dia_line_preview_new(LINESTYLE_SOLID);
653 gtk_container_add(GTK_CONTAINER(lchooser), wid);
654 gtk_widget_show(wid);
655 lchooser->preview = DIA_LINE_PREVIEW(wid);
657 lchooser->dialog = wid = gtk_dialog_new();
658 gtk_window_set_title(GTK_WINDOW(wid), _("Line Style Properties"));
659 gtk_signal_connect(GTK_OBJECT(wid), "delete_event",
660 GTK_SIGNAL_FUNC(close_and_hide), NULL);
662 wid = dia_line_style_selector_new();
663 gtk_container_set_border_width(GTK_CONTAINER(wid), 5);
664 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lchooser->dialog)->vbox), wid,
665 TRUE, TRUE, 0);
666 gtk_widget_show(wid);
667 lchooser->selector = DIALINESTYLESELECTOR(wid);
669 wid = gtk_button_new_with_label(_("OK"));
670 GTK_WIDGET_SET_FLAGS(wid, GTK_CAN_DEFAULT);
671 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser->dialog)->action_area),
672 wid);
673 gtk_widget_grab_default(wid);
674 gtk_signal_connect_object(GTK_OBJECT(wid), "clicked",
675 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_ok),
676 GTK_OBJECT(lchooser));
677 gtk_widget_show(wid);
679 wid = gtk_button_new_with_label(_("Cancel"));
680 GTK_WIDGET_SET_FLAGS(wid, GTK_CAN_DEFAULT);
681 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser->dialog)->action_area),
682 wid);
683 gtk_signal_connect_object(GTK_OBJECT(wid), "clicked",
684 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_cancel),
685 GTK_OBJECT(lchooser));
687 menu = gtk_menu_new();
688 gtk_object_set_data_full(GTK_OBJECT(lchooser), button_menu_key, menu,
689 (GtkDestroyNotify)gtk_widget_unref);
690 for (i = 0; i <= LINESTYLE_DOTTED; i++) {
691 mi = gtk_menu_item_new();
692 gtk_object_set_data(GTK_OBJECT(mi), menuitem_enum_key, GINT_TO_POINTER(i));
693 ln = dia_line_preview_new(i);
694 gtk_container_add(GTK_CONTAINER(mi), ln);
695 gtk_widget_show(ln);
696 gtk_signal_connect(GTK_OBJECT(mi), "activate",
697 GTK_SIGNAL_FUNC(dia_line_chooser_change_line_style),
698 lchooser);
699 gtk_container_add(GTK_CONTAINER(menu), mi);
700 gtk_widget_show(mi);
702 mi = gtk_menu_item_new_with_label(_("Details..."));
703 gtk_signal_connect_object(GTK_OBJECT(mi), "activate",
704 GTK_SIGNAL_FUNC(gtk_widget_show),
705 GTK_OBJECT(lchooser->dialog));
706 gtk_container_add(GTK_CONTAINER(menu), mi);
707 gtk_widget_show(mi);
709 gtk_widget_show(wid);
712 GtkWidget *
713 dia_line_chooser_new(DiaChangeLineCallback callback,
714 gpointer user_data)
716 DiaLineChooser *chooser = gtk_type_new(dia_line_chooser_get_type());
718 chooser->callback = callback;
719 chooser->user_data = user_data;
721 return GTK_WIDGET(chooser);
724 static gint
725 dia_line_chooser_event(GtkWidget *widget, GdkEvent *event)
727 if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) {
728 GtkMenu *menu = gtk_object_get_data(GTK_OBJECT(widget), button_menu_key);
729 gtk_menu_popup(menu, NULL, NULL, NULL, NULL,
730 event->button.button, event->button.time);
731 return TRUE;
733 return FALSE;
736 static void
737 dia_line_chooser_dialog_ok (DiaLineChooser *lchooser)
739 LineStyle new_style;
740 real new_dash;
742 dia_line_style_selector_get_linestyle(lchooser->selector,
743 &new_style, &new_dash);
744 if (new_style != lchooser->lstyle || new_dash != lchooser->dash_length) {
745 lchooser->lstyle = new_style;
746 lchooser->dash_length = new_dash;
747 dia_line_preview_set(lchooser->preview, new_style);
748 if (lchooser->callback)
749 (* lchooser->callback)(new_style, new_dash, lchooser->user_data);
751 gtk_widget_hide(lchooser->dialog);
753 static void
754 dia_line_chooser_dialog_cancel (DiaLineChooser *lchooser)
756 dia_line_style_selector_set_linestyle(lchooser->selector, lchooser->lstyle,
757 lchooser->dash_length);
758 gtk_widget_hide(lchooser->dialog);
761 static void
762 dia_line_chooser_change_line_style(GtkMenuItem *mi, DiaLineChooser *lchooser)
764 LineStyle lstyle = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi),
765 menuitem_enum_key));
767 if (lchooser->lstyle != lstyle) {
768 dia_line_preview_set(lchooser->preview, lstyle);
769 lchooser->lstyle = lstyle;
770 dia_line_style_selector_set_linestyle(lchooser->selector, lchooser->lstyle,
771 lchooser->dash_length);
772 if (lchooser->callback)
773 (* lchooser->callback)(lchooser->lstyle, lchooser->dash_length,
774 lchooser->user_data);