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.
27 #include "lineprops_area.h"
31 /* --------------- DiaArrowPreview -------------------------------- */
33 #define DIA_ARROW_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_arrow_preview_get_type(), DiaArrowPreview))
34 #define DIA_ARROW_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_preview_get_type(), DiaArrowPreviewClass))
36 typedef struct _DiaArrowPreview DiaArrowPreview
;
37 typedef struct _DiaArrowPreviewClass DiaArrowPreviewClass
;
39 struct _DiaArrowPreview
45 struct _DiaArrowPreviewClass
47 GtkMiscClass parent_class
;
50 static void dia_arrow_preview_class_init (DiaArrowPreviewClass
*klass
);
51 static void dia_arrow_preview_init (DiaArrowPreview
*arrow
);
52 static gint
dia_arrow_preview_expose (GtkWidget
*widget
,
53 GdkEventExpose
*event
);
56 dia_arrow_preview_get_type (void)
58 static GtkType arrow_type
= 0;
61 static const GtkTypeInfo arrow_info
= {
63 sizeof (DiaArrowPreview
),
64 sizeof (DiaArrowPreviewClass
),
65 (GtkClassInitFunc
) dia_arrow_preview_class_init
,
66 (GtkObjectInitFunc
) dia_arrow_preview_init
,
67 /* reserved_1 */ NULL
,
68 /* reserved_2 */ NULL
,
69 (GtkClassInitFunc
) NULL
,
71 arrow_type
= gtk_type_unique (GTK_TYPE_MISC
, &arrow_info
);
77 dia_arrow_preview_class_init (DiaArrowPreviewClass
*class)
79 GtkWidgetClass
*widget_class
;
81 widget_class
= (GtkWidgetClass
*)class;
82 widget_class
->expose_event
= dia_arrow_preview_expose
;
86 dia_arrow_preview_init (DiaArrowPreview
*arrow
)
88 GTK_WIDGET_SET_FLAGS (arrow
, GTK_NO_WINDOW
);
90 GTK_WIDGET (arrow
)->requisition
.width
= 30 + GTK_MISC (arrow
)->xpad
* 2;
91 GTK_WIDGET (arrow
)->requisition
.height
= 20 + GTK_MISC (arrow
)->ypad
* 2;
93 arrow
->atype
= ARROW_NONE
;
98 dia_arrow_preview_new (ArrowType atype
, gboolean left
)
100 DiaArrowPreview
*arrow
= gtk_type_new (dia_arrow_preview_get_type());
102 arrow
->atype
= atype
;
104 return GTK_WIDGET(arrow
);
108 dia_arrow_preview_set(DiaArrowPreview
*arrow
, ArrowType atype
, gboolean left
)
110 if (arrow
->atype
!= atype
|| arrow
->left
!= left
) {
111 arrow
->atype
= atype
;
113 if (GTK_WIDGET_DRAWABLE(arrow
))
114 gtk_widget_queue_clear(GTK_WIDGET(arrow
));
119 dia_arrow_preview_expose(GtkWidget
*widget
, GdkEventExpose
*event
)
121 DiaArrowPreview
*arrow
= DIA_ARROW_PREVIEW(widget
);
122 GtkMisc
*misc
= GTK_MISC(widget
);
128 GdkGCValues gcvalues
;
131 if (GTK_WIDGET_DRAWABLE(widget
)) {
132 width
= widget
->allocation
.width
- misc
->xpad
* 2;
133 height
= widget
->allocation
.height
- misc
->ypad
* 2;
134 extent
= MIN(width
, height
);
135 x
= (widget
->allocation
.x
+ misc
->xpad
);
136 y
= (widget
->allocation
.y
+ misc
->ypad
);
138 win
= widget
->window
;
139 gc
= widget
->style
->fg_gc
[widget
->state
];
141 /* increase line width */
142 gdk_gc_get_values(gc
, &gcvalues
);
143 gdk_gc_set_line_attributes(gc
, 3, gcvalues
.line_style
,
144 gcvalues
.cap_style
, gcvalues
.join_style
);
145 switch (arrow
->atype
) {
148 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
150 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
154 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
155 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+5);
156 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+height
-5);
158 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
159 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,y
+5);
160 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,y
+height
-5);
163 case ARROW_HOLLOW_TRIANGLE
:
165 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
166 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
167 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
168 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
169 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
170 gdk_draw_line(win
, gc
, x
+5+height
/2, y
+height
/2, x
+width
, y
+height
/2);
172 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
173 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
174 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
175 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
176 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
177 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
/2, y
+height
/2);
180 case ARROW_FILLED_TRIANGLE
:
182 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
183 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
184 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
185 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
186 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
187 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
188 gdk_draw_line(win
, gc
, x
+5+height
/2, y
+height
/2, x
+width
, y
+height
/2);
190 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
191 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
192 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
193 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
194 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
195 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
196 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
/2, y
+height
/2);
199 case ARROW_HOLLOW_DIAMOND
:
201 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
202 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
203 pts
[2].x
= x
+5+height
*3/4; pts
[2].y
= y
+height
/2;
204 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
-5;
205 pts
[4].x
= x
+5; pts
[4].y
= y
+height
/2;
206 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
207 gdk_draw_line(win
, gc
, x
+5+height
*3/4,y
+height
/2, x
+width
, y
+height
/2);
209 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
210 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
211 pts
[2].x
= x
+width
-5-height
*3/4; pts
[2].y
= y
+height
/2;
212 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
-5;
213 pts
[4].x
= x
+width
-5; pts
[4].y
= y
+height
/2;
214 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
215 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
*3/4,y
+height
/2);
218 case ARROW_FILLED_DIAMOND
:
220 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
221 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
222 pts
[2].x
= x
+5+height
*3/4; pts
[2].y
= y
+height
/2;
223 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
-5;
224 pts
[4].x
= x
+5; pts
[4].y
= y
+height
/2;
225 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 5);
226 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
227 gdk_draw_line(win
, gc
, x
+5+height
*3/4,y
+height
/2, x
+width
, y
+height
/2);
229 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
230 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
231 pts
[2].x
= x
+width
-5-height
*3/4; pts
[2].y
= y
+height
/2;
232 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
-5;
233 pts
[4].x
= x
+width
-5; pts
[4].y
= y
+height
/2;
234 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 5);
235 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
236 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
*3/4,y
+height
/2);
239 case ARROW_SLASHED_CROSS
:
241 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2); /*line*/
242 gdk_draw_line(win
, gc
, x
+5,y
+height
-5, x
+height
-5,y
+5); /*slash*/
243 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
-5, x
+height
/2,y
+5);
246 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2); /*line*/
247 gdk_draw_line(win
, gc
, x
+width
-height
/2-5,y
+height
-5, x
+width
-5,y
+5);
249 gdk_draw_line(win
, gc
, x
+width
-height
/2,y
+height
-5, x
+width
-height
/2,
253 case ARROW_HALF_HEAD
:
255 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
256 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+5);
258 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
259 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,
263 case ARROW_FILLED_ELLIPSE
:
265 gdk_draw_line(win
,gc
,x
+5+8,y
+height
/2,x
+width
,y
+height
/2);
266 gdk_draw_arc(win
,gc
,TRUE
,x
+5,y
+height
/2-6,12,12,0,64*360);
268 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-8,y
+height
/2);
269 gdk_draw_arc(win
,gc
,TRUE
,x
+width
-5-12,y
+height
/2-6,12,12,0,64*360);
272 case ARROW_HOLLOW_ELLIPSE
:
274 gdk_draw_line(win
,gc
,x
+5+8,y
+height
/2,x
+width
,y
+height
/2);
275 gdk_draw_arc(win
,gc
,FALSE
,x
+5,y
+height
/2-4,8,8,0,64*360);
277 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-8,y
+height
/2);
278 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-5-8,y
+height
/2-4,8,8,0,64*360);
282 gdk_gc_set_line_attributes(gc
, gcvalues
.line_width
, gcvalues
.line_style
,
283 gcvalues
.cap_style
, gcvalues
.join_style
);
289 /* --------------- DiaLinePreview -------------------------------- */
291 #define DIA_LINE_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_line_preview_get_type(), DiaLinePreview))
292 #define DIA_LINE_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_preview_get_type(), DiaLinePreviewClass))
294 typedef struct _DiaLinePreview DiaLinePreview
;
295 typedef struct _DiaLinePreviewClass DiaLinePreviewClass
;
297 struct _DiaLinePreview
302 struct _DiaLinePreviewClass
304 GtkMiscClass parent_class
;
307 static void dia_line_preview_class_init (DiaLinePreviewClass
*klass
);
308 static void dia_line_preview_init (DiaLinePreview
*arrow
);
309 static gint
dia_line_preview_expose (GtkWidget
*widget
,
310 GdkEventExpose
*event
);
313 dia_line_preview_get_type (void)
315 static GtkType line_type
= 0;
318 static const GtkTypeInfo line_info
= {
320 sizeof (DiaLinePreview
),
321 sizeof (DiaLinePreviewClass
),
322 (GtkClassInitFunc
) dia_line_preview_class_init
,
323 (GtkObjectInitFunc
) dia_line_preview_init
,
324 /* reserved_1 */ NULL
,
325 /* reserved_2 */ NULL
,
326 (GtkClassInitFunc
) NULL
,
328 line_type
= gtk_type_unique (GTK_TYPE_MISC
, &line_info
);
334 dia_line_preview_class_init (DiaLinePreviewClass
*class)
336 GtkWidgetClass
*widget_class
;
338 widget_class
= (GtkWidgetClass
*)class;
339 widget_class
->expose_event
= dia_line_preview_expose
;
343 dia_line_preview_init (DiaLinePreview
*line
)
345 GTK_WIDGET_SET_FLAGS (line
, GTK_NO_WINDOW
);
347 GTK_WIDGET (line
)->requisition
.width
= 40 + GTK_MISC (line
)->xpad
* 2;
348 GTK_WIDGET (line
)->requisition
.height
= 20 + GTK_MISC (line
)->ypad
* 2;
351 line
->lstyle
= LINESTYLE_SOLID
;
355 dia_line_preview_new (LineStyle lstyle
)
357 DiaLinePreview
*line
= gtk_type_new (dia_line_preview_get_type());
359 line
->lstyle
= lstyle
;
360 return GTK_WIDGET(line
);
364 dia_line_preview_set(DiaLinePreview
*line
, LineStyle lstyle
)
366 if (line
->lstyle
!= lstyle
) {
367 line
->lstyle
= lstyle
;
368 if (GTK_WIDGET_DRAWABLE(line
))
369 gtk_widget_queue_clear(GTK_WIDGET(line
));
374 dia_line_preview_expose(GtkWidget
*widget
, GdkEventExpose
*event
)
376 DiaLinePreview
*line
= DIA_LINE_PREVIEW(widget
);
377 GtkMisc
*misc
= GTK_MISC(widget
);
383 GdkGCValues gcvalues
;
386 if (GTK_WIDGET_DRAWABLE(widget
)) {
387 width
= widget
->allocation
.width
- misc
->xpad
* 2;
388 height
= widget
->allocation
.height
- misc
->ypad
* 2;
389 extent
= MIN(width
, height
);
390 x
= (widget
->allocation
.x
+ misc
->xpad
);
391 y
= (widget
->allocation
.y
+ misc
->ypad
);
393 win
= widget
->window
;
394 gc
= widget
->style
->fg_gc
[widget
->state
];
396 /* increase line width */
397 gdk_gc_get_values(gc
, &gcvalues
);
398 switch (line
->lstyle
) {
399 case LINESTYLE_SOLID
:
400 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_SOLID
,
401 gcvalues
.cap_style
, gcvalues
.join_style
);
403 case LINESTYLE_DASHED
:
404 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
405 gcvalues
.cap_style
, gcvalues
.join_style
);
408 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
410 case LINESTYLE_DASH_DOT
:
411 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
412 gcvalues
.cap_style
, gcvalues
.join_style
);
417 gdk_gc_set_dashes(gc
, 0, dash_list
, 4);
419 case LINESTYLE_DASH_DOT_DOT
:
420 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
421 gcvalues
.cap_style
, gcvalues
.join_style
);
428 gdk_gc_set_dashes(gc
, 0, dash_list
, 6);
430 case LINESTYLE_DOTTED
:
431 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
432 gcvalues
.cap_style
, gcvalues
.join_style
);
435 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
438 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
, y
+height
/2);
439 gdk_gc_set_line_attributes(gc
, gcvalues
.line_width
, gcvalues
.line_style
,
440 gcvalues
.cap_style
, gcvalues
.join_style
);
445 /* ------- Code for DiaArrowChooser ----------------------- */
446 gint
close_and_hide(GtkWidget
*wid
, GdkEventAny
*event
) {
447 gtk_widget_hide(wid
);
450 static const char *button_menu_key
= "dia-button-menu";
451 static const char *menuitem_enum_key
= "dia-menuitem-value";
454 #define DIA_ARROW_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_arrow_chooser_get_type(), DiaArrowChooser))
455 #define DIA_ARROW_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_chooser_get_type(), DiaArrowChooserClass))
457 typedef struct _DiaArrowChooser DiaArrowChooser
;
458 typedef struct _DiaArrowChooserClass DiaArrowChooserClass
;
460 struct _DiaArrowChooser
463 DiaArrowPreview
*preview
;
467 DiaChangeArrowCallback callback
;
471 DiaArrowSelector
*selector
;
473 struct _DiaArrowChooserClass
475 GtkButtonClass parent_class
;
478 static void dia_arrow_chooser_class_init (DiaArrowChooserClass
*klass
);
479 static void dia_arrow_chooser_init (DiaArrowChooser
*arrow
);
480 static gint
dia_arrow_chooser_event (GtkWidget
*widget
,
482 static void dia_arrow_chooser_dialog_ok (DiaArrowChooser
*arrow
);
483 static void dia_arrow_chooser_dialog_cancel (DiaArrowChooser
*arrow
);
484 static void dia_arrow_chooser_change_arrow_type (GtkMenuItem
*mi
,
485 DiaArrowChooser
*arrow
);
488 dia_arrow_chooser_get_type (void)
490 static GtkType arrow_type
= 0;
493 static const GtkTypeInfo arrow_info
= {
495 sizeof (DiaArrowChooser
),
496 sizeof (DiaArrowChooserClass
),
497 (GtkClassInitFunc
) dia_arrow_chooser_class_init
,
498 (GtkObjectInitFunc
) dia_arrow_chooser_init
,
499 /* reserved_1 */ NULL
,
500 /* reserved_2 */ NULL
,
501 (GtkClassInitFunc
) NULL
,
503 arrow_type
= gtk_type_unique (GTK_TYPE_BUTTON
, &arrow_info
);
509 dia_arrow_chooser_class_init (DiaArrowChooserClass
*class)
511 GtkWidgetClass
*widget_class
;
513 widget_class
= (GtkWidgetClass
*)class;
514 widget_class
->event
= dia_arrow_chooser_event
;
518 dia_arrow_chooser_init (DiaArrowChooser
*arrow
)
523 arrow
->arrow
.type
= ARROW_NONE
;
524 arrow
->arrow
.length
= DEFAULT_ARROW_LENGTH
;
525 arrow
->arrow
.width
= DEFAULT_ARROW_WIDTH
;
527 wid
= dia_arrow_preview_new(ARROW_NONE
, arrow
->left
);
528 gtk_container_add(GTK_CONTAINER(arrow
), wid
);
529 gtk_widget_show(wid
);
530 arrow
->preview
= DIA_ARROW_PREVIEW(wid
);
532 arrow
->dialog
= wid
= gtk_dialog_new();
533 gtk_window_set_title(GTK_WINDOW(wid
), _("Arrow Properties"));
534 gtk_signal_connect(GTK_OBJECT(wid
), "delete_event",
535 GTK_SIGNAL_FUNC(close_and_hide
), NULL
);
537 wid
= dia_arrow_selector_new();
538 gtk_container_set_border_width(GTK_CONTAINER(wid
), 5);
539 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(arrow
->dialog
)->vbox
), wid
,
541 gtk_widget_show(wid
);
542 arrow
->selector
= DIAARROWSELECTOR(wid
);
544 wid
= gtk_button_new_with_label(_("OK"));
545 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
546 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(arrow
->dialog
)->action_area
),wid
);
547 gtk_widget_grab_default(wid
);
548 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
549 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_ok
),
551 gtk_widget_show(wid
);
553 wid
= gtk_button_new_with_label(_("Cancel"));
554 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
555 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(arrow
->dialog
)->action_area
),wid
);
556 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
557 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_cancel
),
559 gtk_widget_show(wid
);
563 dia_arrow_chooser_new(gboolean left
, DiaChangeArrowCallback callback
,
566 DiaArrowChooser
*chooser
= gtk_type_new(dia_arrow_chooser_get_type());
567 GtkWidget
*menu
, *mi
, *ar
;
570 chooser
->left
= left
;
571 dia_arrow_preview_set(chooser
->preview
, chooser
->preview
->atype
, left
);
572 chooser
->callback
= callback
;
573 chooser
->user_data
= user_data
;
575 menu
= gtk_menu_new();
576 gtk_object_set_data_full(GTK_OBJECT(chooser
), button_menu_key
, menu
,
577 (GtkDestroyNotify
)gtk_widget_unref
);
578 for (i
= 0; i
<= ARROW_HOLLOW_ELLIPSE
; i
++) {
579 mi
= gtk_menu_item_new();
580 gtk_object_set_data(GTK_OBJECT(mi
), menuitem_enum_key
, GINT_TO_POINTER(i
));
581 ar
= dia_arrow_preview_new(i
, left
);
582 gtk_container_add(GTK_CONTAINER(mi
), ar
);
584 gtk_signal_connect(GTK_OBJECT(mi
), "activate",
585 GTK_SIGNAL_FUNC(dia_arrow_chooser_change_arrow_type
),
587 gtk_container_add(GTK_CONTAINER(menu
), mi
);
590 mi
= gtk_menu_item_new_with_label(_("Details..."));
591 gtk_signal_connect_object(GTK_OBJECT(mi
), "activate",
592 GTK_SIGNAL_FUNC(gtk_widget_show
),
593 GTK_OBJECT(chooser
->dialog
));
594 gtk_container_add(GTK_CONTAINER(menu
), mi
);
597 return GTK_WIDGET(chooser
);
601 dia_arrow_chooser_event(GtkWidget
*widget
, GdkEvent
*event
)
603 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
.button
== 1) {
604 GtkMenu
*menu
= gtk_object_get_data(GTK_OBJECT(widget
), button_menu_key
);
605 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
,
606 event
->button
.button
, event
->button
.time
);
613 dia_arrow_chooser_dialog_ok (DiaArrowChooser
*arrow
)
615 Arrow new_arrow
= dia_arrow_selector_get_arrow(arrow
->selector
);
617 if (new_arrow
.type
!= arrow
->arrow
.type
||
618 new_arrow
.length
!= arrow
->arrow
.length
||
619 new_arrow
.width
!= arrow
->arrow
.width
) {
620 arrow
->arrow
= new_arrow
;
621 dia_arrow_preview_set(arrow
->preview
, new_arrow
.type
, arrow
->left
);
623 (* arrow
->callback
)(arrow
->arrow
, arrow
->user_data
);
625 gtk_widget_hide(arrow
->dialog
);
628 dia_arrow_chooser_dialog_cancel (DiaArrowChooser
*arrow
)
630 dia_arrow_selector_set_arrow(arrow
->selector
, arrow
->arrow
);
631 gtk_widget_hide(arrow
->dialog
);
635 dia_arrow_chooser_change_arrow_type(GtkMenuItem
*mi
, DiaArrowChooser
*arrow
)
637 ArrowType atype
= GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi
),
640 if (arrow
->arrow
.type
!= atype
) {
641 dia_arrow_preview_set(arrow
->preview
, atype
, arrow
->left
);
642 arrow
->arrow
.type
= atype
;
643 dia_arrow_selector_set_arrow(arrow
->selector
, arrow
->arrow
);
645 (* arrow
->callback
)(arrow
->arrow
, arrow
->user_data
);
650 /* ------- Code for DiaLineChooser ---------------------- */
651 #define DIA_LINE_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_line_chooser_get_type(), DiaLineChooser))
652 #define DIA_LINE_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_chooser_get_type(), DiaLineChooserClass))
654 typedef struct _DiaLineChooser DiaLineChooser
;
655 typedef struct _DiaLineChooserClass DiaLineChooserClass
;
657 struct _DiaLineChooser
660 DiaLinePreview
*preview
;
664 DiaChangeLineCallback callback
;
668 DiaLineStyleSelector
*selector
;
670 struct _DiaLineChooserClass
672 GtkButtonClass parent_class
;
675 static void dia_line_chooser_class_init (DiaLineChooserClass
*klass
);
676 static void dia_line_chooser_init (DiaLineChooser
*arrow
);
677 static gint
dia_line_chooser_event (GtkWidget
*widget
,
679 static void dia_line_chooser_dialog_ok (DiaLineChooser
*lchooser
);
680 static void dia_line_chooser_dialog_cancel (DiaLineChooser
*lchooser
);
681 static void dia_line_chooser_change_line_style (GtkMenuItem
*mi
,
682 DiaLineChooser
*lchooser
);
685 dia_line_chooser_get_type (void)
687 static GtkType arrow_type
= 0;
690 static const GtkTypeInfo arrow_info
= {
692 sizeof (DiaLineChooser
),
693 sizeof (DiaLineChooserClass
),
694 (GtkClassInitFunc
) dia_line_chooser_class_init
,
695 (GtkObjectInitFunc
) dia_line_chooser_init
,
696 /* reserved_1 */ NULL
,
697 /* reserved_2 */ NULL
,
698 (GtkClassInitFunc
) NULL
,
700 arrow_type
= gtk_type_unique (GTK_TYPE_BUTTON
, &arrow_info
);
706 dia_line_chooser_class_init (DiaLineChooserClass
*class)
708 GtkWidgetClass
*widget_class
;
710 widget_class
= (GtkWidgetClass
*)class;
711 widget_class
->event
= dia_line_chooser_event
;
715 dia_line_chooser_init (DiaLineChooser
*lchooser
)
718 GtkWidget
*menu
, *mi
, *ln
;
721 lchooser
->lstyle
= LINESTYLE_SOLID
;
722 lchooser
->dash_length
= DEFAULT_LINESTYLE_DASHLEN
;
724 wid
= dia_line_preview_new(LINESTYLE_SOLID
);
725 gtk_container_add(GTK_CONTAINER(lchooser
), wid
);
726 gtk_widget_show(wid
);
727 lchooser
->preview
= DIA_LINE_PREVIEW(wid
);
729 lchooser
->dialog
= wid
= gtk_dialog_new();
730 gtk_window_set_title(GTK_WINDOW(wid
), _("Line Style Properties"));
731 gtk_signal_connect(GTK_OBJECT(wid
), "delete_event",
732 GTK_SIGNAL_FUNC(close_and_hide
), NULL
);
734 wid
= dia_line_style_selector_new();
735 gtk_container_set_border_width(GTK_CONTAINER(wid
), 5);
736 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lchooser
->dialog
)->vbox
), wid
,
738 gtk_widget_show(wid
);
739 lchooser
->selector
= DIALINESTYLESELECTOR(wid
);
741 wid
= gtk_button_new_with_label(_("OK"));
742 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
743 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser
->dialog
)->action_area
),
745 gtk_widget_grab_default(wid
);
746 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
747 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_ok
),
748 GTK_OBJECT(lchooser
));
749 gtk_widget_show(wid
);
751 wid
= gtk_button_new_with_label(_("Cancel"));
752 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
753 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser
->dialog
)->action_area
),
755 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
756 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_cancel
),
757 GTK_OBJECT(lchooser
));
759 menu
= gtk_menu_new();
760 gtk_object_set_data_full(GTK_OBJECT(lchooser
), button_menu_key
, menu
,
761 (GtkDestroyNotify
)gtk_widget_unref
);
762 for (i
= 0; i
<= LINESTYLE_DOTTED
; i
++) {
763 mi
= gtk_menu_item_new();
764 gtk_object_set_data(GTK_OBJECT(mi
), menuitem_enum_key
, GINT_TO_POINTER(i
));
765 ln
= dia_line_preview_new(i
);
766 gtk_container_add(GTK_CONTAINER(mi
), ln
);
768 gtk_signal_connect(GTK_OBJECT(mi
), "activate",
769 GTK_SIGNAL_FUNC(dia_line_chooser_change_line_style
),
771 gtk_container_add(GTK_CONTAINER(menu
), mi
);
774 mi
= gtk_menu_item_new_with_label(_("Details..."));
775 gtk_signal_connect_object(GTK_OBJECT(mi
), "activate",
776 GTK_SIGNAL_FUNC(gtk_widget_show
),
777 GTK_OBJECT(lchooser
->dialog
));
778 gtk_container_add(GTK_CONTAINER(menu
), mi
);
781 gtk_widget_show(wid
);
785 dia_line_chooser_new(DiaChangeLineCallback callback
,
788 DiaLineChooser
*chooser
= gtk_type_new(dia_line_chooser_get_type());
790 chooser
->callback
= callback
;
791 chooser
->user_data
= user_data
;
793 return GTK_WIDGET(chooser
);
797 dia_line_chooser_event(GtkWidget
*widget
, GdkEvent
*event
)
799 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
.button
== 1) {
800 GtkMenu
*menu
= gtk_object_get_data(GTK_OBJECT(widget
), button_menu_key
);
801 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
,
802 event
->button
.button
, event
->button
.time
);
809 dia_line_chooser_dialog_ok (DiaLineChooser
*lchooser
)
814 dia_line_style_selector_get_linestyle(lchooser
->selector
,
815 &new_style
, &new_dash
);
816 if (new_style
!= lchooser
->lstyle
|| new_dash
!= lchooser
->dash_length
) {
817 lchooser
->lstyle
= new_style
;
818 lchooser
->dash_length
= new_dash
;
819 dia_line_preview_set(lchooser
->preview
, new_style
);
820 if (lchooser
->callback
)
821 (* lchooser
->callback
)(new_style
, new_dash
, lchooser
->user_data
);
823 gtk_widget_hide(lchooser
->dialog
);
826 dia_line_chooser_dialog_cancel (DiaLineChooser
*lchooser
)
828 dia_line_style_selector_set_linestyle(lchooser
->selector
, lchooser
->lstyle
,
829 lchooser
->dash_length
);
830 gtk_widget_hide(lchooser
->dialog
);
834 dia_line_chooser_change_line_style(GtkMenuItem
*mi
, DiaLineChooser
*lchooser
)
836 LineStyle lstyle
= GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi
),
839 if (lchooser
->lstyle
!= lstyle
) {
840 dia_line_preview_set(lchooser
->preview
, lstyle
);
841 lchooser
->lstyle
= lstyle
;
842 dia_line_style_selector_set_linestyle(lchooser
->selector
, lchooser
->lstyle
,
843 lchooser
->dash_length
);
844 if (lchooser
->callback
)
845 (* lchooser
->callback
)(lchooser
->lstyle
, lchooser
->dash_length
,
846 lchooser
->user_data
);