1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include "orth_conn.h"
30 #include "connectionpoint.h"
32 #include "attributes.h"
35 #include "properties.h"
37 #include "pixmaps/zigzag.xpm"
39 #define DEFAULT_WIDTH 0.15
41 #define HANDLE_MIDDLE HANDLE_CUSTOM1
43 typedef struct _Zigzagline
{
50 Arrow start_arrow
, end_arrow
;
54 static void zigzagline_move_handle(Zigzagline
*zigzagline
, Handle
*handle
,
55 Point
*to
, HandleMoveReason reason
, ModifierKeys modifiers
);
56 static void zigzagline_move(Zigzagline
*zigzagline
, Point
*to
);
57 static void zigzagline_select(Zigzagline
*zigzagline
, Point
*clicked_point
,
58 Renderer
*interactive_renderer
);
59 static void zigzagline_draw(Zigzagline
*zigzagline
, Renderer
*renderer
);
60 static Object
*zigzagline_create(Point
*startpoint
,
64 static real
zigzagline_distance_from(Zigzagline
*zigzagline
, Point
*point
);
65 static void zigzagline_update_data(Zigzagline
*zigzagline
);
66 static void zigzagline_destroy(Zigzagline
*zigzagline
);
67 static Object
*zigzagline_copy(Zigzagline
*zigzagline
);
68 static DiaMenu
*zigzagline_get_object_menu(Zigzagline
*zigzagline
,
71 static PropDescription
*zigzagline_describe_props(Zigzagline
*zigzagline
);
72 static void zigzagline_get_props(Zigzagline
*zigzagline
, GPtrArray
*props
);
73 static void zigzagline_set_props(Zigzagline
*zigzagline
, GPtrArray
*props
);
75 static void zigzagline_save(Zigzagline
*zigzagline
, ObjectNode obj_node
,
76 const char *filename
);
77 static Object
*zigzagline_load(ObjectNode obj_node
, int version
,
78 const char *filename
);
79 /* static GtkWidget *zigzagline_get_defaults();
80 static void zigzagline_apply_defaults(); */
82 static ObjectTypeOps zigzagline_type_ops
=
84 (CreateFunc
)zigzagline_create
, /* create */
85 (LoadFunc
) zigzagline_load
, /* load */
86 (SaveFunc
) zigzagline_save
, /* save */
87 (GetDefaultsFunc
) NULL
,/*zigzagline_get_defaults*/
88 (ApplyDefaultsFunc
) NULL
/*zigzagline_apply_defaults*/
91 static ObjectType zigzagline_type
=
93 "Standard - ZigZagLine", /* name */
95 (char **) zigzag_xpm
, /* pixmap */
97 &zigzagline_type_ops
/* ops */
100 ObjectType
*_zigzagline_type
= (ObjectType
*) &zigzagline_type
;
103 static ObjectOps zigzagline_ops
= {
104 (DestroyFunc
) zigzagline_destroy
,
105 (DrawFunc
) zigzagline_draw
,
106 (DistanceFunc
) zigzagline_distance_from
,
107 (SelectFunc
) zigzagline_select
,
108 (CopyFunc
) zigzagline_copy
,
109 (MoveFunc
) zigzagline_move
,
110 (MoveHandleFunc
) zigzagline_move_handle
,
111 (GetPropertiesFunc
) object_create_props_dialog
,
112 (ApplyPropertiesFunc
) object_apply_props_from_dialog
,
113 (ObjectMenuFunc
) zigzagline_get_object_menu
,
114 (DescribePropsFunc
) zigzagline_describe_props
,
115 (GetPropsFunc
) zigzagline_get_props
,
116 (SetPropsFunc
) zigzagline_set_props
,
119 static PropDescription zigzagline_props
[] = {
120 OBJECT_COMMON_PROPERTIES
,
122 PROP_STD_LINE_COLOUR
,
124 PROP_STD_START_ARROW
,
129 static PropDescription
*
130 zigzagline_describe_props(Zigzagline
*zigzagline
)
132 if (zigzagline_props
[0].quark
== 0)
133 prop_desc_list_calculate_quarks(zigzagline_props
);
134 return zigzagline_props
;
137 static PropOffset zigzagline_offsets
[] = {
138 OBJECT_COMMON_PROPERTIES_OFFSETS
,
139 { "line_width", PROP_TYPE_REAL
, offsetof(Zigzagline
, line_width
) },
140 { "line_colour", PROP_TYPE_COLOUR
, offsetof(Zigzagline
, line_color
) },
141 { "line_style", PROP_TYPE_LINESTYLE
,
142 offsetof(Zigzagline
, line_style
), offsetof(Zigzagline
, dashlength
) },
143 { "start_arrow", PROP_TYPE_ARROW
, offsetof(Zigzagline
, start_arrow
) },
144 { "end_arrow", PROP_TYPE_ARROW
, offsetof(Zigzagline
, end_arrow
) },
149 zigzagline_get_props(Zigzagline
*zigzagline
, GPtrArray
*props
)
151 object_get_props_from_offsets(&zigzagline
->orth
.object
, zigzagline_offsets
,
156 zigzagline_set_props(Zigzagline
*zigzagline
, GPtrArray
*props
)
158 object_set_props_from_offsets(&zigzagline
->orth
.object
, zigzagline_offsets
,
160 zigzagline_update_data(zigzagline
);
164 zigzagline_distance_from(Zigzagline
*zigzagline
, Point
*point
)
166 OrthConn
*orth
= &zigzagline
->orth
;
167 return orthconn_distance_from(orth
, point
, zigzagline
->line_width
);
171 zigzagline_select(Zigzagline
*zigzagline
, Point
*clicked_point
,
172 Renderer
*interactive_renderer
)
174 orthconn_update_data(&zigzagline
->orth
);
178 zigzagline_move_handle(Zigzagline
*zigzagline
, Handle
*handle
,
179 Point
*to
, HandleMoveReason reason
, ModifierKeys modifiers
)
181 assert(zigzagline
!=NULL
);
182 assert(handle
!=NULL
);
185 orthconn_move_handle(&zigzagline
->orth
, handle
, to
, reason
);
186 zigzagline_update_data(zigzagline
);
191 zigzagline_move(Zigzagline
*zigzagline
, Point
*to
)
193 orthconn_move(&zigzagline
->orth
, to
);
194 zigzagline_update_data(zigzagline
);
198 zigzagline_draw(Zigzagline
*zigzagline
, Renderer
*renderer
)
200 OrthConn
*orth
= &zigzagline
->orth
;
204 points
= &orth
->points
[0];
207 renderer
->ops
->set_linewidth(renderer
, zigzagline
->line_width
);
208 renderer
->ops
->set_linestyle(renderer
, zigzagline
->line_style
);
209 renderer
->ops
->set_dashlength(renderer
, zigzagline
->dashlength
);
210 renderer
->ops
->set_linejoin(renderer
, LINEJOIN_MITER
);
211 renderer
->ops
->set_linecaps(renderer
, LINECAPS_BUTT
);
213 renderer
->ops
->draw_polyline(renderer
, points
, n
, &zigzagline
->line_color
);
215 if (zigzagline
->start_arrow
.type
!= ARROW_NONE
) {
216 arrow_draw(renderer
, zigzagline
->start_arrow
.type
,
217 &points
[0], &points
[1],
218 zigzagline
->start_arrow
.length
, zigzagline
->start_arrow
.width
,
219 zigzagline
->line_width
,
220 &zigzagline
->line_color
, &color_white
);
222 if (zigzagline
->end_arrow
.type
!= ARROW_NONE
) {
223 arrow_draw(renderer
, zigzagline
->end_arrow
.type
,
224 &points
[n
-1], &points
[n
-2],
225 zigzagline
->end_arrow
.length
, zigzagline
->end_arrow
.width
,
226 zigzagline
->line_width
,
227 &zigzagline
->line_color
, &color_white
);
232 zigzagline_create(Point
*startpoint
,
237 Zigzagline
*zigzagline
;
241 /*zigzagline_init_defaults();*/
242 zigzagline
= g_malloc0(sizeof(Zigzagline
));
243 orth
= &zigzagline
->orth
;
246 obj
->type
= &zigzagline_type
;
247 obj
->ops
= &zigzagline_ops
;
249 orthconn_init(orth
, startpoint
);
251 zigzagline_update_data(zigzagline
);
253 zigzagline
->line_width
= attributes_get_default_linewidth();
254 zigzagline
->line_color
= attributes_get_foreground();
255 attributes_get_default_line_style(&zigzagline
->line_style
,
256 &zigzagline
->dashlength
);
257 zigzagline
->start_arrow
= attributes_get_default_start_arrow();
258 zigzagline
->end_arrow
= attributes_get_default_end_arrow();
260 *handle1
= orth
->handles
[0];
261 *handle2
= orth
->handles
[orth
->numpoints
-2];
262 return &zigzagline
->orth
.object
;
266 zigzagline_destroy(Zigzagline
*zigzagline
)
268 orthconn_destroy(&zigzagline
->orth
);
272 zigzagline_copy(Zigzagline
*zigzagline
)
274 Zigzagline
*newzigzagline
;
275 OrthConn
*orth
, *neworth
;
278 orth
= &zigzagline
->orth
;
280 newzigzagline
= g_malloc0(sizeof(Zigzagline
));
281 neworth
= &newzigzagline
->orth
;
282 newobj
= &neworth
->object
;
284 orthconn_copy(orth
, neworth
);
286 newzigzagline
->line_color
= zigzagline
->line_color
;
287 newzigzagline
->line_width
= zigzagline
->line_width
;
288 newzigzagline
->line_style
= zigzagline
->line_style
;
289 newzigzagline
->dashlength
= zigzagline
->dashlength
;
290 newzigzagline
->start_arrow
= zigzagline
->start_arrow
;
291 newzigzagline
->end_arrow
= zigzagline
->end_arrow
;
293 return &newzigzagline
->orth
.object
;
297 zigzagline_update_data(Zigzagline
*zigzagline
)
299 OrthConn
*orth
= &zigzagline
->orth
;
300 PolyBBExtras
*extra
= &orth
->extra_spacing
;
302 orthconn_update_data(&zigzagline
->orth
);
306 extra
->middle_trans
= zigzagline
->line_width
/2.0;
307 extra
->start_trans
= (zigzagline
->line_width
/ 2.0);
308 extra
->end_trans
= (zigzagline
->line_width
/ 2.0);
310 if (zigzagline
->start_arrow
.type
!= ARROW_NONE
)
311 extra
->start_trans
= MAX(extra
->start_trans
,zigzagline
->start_arrow
.width
);
312 if (zigzagline
->end_arrow
.type
!= ARROW_NONE
)
313 extra
->end_trans
= MAX(extra
->end_trans
,zigzagline
->end_arrow
.width
);
315 orthconn_update_boundingbox(orth
);
318 static ObjectChange
*
319 zigzagline_add_segment_callback(Object
*obj
, Point
*clicked
, gpointer data
)
321 ObjectChange
*change
;
322 change
= orthconn_add_segment((OrthConn
*)obj
, clicked
);
323 zigzagline_update_data((Zigzagline
*)obj
);
327 static ObjectChange
*
328 zigzagline_delete_segment_callback(Object
*obj
, Point
*clicked
, gpointer data
)
330 ObjectChange
*change
;
331 change
= orthconn_delete_segment((OrthConn
*)obj
, clicked
);
332 zigzagline_update_data((Zigzagline
*)obj
);
336 static DiaMenuItem object_menu_items
[] = {
337 { N_("Add segment"), zigzagline_add_segment_callback
, NULL
, 1 },
338 { N_("Delete segment"), zigzagline_delete_segment_callback
, NULL
, 1 },
341 static DiaMenu object_menu
= {
343 sizeof(object_menu_items
)/sizeof(DiaMenuItem
),
349 zigzagline_get_object_menu(Zigzagline
*zigzagline
, Point
*clickedpoint
)
353 orth
= &zigzagline
->orth
;
354 /* Set entries sensitive/selected etc here */
355 object_menu_items
[0].active
= orthconn_can_add_segment(orth
, clickedpoint
);
356 object_menu_items
[1].active
= orthconn_can_delete_segment(orth
, clickedpoint
);
362 zigzagline_save(Zigzagline
*zigzagline
, ObjectNode obj_node
,
363 const char *filename
)
365 orthconn_save(&zigzagline
->orth
, obj_node
);
367 if (!color_equals(&zigzagline
->line_color
, &color_black
))
368 data_add_color(new_attribute(obj_node
, "line_color"),
369 &zigzagline
->line_color
);
371 if (zigzagline
->line_width
!= 0.1)
372 data_add_real(new_attribute(obj_node
, "line_width"),
373 zigzagline
->line_width
);
375 if (zigzagline
->line_style
!= LINESTYLE_SOLID
)
376 data_add_enum(new_attribute(obj_node
, "line_style"),
377 zigzagline
->line_style
);
379 if (zigzagline
->start_arrow
.type
!= ARROW_NONE
) {
380 data_add_enum(new_attribute(obj_node
, "start_arrow"),
381 zigzagline
->start_arrow
.type
);
382 data_add_real(new_attribute(obj_node
, "start_arrow_length"),
383 zigzagline
->start_arrow
.length
);
384 data_add_real(new_attribute(obj_node
, "start_arrow_width"),
385 zigzagline
->start_arrow
.width
);
388 if (zigzagline
->end_arrow
.type
!= ARROW_NONE
) {
389 data_add_enum(new_attribute(obj_node
, "end_arrow"),
390 zigzagline
->end_arrow
.type
);
391 data_add_real(new_attribute(obj_node
, "end_arrow_length"),
392 zigzagline
->end_arrow
.length
);
393 data_add_real(new_attribute(obj_node
, "end_arrow_width"),
394 zigzagline
->end_arrow
.width
);
397 if (zigzagline
->line_style
!= LINESTYLE_SOLID
&&
398 zigzagline
->dashlength
!= DEFAULT_LINESTYLE_DASHLEN
)
399 data_add_real(new_attribute(obj_node
, "dashlength"),
400 zigzagline
->dashlength
);
404 zigzagline_load(ObjectNode obj_node
, int version
, const char *filename
)
406 Zigzagline
*zigzagline
;
411 zigzagline
= g_malloc0(sizeof(Zigzagline
));
413 orth
= &zigzagline
->orth
;
416 obj
->type
= &zigzagline_type
;
417 obj
->ops
= &zigzagline_ops
;
419 orthconn_load(orth
, obj_node
);
421 zigzagline
->line_color
= color_black
;
422 attr
= object_find_attribute(obj_node
, "line_color");
424 data_color(attribute_first_data(attr
), &zigzagline
->line_color
);
426 zigzagline
->line_width
= 0.1;
427 attr
= object_find_attribute(obj_node
, "line_width");
429 zigzagline
->line_width
= data_real(attribute_first_data(attr
));
431 zigzagline
->line_style
= LINESTYLE_SOLID
;
432 attr
= object_find_attribute(obj_node
, "line_style");
434 zigzagline
->line_style
= data_enum(attribute_first_data(attr
));
436 zigzagline
->start_arrow
.type
= ARROW_NONE
;
437 zigzagline
->start_arrow
.length
= 0.8;
438 zigzagline
->start_arrow
.width
= 0.8;
439 attr
= object_find_attribute(obj_node
, "start_arrow");
441 zigzagline
->start_arrow
.type
= data_enum(attribute_first_data(attr
));
442 attr
= object_find_attribute(obj_node
, "start_arrow_length");
444 zigzagline
->start_arrow
.length
= data_real(attribute_first_data(attr
));
445 attr
= object_find_attribute(obj_node
, "start_arrow_width");
447 zigzagline
->start_arrow
.width
= data_real(attribute_first_data(attr
));
449 zigzagline
->end_arrow
.type
= ARROW_NONE
;
450 zigzagline
->end_arrow
.length
= 0.8;
451 zigzagline
->end_arrow
.width
= 0.8;
452 attr
= object_find_attribute(obj_node
, "end_arrow");
454 zigzagline
->end_arrow
.type
= data_enum(attribute_first_data(attr
));
455 attr
= object_find_attribute(obj_node
, "end_arrow_length");
457 zigzagline
->end_arrow
.length
= data_real(attribute_first_data(attr
));
458 attr
= object_find_attribute(obj_node
, "end_arrow_width");
460 zigzagline
->end_arrow
.width
= data_real(attribute_first_data(attr
));
462 zigzagline
->dashlength
= DEFAULT_LINESTYLE_DASHLEN
;
463 attr
= object_find_attribute(obj_node
, "dashlength");
465 zigzagline
->dashlength
= data_real(attribute_first_data(attr
));
467 zigzagline_update_data(zigzagline
);
469 return &zigzagline
->orth
.object
;