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 typedef struct _DiaArrowPreview DiaArrowPreview
;
34 typedef struct _DiaArrowPreviewClass DiaArrowPreviewClass
;
36 static GtkType
dia_arrow_preview_get_type (void);
37 static GtkWidget
*dia_arrow_preview_new (ArrowType atype
, gboolean left
);
38 static void dia_arrow_preview_set(DiaArrowPreview
*arrow
,
39 ArrowType atype
, gboolean left
);
41 #define DIA_ARROW_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_arrow_preview_get_type(), DiaArrowPreview))
42 #define DIA_ARROW_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_preview_get_type(), DiaArrowPreviewClass))
44 struct _DiaArrowPreview
50 struct _DiaArrowPreviewClass
52 GtkMiscClass parent_class
;
55 static void dia_arrow_preview_class_init (DiaArrowPreviewClass
*klass
);
56 static void dia_arrow_preview_init (DiaArrowPreview
*arrow
);
57 static gint
dia_arrow_preview_expose (GtkWidget
*widget
,
58 GdkEventExpose
*event
);
61 dia_arrow_preview_get_type (void)
63 static GtkType arrow_type
= 0;
66 static const GtkTypeInfo arrow_info
= {
68 sizeof (DiaArrowPreview
),
69 sizeof (DiaArrowPreviewClass
),
70 (GtkClassInitFunc
) dia_arrow_preview_class_init
,
71 (GtkObjectInitFunc
) dia_arrow_preview_init
,
72 /* reserved_1 */ NULL
,
73 /* reserved_2 */ NULL
,
74 (GtkClassInitFunc
) NULL
,
76 arrow_type
= gtk_type_unique (GTK_TYPE_MISC
, &arrow_info
);
82 dia_arrow_preview_class_init (DiaArrowPreviewClass
*class)
84 GtkWidgetClass
*widget_class
;
86 widget_class
= (GtkWidgetClass
*)class;
87 widget_class
->expose_event
= dia_arrow_preview_expose
;
91 dia_arrow_preview_init (DiaArrowPreview
*arrow
)
93 GTK_WIDGET_SET_FLAGS (arrow
, GTK_NO_WINDOW
);
95 GTK_WIDGET (arrow
)->requisition
.width
= 30 + GTK_MISC (arrow
)->xpad
* 2;
96 GTK_WIDGET (arrow
)->requisition
.height
= 20 + GTK_MISC (arrow
)->ypad
* 2;
98 arrow
->atype
= ARROW_NONE
;
103 dia_arrow_preview_new (ArrowType atype
, gboolean left
)
105 DiaArrowPreview
*arrow
= gtk_type_new (dia_arrow_preview_get_type());
107 arrow
->atype
= atype
;
109 return GTK_WIDGET(arrow
);
113 dia_arrow_preview_set(DiaArrowPreview
*arrow
, ArrowType atype
, gboolean left
)
115 if (arrow
->atype
!= atype
|| arrow
->left
!= left
) {
116 arrow
->atype
= atype
;
118 if (GTK_WIDGET_DRAWABLE(arrow
))
119 gtk_widget_queue_clear(GTK_WIDGET(arrow
));
124 dia_arrow_preview_expose(GtkWidget
*widget
, GdkEventExpose
*event
)
126 DiaArrowPreview
*arrow
= DIA_ARROW_PREVIEW(widget
);
127 GtkMisc
*misc
= GTK_MISC(widget
);
133 GdkGCValues gcvalues
;
136 if (GTK_WIDGET_DRAWABLE(widget
)) {
137 width
= widget
->allocation
.width
- misc
->xpad
* 2;
138 height
= widget
->allocation
.height
- misc
->ypad
* 2;
139 extent
= MIN(width
, height
);
140 x
= (widget
->allocation
.x
+ misc
->xpad
);
141 y
= (widget
->allocation
.y
+ misc
->ypad
);
143 win
= widget
->window
;
144 gc
= widget
->style
->fg_gc
[widget
->state
];
146 /* increase line width */
147 gdk_gc_get_values(gc
, &gcvalues
);
148 gdk_gc_set_line_attributes(gc
, 3, gcvalues
.line_style
,
149 gcvalues
.cap_style
, gcvalues
.join_style
);
150 switch (arrow
->atype
) {
153 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
155 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
159 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
160 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+5);
161 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+height
-5);
163 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
164 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,y
+5);
165 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,y
+height
-5);
168 case ARROW_HOLLOW_TRIANGLE
:
170 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
171 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
172 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
173 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
174 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
175 gdk_draw_line(win
, gc
, x
+5+height
/2, y
+height
/2, x
+width
, y
+height
/2);
177 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
178 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
179 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
180 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
181 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
182 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
/2, y
+height
/2);
185 case ARROW_UNFILLED_TRIANGLE
:
187 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
188 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
189 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
190 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
191 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
192 gdk_draw_line(win
, gc
, x
+5, y
+height
/2, x
+width
, y
+height
/2);
194 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
195 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
196 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
197 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
198 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
199 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5, y
+height
/2);
202 case ARROW_FILLED_TRIANGLE
:
204 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
205 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
206 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
207 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
208 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
209 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
210 gdk_draw_line(win
, gc
, x
+5+height
/2, y
+height
/2, x
+width
, y
+height
/2);
212 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
213 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
214 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
215 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
216 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
217 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
218 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
/2, y
+height
/2);
221 case ARROW_HOLLOW_DIAMOND
:
223 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
224 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
225 pts
[2].x
= x
+5+height
*3/4; pts
[2].y
= y
+height
/2;
226 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
-5;
227 pts
[4].x
= x
+5; pts
[4].y
= y
+height
/2;
228 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
229 gdk_draw_line(win
, gc
, x
+5+height
*3/4,y
+height
/2, x
+width
, y
+height
/2);
231 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
232 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
233 pts
[2].x
= x
+width
-5-height
*3/4; pts
[2].y
= y
+height
/2;
234 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
-5;
235 pts
[4].x
= x
+width
-5; pts
[4].y
= y
+height
/2;
236 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
237 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
*3/4,y
+height
/2);
240 case ARROW_FILLED_DIAMOND
:
242 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
243 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
244 pts
[2].x
= x
+5+height
*3/4; pts
[2].y
= y
+height
/2;
245 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
-5;
246 pts
[4].x
= x
+5; pts
[4].y
= y
+height
/2;
247 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 5);
248 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
249 gdk_draw_line(win
, gc
, x
+5+height
*3/4,y
+height
/2, x
+width
, y
+height
/2);
251 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
252 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
253 pts
[2].x
= x
+width
-5-height
*3/4; pts
[2].y
= y
+height
/2;
254 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
-5;
255 pts
[4].x
= x
+width
-5; pts
[4].y
= y
+height
/2;
256 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 5);
257 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 5);
258 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
*3/4,y
+height
/2);
261 case ARROW_SLASHED_CROSS
:
263 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2); /*line*/
264 gdk_draw_line(win
, gc
, x
+5,y
+height
-5, x
+height
-5,y
+5); /*slash*/
265 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
-5, x
+height
/2,y
+5);
268 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2); /*line*/
269 gdk_draw_line(win
, gc
, x
+width
-height
/2-5,y
+height
-5, x
+width
-5,y
+5);
271 gdk_draw_line(win
, gc
, x
+width
-height
/2,y
+height
-5, x
+width
-height
/2,
275 case ARROW_HALF_HEAD
:
277 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+width
,y
+height
/2);
278 gdk_draw_line(win
, gc
, x
+5,y
+height
/2, x
+5+height
/2,y
+5);
280 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-5,y
+height
/2);
281 gdk_draw_line(win
, gc
, x
+width
-5,y
+height
/2, x
+width
-5-height
/2,
285 case ARROW_FILLED_ELLIPSE
:
287 gdk_draw_line(win
,gc
,x
+5+8,y
+height
/2,x
+width
,y
+height
/2);
288 gdk_draw_arc(win
,gc
,TRUE
,x
+5,y
+height
/2-6,12,12,0,64*360);
290 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-8,y
+height
/2);
291 gdk_draw_arc(win
,gc
,TRUE
,x
+width
-5-12,y
+height
/2-6,12,12,0,64*360);
294 case ARROW_HOLLOW_ELLIPSE
:
296 gdk_draw_line(win
,gc
,x
+5+8,y
+height
/2,x
+width
,y
+height
/2);
297 gdk_draw_arc(win
,gc
,FALSE
,x
+5,y
+height
/2-4,8,8,0,64*360);
299 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-8,y
+height
/2);
300 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-5-8,y
+height
/2-4,8,8,0,64*360);
303 case ARROW_DOUBLE_HOLLOW_TRIANGLE
:
305 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
306 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
307 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
308 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
309 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
310 pts
[0].x
= x
+5+height
/2; pts
[0].y
= y
+height
/2;
311 pts
[1].x
= x
+5+height
; pts
[1].y
= y
+5;
312 pts
[2].x
= x
+5+height
; pts
[2].y
= y
+height
-5;
313 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
/2;
314 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
315 gdk_draw_line(win
, gc
, x
+5+height
, y
+height
/2, x
+width
, y
+height
/2);
317 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
318 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
319 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
320 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
321 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
322 pts
[0].x
= x
+width
-5-height
/2; pts
[0].y
= y
+height
/2;
323 pts
[1].x
= x
+width
-5-height
; pts
[1].y
= y
+5;
324 pts
[2].x
= x
+width
-5-height
; pts
[2].y
= y
+height
-5;
325 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
/2;
326 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
327 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
, y
+height
/2);
330 case ARROW_DOUBLE_FILLED_TRIANGLE
:
332 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2;
333 pts
[1].x
= x
+5+height
/2; pts
[1].y
= y
+5;
334 pts
[2].x
= x
+5+height
/2; pts
[2].y
= y
+height
-5;
335 pts
[3].x
= x
+5; pts
[3].y
= y
+height
/2;
336 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
337 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
338 pts
[0].x
= x
+5+height
/2; pts
[0].y
= y
+height
/2;
339 pts
[1].x
= x
+5+height
; pts
[1].y
= y
+5;
340 pts
[2].x
= x
+5+height
; pts
[2].y
= y
+height
-5;
341 pts
[3].x
= x
+5+height
/2; pts
[3].y
= y
+height
/2;
342 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
343 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
344 gdk_draw_line(win
, gc
, x
+5+height
, y
+height
/2, x
+width
, y
+height
/2);
346 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2;
347 pts
[1].x
= x
+width
-5-height
/2; pts
[1].y
= y
+5;
348 pts
[2].x
= x
+width
-5-height
/2; pts
[2].y
= y
+height
-5;
349 pts
[3].x
= x
+width
-5; pts
[3].y
= y
+height
/2;
350 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
351 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
352 pts
[0].x
= x
+width
-5-height
/2; pts
[0].y
= y
+height
/2;
353 pts
[1].x
= x
+width
-5-height
; pts
[1].y
= y
+5;
354 pts
[2].x
= x
+width
-5-height
; pts
[2].y
= y
+height
-5;
355 pts
[3].x
= x
+width
-5-height
/2; pts
[3].y
= y
+height
/2;
356 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
357 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
358 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
-5-height
, y
+height
/2);
361 case ARROW_FILLED_DOT
:
363 gdk_draw_line(win
,gc
,x
+5+6,y
+height
/2,x
+width
,y
+height
/2);
364 gdk_draw_line(win
,gc
,x
+5+6,y
,x
+5+6,y
+height
);
365 gdk_draw_arc(win
,gc
,TRUE
,x
+5,y
+height
/2-6,12,12,0,64*360);
367 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-6,y
+height
/2);
368 gdk_draw_line(win
,gc
,x
+width
-5-6,y
,x
+width
-5-6,y
+height
);
369 gdk_draw_arc(win
,gc
,TRUE
,x
+width
-5-12,y
+height
/2-6,12,12,0,64*360);
372 case ARROW_BLANKED_DOT
:
374 gdk_draw_line(win
,gc
,x
+5+6,y
+height
/2,x
+width
,y
+height
/2);
375 gdk_draw_line(win
,gc
,x
+5+6,y
,x
+5+6,y
+height
);
376 gdk_draw_arc(win
,gc
,FALSE
,x
+5,y
+height
/2-6,12,12,0,64*360);
378 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-6,y
+height
/2);
379 gdk_draw_line(win
,gc
,x
+width
-5-6,y
,x
+width
-5-6,y
+height
);
380 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-5-12,y
+height
/2-6,12,12,0,64*360);
383 case ARROW_DIMENSION_ORIGIN
:
385 gdk_draw_line(win
,gc
,x
+5+12,y
+height
/2,x
+width
,y
+height
/2);
386 gdk_draw_line(win
,gc
,x
+5+6,y
,x
+5+6,y
+height
);
387 gdk_draw_arc(win
,gc
,FALSE
,x
+5,y
+height
/2-6,12,12,0,64*360);
389 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-12,y
+height
/2);
390 gdk_draw_line(win
,gc
,x
+width
-5-6,y
,x
+width
-5-6,y
+height
);
391 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-5-12,y
+height
/2-6,12,12,0,64*360);
394 case ARROW_FILLED_BOX
:
396 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2-6;
397 pts
[1].x
= x
+5; pts
[1].y
= y
+height
/2+6;
398 pts
[2].x
= x
+5+12; pts
[2].y
= y
+height
/2+6;
399 pts
[3].x
= x
+5+12; pts
[3].y
= y
+height
/2-6;
400 gdk_draw_line(win
,gc
,x
+5+12,y
+height
/2,x
+width
,y
+height
/2);
401 gdk_draw_line(win
,gc
,x
+5+6,y
,x
+5+6,y
+height
);
402 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
404 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2-6;
405 pts
[1].x
= x
+width
-5; pts
[1].y
= y
+height
/2+6;
406 pts
[2].x
= x
+width
-5-12; pts
[2].y
= y
+height
/2+6;
407 pts
[3].x
= x
+width
-5-12; pts
[3].y
= y
+height
/2-6;
408 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-12,y
+height
/2);
409 gdk_draw_line(win
,gc
,x
+width
-5-6,y
,x
+width
-5-6,y
+height
);
410 gdk_draw_polygon(win
, gc
, TRUE
, pts
, 4);
413 case ARROW_BLANKED_BOX
:
415 pts
[0].x
= x
+5; pts
[0].y
= y
+height
/2-6;
416 pts
[1].x
= x
+5; pts
[1].y
= y
+height
/2+6;
417 pts
[2].x
= x
+5+12; pts
[2].y
= y
+height
/2+6;
418 pts
[3].x
= x
+5+12; pts
[3].y
= y
+height
/2-6;
419 gdk_draw_line(win
,gc
,x
+5+12,y
+height
/2,x
+width
,y
+height
/2);
420 gdk_draw_line(win
,gc
,x
+5+6,y
,x
+5+6,y
+height
);
421 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
423 pts
[0].x
= x
+width
-5; pts
[0].y
= y
+height
/2-6;
424 pts
[1].x
= x
+width
-5; pts
[1].y
= y
+height
/2+6;
425 pts
[2].x
= x
+width
-5-12; pts
[2].y
= y
+height
/2+6;
426 pts
[3].x
= x
+width
-5-12; pts
[3].y
= y
+height
/2-6;
427 gdk_draw_line(win
,gc
,x
,y
+height
/2,x
+width
-5-12,y
+height
/2);
428 gdk_draw_line(win
,gc
,x
+width
-5-6,y
,x
+width
-5-6,y
+height
);
429 gdk_draw_polygon(win
, gc
, FALSE
, pts
, 4);
432 case ARROW_SLASH_ARROW
:
434 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
/2, x
+width
,y
+height
/2); /*line*/
435 gdk_draw_line(win
, gc
, x
+5,y
+height
-5, x
+height
-5,y
+5); /*slash*/
436 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
-4, x
+height
/2,y
+4);
439 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-height
/2,y
+height
/2); /*line*/
440 gdk_draw_line(win
, gc
, x
+width
-height
/2-5,y
+height
-5, x
+width
-5,y
+5);
442 gdk_draw_line(win
, gc
, x
+width
-height
/2,y
+height
-4, x
+width
-height
/2,
446 case ARROW_INTEGRAL_SYMBOL
:
448 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
/2, x
+width
,y
+height
/2); /*line*/
449 gdk_draw_arc(win
,gc
,FALSE
,x
+height
/2-12,y
+height
/2-9,
451 gdk_draw_arc(win
,gc
,FALSE
,x
+height
/2+1,y
+height
/2-5,
453 gdk_draw_line(win
, gc
, x
+height
/2,y
+height
-4, x
+height
/2,y
+4);
455 gdk_draw_line(win
, gc
, x
,y
+height
/2, x
+width
-height
/2,y
+height
/2); /*line*/
456 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-height
/2-13,y
+height
/2-8,
458 gdk_draw_arc(win
,gc
,FALSE
,x
+width
-height
/2-0,y
+height
/2-5,
460 gdk_draw_line(win
, gc
, x
+width
-height
/2,y
+height
-4, x
+width
-height
/2,
465 gdk_gc_set_line_attributes(gc
, gcvalues
.line_width
, gcvalues
.line_style
,
466 gcvalues
.cap_style
, gcvalues
.join_style
);
472 /* --------------- DiaLinePreview -------------------------------- */
473 typedef struct _DiaLinePreview DiaLinePreview
;
474 typedef struct _DiaLinePreviewClass DiaLinePreviewClass
;
476 static GtkType
dia_line_preview_get_type (void);
477 static void dia_line_preview_set(DiaLinePreview
*line
, LineStyle lstyle
);
478 static GtkWidget
*dia_line_preview_new (LineStyle lstyle
);
480 #define DIA_LINE_PREVIEW(obj) (GTK_CHECK_CAST((obj),dia_line_preview_get_type(), DiaLinePreview))
481 #define DIA_LINE_PREVIEW_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_preview_get_type(), DiaLinePreviewClass))
483 struct _DiaLinePreview
488 struct _DiaLinePreviewClass
490 GtkMiscClass parent_class
;
493 static void dia_line_preview_class_init (DiaLinePreviewClass
*klass
);
494 static void dia_line_preview_init (DiaLinePreview
*arrow
);
495 static gint
dia_line_preview_expose (GtkWidget
*widget
,
496 GdkEventExpose
*event
);
499 dia_line_preview_get_type (void)
501 static GtkType line_type
= 0;
504 static const GtkTypeInfo line_info
= {
506 sizeof (DiaLinePreview
),
507 sizeof (DiaLinePreviewClass
),
508 (GtkClassInitFunc
) dia_line_preview_class_init
,
509 (GtkObjectInitFunc
) dia_line_preview_init
,
510 /* reserved_1 */ NULL
,
511 /* reserved_2 */ NULL
,
512 (GtkClassInitFunc
) NULL
,
514 line_type
= gtk_type_unique (GTK_TYPE_MISC
, &line_info
);
520 dia_line_preview_class_init (DiaLinePreviewClass
*class)
522 GtkWidgetClass
*widget_class
;
524 widget_class
= (GtkWidgetClass
*)class;
525 widget_class
->expose_event
= dia_line_preview_expose
;
529 dia_line_preview_init (DiaLinePreview
*line
)
531 GTK_WIDGET_SET_FLAGS (line
, GTK_NO_WINDOW
);
533 GTK_WIDGET (line
)->requisition
.width
= 40 + GTK_MISC (line
)->xpad
* 2;
534 GTK_WIDGET (line
)->requisition
.height
= 20 + GTK_MISC (line
)->ypad
* 2;
537 line
->lstyle
= LINESTYLE_SOLID
;
541 dia_line_preview_new (LineStyle lstyle
)
543 DiaLinePreview
*line
= gtk_type_new (dia_line_preview_get_type());
545 line
->lstyle
= lstyle
;
546 return GTK_WIDGET(line
);
550 dia_line_preview_set(DiaLinePreview
*line
, LineStyle lstyle
)
552 if (line
->lstyle
!= lstyle
) {
553 line
->lstyle
= lstyle
;
554 if (GTK_WIDGET_DRAWABLE(line
))
555 gtk_widget_queue_clear(GTK_WIDGET(line
));
560 dia_line_preview_expose(GtkWidget
*widget
, GdkEventExpose
*event
)
562 DiaLinePreview
*line
= DIA_LINE_PREVIEW(widget
);
563 GtkMisc
*misc
= GTK_MISC(widget
);
569 GdkGCValues gcvalues
;
572 if (GTK_WIDGET_DRAWABLE(widget
)) {
573 width
= widget
->allocation
.width
- misc
->xpad
* 2;
574 height
= widget
->allocation
.height
- misc
->ypad
* 2;
575 extent
= MIN(width
, height
);
576 x
= (widget
->allocation
.x
+ misc
->xpad
);
577 y
= (widget
->allocation
.y
+ misc
->ypad
);
579 win
= widget
->window
;
580 gc
= widget
->style
->fg_gc
[widget
->state
];
582 /* increase line width */
583 gdk_gc_get_values(gc
, &gcvalues
);
584 switch (line
->lstyle
) {
585 case LINESTYLE_SOLID
:
586 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_SOLID
,
587 gcvalues
.cap_style
, gcvalues
.join_style
);
589 case LINESTYLE_DASHED
:
590 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
591 gcvalues
.cap_style
, gcvalues
.join_style
);
594 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
596 case LINESTYLE_DASH_DOT
:
597 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
598 gcvalues
.cap_style
, gcvalues
.join_style
);
603 gdk_gc_set_dashes(gc
, 0, dash_list
, 4);
605 case LINESTYLE_DASH_DOT_DOT
:
606 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
607 gcvalues
.cap_style
, gcvalues
.join_style
);
614 gdk_gc_set_dashes(gc
, 0, dash_list
, 6);
616 case LINESTYLE_DOTTED
:
617 gdk_gc_set_line_attributes(gc
, 3, GDK_LINE_ON_OFF_DASH
,
618 gcvalues
.cap_style
, gcvalues
.join_style
);
621 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
624 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
, y
+height
/2);
625 gdk_gc_set_line_attributes(gc
, gcvalues
.line_width
, gcvalues
.line_style
,
626 gcvalues
.cap_style
, gcvalues
.join_style
);
631 /* ------- Code for DiaArrowChooser ----------------------- */
632 static GtkType
dia_arrow_chooser_get_type (void);
634 static gint
close_and_hide(GtkWidget
*wid
, GdkEventAny
*event
) {
635 gtk_widget_hide(wid
);
638 static const char *button_menu_key
= "dia-button-menu";
639 static const char *menuitem_enum_key
= "dia-menuitem-value";
642 #define DIA_ARROW_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_arrow_chooser_get_type(), DiaArrowChooser))
643 #define DIA_ARROW_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_arrow_chooser_get_type(), DiaArrowChooserClass))
645 typedef struct _DiaArrowChooser DiaArrowChooser
;
646 typedef struct _DiaArrowChooserClass DiaArrowChooserClass
;
648 struct _DiaArrowChooser
651 DiaArrowPreview
*preview
;
655 DiaChangeArrowCallback callback
;
659 DiaArrowSelector
*selector
;
661 struct _DiaArrowChooserClass
663 GtkButtonClass parent_class
;
666 static void dia_arrow_chooser_class_init (DiaArrowChooserClass
*klass
);
667 static void dia_arrow_chooser_init (DiaArrowChooser
*arrow
);
668 static gint
dia_arrow_chooser_event (GtkWidget
*widget
,
670 static void dia_arrow_chooser_dialog_ok (DiaArrowChooser
*arrow
);
671 static void dia_arrow_chooser_dialog_cancel (DiaArrowChooser
*arrow
);
672 static void dia_arrow_chooser_change_arrow_type (GtkMenuItem
*mi
,
673 DiaArrowChooser
*arrow
);
676 dia_arrow_chooser_get_type (void)
678 static GtkType arrow_type
= 0;
681 static const GtkTypeInfo arrow_info
= {
683 sizeof (DiaArrowChooser
),
684 sizeof (DiaArrowChooserClass
),
685 (GtkClassInitFunc
) dia_arrow_chooser_class_init
,
686 (GtkObjectInitFunc
) dia_arrow_chooser_init
,
687 /* reserved_1 */ NULL
,
688 /* reserved_2 */ NULL
,
689 (GtkClassInitFunc
) NULL
,
691 arrow_type
= gtk_type_unique (GTK_TYPE_BUTTON
, &arrow_info
);
697 dia_arrow_chooser_class_init (DiaArrowChooserClass
*class)
699 GtkWidgetClass
*widget_class
;
701 widget_class
= (GtkWidgetClass
*)class;
702 widget_class
->event
= dia_arrow_chooser_event
;
706 dia_arrow_chooser_init (DiaArrowChooser
*arrow
)
711 arrow
->arrow
.type
= ARROW_NONE
;
712 arrow
->arrow
.length
= DEFAULT_ARROW_LENGTH
;
713 arrow
->arrow
.width
= DEFAULT_ARROW_WIDTH
;
715 wid
= dia_arrow_preview_new(ARROW_NONE
, arrow
->left
);
716 gtk_container_add(GTK_CONTAINER(arrow
), wid
);
717 gtk_widget_show(wid
);
718 arrow
->preview
= DIA_ARROW_PREVIEW(wid
);
720 arrow
->dialog
= wid
= gtk_dialog_new();
721 gtk_window_set_title(GTK_WINDOW(wid
), _("Arrow Properties"));
722 gtk_signal_connect(GTK_OBJECT(wid
), "delete_event",
723 GTK_SIGNAL_FUNC(close_and_hide
), NULL
);
725 wid
= dia_arrow_selector_new();
726 gtk_container_set_border_width(GTK_CONTAINER(wid
), 5);
727 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(arrow
->dialog
)->vbox
), wid
,
729 gtk_widget_show(wid
);
730 arrow
->selector
= DIAARROWSELECTOR(wid
);
732 wid
= gtk_button_new_with_label(_("OK"));
733 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
734 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(arrow
->dialog
)->action_area
),wid
);
735 gtk_widget_grab_default(wid
);
736 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
737 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_ok
),
739 gtk_widget_show(wid
);
741 wid
= gtk_button_new_with_label(_("Cancel"));
742 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
743 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(arrow
->dialog
)->action_area
),wid
);
744 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
745 GTK_SIGNAL_FUNC(dia_arrow_chooser_dialog_cancel
),
747 gtk_widget_show(wid
);
751 dia_arrow_chooser_new(gboolean left
, DiaChangeArrowCallback callback
,
754 DiaArrowChooser
*chooser
= gtk_type_new(dia_arrow_chooser_get_type());
755 GtkWidget
*menu
, *mi
, *ar
;
758 chooser
->left
= left
;
759 dia_arrow_preview_set(chooser
->preview
, chooser
->preview
->atype
, left
);
760 chooser
->callback
= callback
;
761 chooser
->user_data
= user_data
;
763 menu
= gtk_menu_new();
764 gtk_object_set_data_full(GTK_OBJECT(chooser
), button_menu_key
, menu
,
765 (GtkDestroyNotify
)gtk_widget_unref
);
766 for (i
= 0; i
<= ARROW_INTEGRAL_SYMBOL
; i
++) {
767 mi
= gtk_menu_item_new();
768 gtk_object_set_data(GTK_OBJECT(mi
), menuitem_enum_key
, GINT_TO_POINTER(i
));
769 ar
= dia_arrow_preview_new(i
, left
);
770 gtk_container_add(GTK_CONTAINER(mi
), ar
);
772 gtk_signal_connect(GTK_OBJECT(mi
), "activate",
773 GTK_SIGNAL_FUNC(dia_arrow_chooser_change_arrow_type
),
775 gtk_container_add(GTK_CONTAINER(menu
), mi
);
778 mi
= gtk_menu_item_new_with_label(_("Details..."));
779 gtk_signal_connect_object(GTK_OBJECT(mi
), "activate",
780 GTK_SIGNAL_FUNC(gtk_widget_show
),
781 GTK_OBJECT(chooser
->dialog
));
782 gtk_container_add(GTK_CONTAINER(menu
), mi
);
785 return GTK_WIDGET(chooser
);
789 dia_arrow_chooser_event(GtkWidget
*widget
, GdkEvent
*event
)
791 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
.button
== 1) {
792 GtkMenu
*menu
= gtk_object_get_data(GTK_OBJECT(widget
), button_menu_key
);
793 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
,
794 event
->button
.button
, event
->button
.time
);
801 dia_arrow_chooser_dialog_ok (DiaArrowChooser
*arrow
)
803 Arrow new_arrow
= dia_arrow_selector_get_arrow(arrow
->selector
);
805 if (new_arrow
.type
!= arrow
->arrow
.type
||
806 new_arrow
.length
!= arrow
->arrow
.length
||
807 new_arrow
.width
!= arrow
->arrow
.width
) {
808 arrow
->arrow
= new_arrow
;
809 dia_arrow_preview_set(arrow
->preview
, new_arrow
.type
, arrow
->left
);
811 (* arrow
->callback
)(arrow
->arrow
, arrow
->user_data
);
813 gtk_widget_hide(arrow
->dialog
);
816 dia_arrow_chooser_dialog_cancel (DiaArrowChooser
*arrow
)
818 dia_arrow_selector_set_arrow(arrow
->selector
, arrow
->arrow
);
819 gtk_widget_hide(arrow
->dialog
);
823 dia_arrow_chooser_change_arrow_type(GtkMenuItem
*mi
, DiaArrowChooser
*arrow
)
825 ArrowType atype
= GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi
),
828 if (arrow
->arrow
.type
!= atype
) {
829 dia_arrow_preview_set(arrow
->preview
, atype
, arrow
->left
);
830 arrow
->arrow
.type
= atype
;
831 dia_arrow_selector_set_arrow(arrow
->selector
, arrow
->arrow
);
833 (* arrow
->callback
)(arrow
->arrow
, arrow
->user_data
);
838 /* ------- Code for DiaLineChooser ---------------------- */
839 static GtkType
dia_line_chooser_get_type (void);
841 #define DIA_LINE_CHOOSER(obj) (GTK_CHECK_CAST((obj),dia_line_chooser_get_type(), DiaLineChooser))
842 #define DIA_LINE_CHOOSER_CLASS(obj) (GTK_CHECK_CLASS_CAST((obj), dia_line_chooser_get_type(), DiaLineChooserClass))
844 typedef struct _DiaLineChooser DiaLineChooser
;
845 typedef struct _DiaLineChooserClass DiaLineChooserClass
;
847 struct _DiaLineChooser
850 DiaLinePreview
*preview
;
854 DiaChangeLineCallback callback
;
858 DiaLineStyleSelector
*selector
;
860 struct _DiaLineChooserClass
862 GtkButtonClass parent_class
;
865 static void dia_line_chooser_class_init (DiaLineChooserClass
*klass
);
866 static void dia_line_chooser_init (DiaLineChooser
*arrow
);
867 static gint
dia_line_chooser_event (GtkWidget
*widget
,
869 static void dia_line_chooser_dialog_ok (DiaLineChooser
*lchooser
);
870 static void dia_line_chooser_dialog_cancel (DiaLineChooser
*lchooser
);
871 static void dia_line_chooser_change_line_style (GtkMenuItem
*mi
,
872 DiaLineChooser
*lchooser
);
875 dia_line_chooser_get_type (void)
877 static GtkType arrow_type
= 0;
880 static const GtkTypeInfo arrow_info
= {
882 sizeof (DiaLineChooser
),
883 sizeof (DiaLineChooserClass
),
884 (GtkClassInitFunc
) dia_line_chooser_class_init
,
885 (GtkObjectInitFunc
) dia_line_chooser_init
,
886 /* reserved_1 */ NULL
,
887 /* reserved_2 */ NULL
,
888 (GtkClassInitFunc
) NULL
,
890 arrow_type
= gtk_type_unique (GTK_TYPE_BUTTON
, &arrow_info
);
896 dia_line_chooser_class_init (DiaLineChooserClass
*class)
898 GtkWidgetClass
*widget_class
;
900 widget_class
= (GtkWidgetClass
*)class;
901 widget_class
->event
= dia_line_chooser_event
;
905 dia_line_chooser_init (DiaLineChooser
*lchooser
)
908 GtkWidget
*menu
, *mi
, *ln
;
911 lchooser
->lstyle
= LINESTYLE_SOLID
;
912 lchooser
->dash_length
= DEFAULT_LINESTYLE_DASHLEN
;
914 wid
= dia_line_preview_new(LINESTYLE_SOLID
);
915 gtk_container_add(GTK_CONTAINER(lchooser
), wid
);
916 gtk_widget_show(wid
);
917 lchooser
->preview
= DIA_LINE_PREVIEW(wid
);
919 lchooser
->dialog
= wid
= gtk_dialog_new();
920 gtk_window_set_title(GTK_WINDOW(wid
), _("Line Style Properties"));
921 gtk_signal_connect(GTK_OBJECT(wid
), "delete_event",
922 GTK_SIGNAL_FUNC(close_and_hide
), NULL
);
924 wid
= dia_line_style_selector_new();
925 gtk_container_set_border_width(GTK_CONTAINER(wid
), 5);
926 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lchooser
->dialog
)->vbox
), wid
,
928 gtk_widget_show(wid
);
929 lchooser
->selector
= DIALINESTYLESELECTOR(wid
);
931 wid
= gtk_button_new_with_label(_("OK"));
932 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
933 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser
->dialog
)->action_area
),
935 gtk_widget_grab_default(wid
);
936 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
937 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_ok
),
938 GTK_OBJECT(lchooser
));
939 gtk_widget_show(wid
);
941 wid
= gtk_button_new_with_label(_("Cancel"));
942 GTK_WIDGET_SET_FLAGS(wid
, GTK_CAN_DEFAULT
);
943 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(lchooser
->dialog
)->action_area
),
945 gtk_signal_connect_object(GTK_OBJECT(wid
), "clicked",
946 GTK_SIGNAL_FUNC(dia_line_chooser_dialog_cancel
),
947 GTK_OBJECT(lchooser
));
949 menu
= gtk_menu_new();
950 gtk_object_set_data_full(GTK_OBJECT(lchooser
), button_menu_key
, menu
,
951 (GtkDestroyNotify
)gtk_widget_unref
);
952 for (i
= 0; i
<= LINESTYLE_DOTTED
; i
++) {
953 mi
= gtk_menu_item_new();
954 gtk_object_set_data(GTK_OBJECT(mi
), menuitem_enum_key
, GINT_TO_POINTER(i
));
955 ln
= dia_line_preview_new(i
);
956 gtk_container_add(GTK_CONTAINER(mi
), ln
);
958 gtk_signal_connect(GTK_OBJECT(mi
), "activate",
959 GTK_SIGNAL_FUNC(dia_line_chooser_change_line_style
),
961 gtk_container_add(GTK_CONTAINER(menu
), mi
);
964 mi
= gtk_menu_item_new_with_label(_("Details..."));
965 gtk_signal_connect_object(GTK_OBJECT(mi
), "activate",
966 GTK_SIGNAL_FUNC(gtk_widget_show
),
967 GTK_OBJECT(lchooser
->dialog
));
968 gtk_container_add(GTK_CONTAINER(menu
), mi
);
971 gtk_widget_show(wid
);
975 dia_line_chooser_new(DiaChangeLineCallback callback
,
978 DiaLineChooser
*chooser
= gtk_type_new(dia_line_chooser_get_type());
980 chooser
->callback
= callback
;
981 chooser
->user_data
= user_data
;
983 return GTK_WIDGET(chooser
);
987 dia_line_chooser_event(GtkWidget
*widget
, GdkEvent
*event
)
989 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
.button
== 1) {
990 GtkMenu
*menu
= gtk_object_get_data(GTK_OBJECT(widget
), button_menu_key
);
991 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
,
992 event
->button
.button
, event
->button
.time
);
999 dia_line_chooser_dialog_ok (DiaLineChooser
*lchooser
)
1001 LineStyle new_style
;
1004 dia_line_style_selector_get_linestyle(lchooser
->selector
,
1005 &new_style
, &new_dash
);
1006 if (new_style
!= lchooser
->lstyle
|| new_dash
!= lchooser
->dash_length
) {
1007 lchooser
->lstyle
= new_style
;
1008 lchooser
->dash_length
= new_dash
;
1009 dia_line_preview_set(lchooser
->preview
, new_style
);
1010 if (lchooser
->callback
)
1011 (* lchooser
->callback
)(new_style
, new_dash
, lchooser
->user_data
);
1013 gtk_widget_hide(lchooser
->dialog
);
1016 dia_line_chooser_dialog_cancel (DiaLineChooser
*lchooser
)
1018 dia_line_style_selector_set_linestyle(lchooser
->selector
, lchooser
->lstyle
,
1019 lchooser
->dash_length
);
1020 gtk_widget_hide(lchooser
->dialog
);
1024 dia_line_chooser_change_line_style(GtkMenuItem
*mi
, DiaLineChooser
*lchooser
)
1026 LineStyle lstyle
= GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi
),
1027 menuitem_enum_key
));
1029 if (lchooser
->lstyle
!= lstyle
) {
1030 dia_line_preview_set(lchooser
->preview
, lstyle
);
1031 lchooser
->lstyle
= lstyle
;
1032 dia_line_style_selector_set_linestyle(lchooser
->selector
, lchooser
->lstyle
,
1033 lchooser
->dash_length
);
1034 if (lchooser
->callback
)
1035 (* lchooser
->callback
)(lchooser
->lstyle
, lchooser
->dash_length
,
1036 lchooser
->user_data
);