1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * Flowchart toolbox -- objects for drawing flowcharts.
5 * Copyright (C) 1999 James Henstridge.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /* DO NOT USE THIS OBJECT AS A BASIS FOR A NEW OBJECT. */
34 #include "connectionpoint.h"
35 #include "diarenderer.h"
36 #include "attributes.h"
40 #include "properties.h"
42 #include "pixmaps/box.xpm"
44 #define DEFAULT_WIDTH 2.0
45 #define DEFAULT_HEIGHT 1.0
46 #define DEFAULT_BORDER 0.25
48 #define NUM_CONNECTIONS 17
56 typedef struct _Box Box
;
61 ConnectionPoint connections
[NUM_CONNECTIONS
];
65 gboolean show_background
;
75 typedef struct _BoxProperties
{
76 gboolean show_background
;
81 static BoxProperties default_properties
;
83 static real
box_distance_from(Box
*box
, Point
*point
);
84 static void box_select(Box
*box
, Point
*clicked_point
,
85 DiaRenderer
*interactive_renderer
);
86 static ObjectChange
* box_move_handle(Box
*box
, Handle
*handle
,
87 Point
*to
, ConnectionPoint
*cp
,
88 HandleMoveReason reason
,
89 ModifierKeys modifiers
);
90 static ObjectChange
* box_move(Box
*box
, Point
*to
);
91 static void box_draw(Box
*box
, DiaRenderer
*renderer
);
92 static void box_update_data(Box
*box
, AnchorShape horix
, AnchorShape vert
);
93 static DiaObject
*box_create(Point
*startpoint
,
97 static void box_destroy(Box
*box
);
98 static PropDescription
*box_describe_props(Box
*box
);
99 static void box_get_props(Box
*box
, GPtrArray
*props
);
100 static void box_set_props(Box
*box
, GPtrArray
*props
);
102 static void box_save(Box
*box
, ObjectNode obj_node
, const char *filename
);
103 static DiaObject
*box_load(ObjectNode obj_node
, int version
, const char *filename
);
105 static ObjectTypeOps box_type_ops
=
107 (CreateFunc
) box_create
,
110 (GetDefaultsFunc
) NULL
,
111 (ApplyDefaultsFunc
) NULL
114 DiaObjectType fc_box_type
=
116 "Flowchart - Box", /* name */
118 (char **) box_xpm
, /* pixmap */
120 &box_type_ops
/* ops */
123 static ObjectOps box_ops
= {
124 (DestroyFunc
) box_destroy
,
126 (DistanceFunc
) box_distance_from
,
127 (SelectFunc
) box_select
,
128 (CopyFunc
) object_copy_using_properties
,
130 (MoveHandleFunc
) box_move_handle
,
131 (GetPropertiesFunc
) object_create_props_dialog
,
132 (ApplyPropertiesFunc
) object_apply_props_from_dialog
,
133 (ObjectMenuFunc
) NULL
,
134 (DescribePropsFunc
) box_describe_props
,
135 (GetPropsFunc
) box_get_props
,
136 (SetPropsFunc
) box_set_props
,
139 static PropNumData corner_radius_data
= { 0.0, 10.0, 0.1 };
140 static PropNumData text_padding_data
= { 0.0, 10.0, 0.1 };
142 static PropDescription box_props
[] = {
143 ELEMENT_COMMON_PROPERTIES
,
145 PROP_STD_LINE_COLOUR
,
146 PROP_STD_FILL_COLOUR
,
147 PROP_STD_SHOW_BACKGROUND
,
149 { "corner_radius", PROP_TYPE_REAL
, PROP_FLAG_VISIBLE
,
150 N_("Corner radius"), NULL
, &corner_radius_data
},
151 { "padding", PROP_TYPE_REAL
, PROP_FLAG_VISIBLE
,
152 N_("Text padding"), NULL
, &text_padding_data
},
154 PROP_STD_TEXT_HEIGHT
,
155 PROP_STD_TEXT_COLOUR
,
156 PROP_STD_TEXT_ALIGNMENT
,
159 { NULL
, 0, 0, NULL
, NULL
, NULL
, 0}
162 static PropDescription
*
163 box_describe_props(Box
*box
)
165 if (box_props
[0].quark
== 0)
166 prop_desc_list_calculate_quarks(box_props
);
170 static PropOffset box_offsets
[] = {
171 ELEMENT_COMMON_PROPERTIES_OFFSETS
,
172 { "line_width", PROP_TYPE_REAL
, offsetof(Box
, border_width
) },
173 { "line_colour", PROP_TYPE_COLOUR
, offsetof(Box
, border_color
) },
174 { "fill_colour", PROP_TYPE_COLOUR
, offsetof(Box
, inner_color
) },
175 { "show_background", PROP_TYPE_BOOL
, offsetof(Box
, show_background
) },
176 { "line_style", PROP_TYPE_LINESTYLE
,
177 offsetof(Box
, line_style
), offsetof(Box
, dashlength
) },
178 { "corner_radius", PROP_TYPE_REAL
, offsetof(Box
, corner_radius
) },
179 { "padding", PROP_TYPE_REAL
, offsetof(Box
, padding
) },
180 {"text",PROP_TYPE_TEXT
,offsetof(Box
,text
)},
181 {"text_font",PROP_TYPE_FONT
,offsetof(Box
,attrs
.font
)},
182 {"text_height",PROP_TYPE_REAL
,offsetof(Box
,attrs
.height
)},
183 {"text_colour",PROP_TYPE_COLOUR
,offsetof(Box
,attrs
.color
)},
184 {"text_alignment",PROP_TYPE_ENUM
,offsetof(Box
,attrs
.alignment
)},
189 box_get_props(Box
*box
, GPtrArray
*props
)
191 text_get_attributes(box
->text
,&box
->attrs
);
192 object_get_props_from_offsets(&box
->element
.object
,
197 box_set_props(Box
*box
, GPtrArray
*props
)
199 object_set_props_from_offsets(&box
->element
.object
,
201 apply_textattr_properties(props
,box
->text
,"text",&box
->attrs
);
202 box_update_data(box
, ANCHOR_MIDDLE
, ANCHOR_MIDDLE
);
206 init_default_values() {
207 static int defaults_initialized
= 0;
209 if (!defaults_initialized
) {
210 default_properties
.show_background
= 1;
211 default_properties
.padding
= 0.5;
212 defaults_initialized
= 1;
217 box_distance_from(Box
*box
, Point
*point
)
219 Element
*elem
= &box
->element
;
222 rect
.left
= elem
->corner
.x
- box
->border_width
/2;
223 rect
.right
= elem
->corner
.x
+ elem
->width
+ box
->border_width
/2;
224 rect
.top
= elem
->corner
.y
- box
->border_width
/2;
225 rect
.bottom
= elem
->corner
.y
+ elem
->height
+ box
->border_width
/2;
226 return distance_rectangle_point(&rect
, point
);
230 box_select(Box
*box
, Point
*clicked_point
,
231 DiaRenderer
*interactive_renderer
)
235 text_set_cursor(box
->text
, clicked_point
, interactive_renderer
);
236 text_grab_focus(box
->text
, &box
->element
.object
);
238 element_update_handles(&box
->element
);
240 if (box
->corner_radius
> 0) {
241 Element
*elem
= (Element
*)box
;
242 radius
= box
->corner_radius
;
243 radius
= MIN(radius
, elem
->width
/2);
244 radius
= MIN(radius
, elem
->height
/2);
245 radius
*= (1-M_SQRT1_2
);
247 elem
->resize_handles
[0].pos
.x
+= radius
;
248 elem
->resize_handles
[0].pos
.y
+= radius
;
249 elem
->resize_handles
[2].pos
.x
-= radius
;
250 elem
->resize_handles
[2].pos
.y
+= radius
;
251 elem
->resize_handles
[5].pos
.x
+= radius
;
252 elem
->resize_handles
[5].pos
.y
-= radius
;
253 elem
->resize_handles
[7].pos
.x
-= radius
;
254 elem
->resize_handles
[7].pos
.y
-= radius
;
259 box_move_handle(Box
*box
, Handle
*handle
,
260 Point
*to
, ConnectionPoint
*cp
,
261 HandleMoveReason reason
, ModifierKeys modifiers
)
263 AnchorShape horiz
= ANCHOR_MIDDLE
, vert
= ANCHOR_MIDDLE
;
266 assert(handle
!=NULL
);
269 element_move_handle(&box
->element
, handle
->id
, to
, cp
, reason
, modifiers
);
271 switch (handle
->id
) {
272 case HANDLE_RESIZE_NW
:
273 horiz
= ANCHOR_END
; vert
= ANCHOR_END
; break;
274 case HANDLE_RESIZE_N
:
275 vert
= ANCHOR_END
; break;
276 case HANDLE_RESIZE_NE
:
277 horiz
= ANCHOR_START
; vert
= ANCHOR_END
; break;
278 case HANDLE_RESIZE_E
:
279 horiz
= ANCHOR_START
; break;
280 case HANDLE_RESIZE_SE
:
281 horiz
= ANCHOR_START
; vert
= ANCHOR_START
; break;
282 case HANDLE_RESIZE_S
:
283 vert
= ANCHOR_START
; break;
284 case HANDLE_RESIZE_SW
:
285 horiz
= ANCHOR_END
; vert
= ANCHOR_START
; break;
286 case HANDLE_RESIZE_W
:
287 horiz
= ANCHOR_END
; break;
291 box_update_data(box
, horiz
, vert
);
297 box_move(Box
*box
, Point
*to
)
299 box
->element
.corner
= *to
;
301 box_update_data(box
, ANCHOR_MIDDLE
, ANCHOR_MIDDLE
);
307 box_draw(Box
*box
, DiaRenderer
*renderer
)
309 DiaRendererClass
*renderer_ops
= DIA_RENDERER_GET_CLASS (renderer
);
315 assert(renderer
!= NULL
);
316 elem
= &box
->element
;
318 lr_corner
.x
= elem
->corner
.x
+ elem
->width
;
319 lr_corner
.y
= elem
->corner
.y
+ elem
->height
;
321 if (box
->show_background
) {
322 renderer_ops
->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
324 /* Problem: How do we make the fill with rounded corners? */
325 if (box
->corner_radius
> 0) {
326 Point start
, end
, center
;
328 radius
= box
->corner_radius
;
329 radius
= MIN(radius
, elem
->width
/2);
330 radius
= MIN(radius
, elem
->height
/2);
331 start
.x
= center
.x
= elem
->corner
.x
+radius
;
332 end
.x
= lr_corner
.x
-radius
;
333 start
.y
= elem
->corner
.y
;
335 renderer_ops
->fill_rect(renderer
, &start
, &end
, &box
->inner_color
);
337 center
.y
= elem
->corner
.y
+radius
;
338 renderer_ops
->fill_arc(renderer
, ¢er
,
339 2.0*radius
, 2.0*radius
,
340 90.0, 180.0, &box
->inner_color
);
342 renderer_ops
->fill_arc(renderer
, ¢er
,
343 2.0*radius
, 2.0*radius
,
344 0.0, 90.0, &box
->inner_color
);
346 start
.x
= elem
->corner
.x
;
347 start
.y
= elem
->corner
.y
+radius
;
349 end
.y
= center
.y
= lr_corner
.y
-radius
;
350 renderer_ops
->fill_rect(renderer
, &start
, &end
, &box
->inner_color
);
352 center
.y
= lr_corner
.y
-radius
;
353 center
.x
= elem
->corner
.x
+radius
;
354 renderer_ops
->fill_arc(renderer
, ¢er
,
355 2.0*radius
, 2.0*radius
,
356 180.0, 270.0, &box
->inner_color
);
357 center
.x
= lr_corner
.x
-radius
;
358 renderer_ops
->fill_arc(renderer
, ¢er
,
359 2.0*radius
, 2.0*radius
,
360 270.0, 360.0, &box
->inner_color
);
362 renderer_ops
->fill_rect(renderer
,
369 renderer_ops
->set_linewidth(renderer
, box
->border_width
);
370 renderer_ops
->set_linestyle(renderer
, box
->line_style
);
371 renderer_ops
->set_dashlength(renderer
, box
->dashlength
);
372 renderer_ops
->set_linejoin(renderer
, LINEJOIN_MITER
);
374 if (box
->corner_radius
> 0) {
375 Point start
, end
, center
;
377 radius
= box
->corner_radius
;
378 radius
= MIN(radius
, elem
->width
/2);
379 radius
= MIN(radius
, elem
->height
/2);
380 start
.x
= center
.x
= elem
->corner
.x
+radius
;
381 end
.x
= lr_corner
.x
-radius
;
382 start
.y
= end
.y
= elem
->corner
.y
;
383 renderer_ops
->draw_line(renderer
, &start
, &end
, &box
->border_color
);
384 start
.y
= end
.y
= lr_corner
.y
;
385 renderer_ops
->draw_line(renderer
, &start
, &end
, &box
->border_color
);
387 center
.y
= elem
->corner
.y
+radius
;
388 renderer_ops
->draw_arc(renderer
, ¢er
,
389 2.0*radius
, 2.0*radius
,
390 90.0, 180.0, &box
->border_color
);
392 renderer_ops
->draw_arc(renderer
, ¢er
,
393 2.0*radius
, 2.0*radius
,
394 0.0, 90.0, &box
->border_color
);
396 start
.y
= elem
->corner
.y
+radius
;
397 start
.x
= end
.x
= elem
->corner
.x
;
398 end
.y
= center
.y
= lr_corner
.y
-radius
;
399 renderer_ops
->draw_line(renderer
, &start
, &end
, &box
->border_color
);
400 start
.x
= end
.x
= lr_corner
.x
;
401 renderer_ops
->draw_line(renderer
, &start
, &end
, &box
->border_color
);
403 center
.y
= lr_corner
.y
-radius
;
404 center
.x
= elem
->corner
.x
+radius
;
405 renderer_ops
->draw_arc(renderer
, ¢er
,
406 2.0*radius
, 2.0*radius
,
407 180.0, 270.0, &box
->border_color
);
408 center
.x
= lr_corner
.x
-radius
;
409 renderer_ops
->draw_arc(renderer
, ¢er
,
410 2.0*radius
, 2.0*radius
,
411 270.0, 360.0, &box
->border_color
);
413 renderer_ops
->draw_rect(renderer
,
418 text_draw(box
->text
, renderer
);
422 box_update_data(Box
*box
, AnchorShape horiz
, AnchorShape vert
)
424 Element
*elem
= &box
->element
;
425 ElementBBExtras
*extra
= &elem
->extra_spacing
;
426 DiaObject
*obj
= &elem
->object
;
427 Point center
, bottom_right
;
432 /* save starting points */
433 center
= bottom_right
= elem
->corner
;
434 center
.x
+= elem
->width
/2;
435 bottom_right
.x
+= elem
->width
;
436 center
.y
+= elem
->height
/2;
437 bottom_right
.y
+= elem
->height
;
439 text_calc_boundingbox(box
->text
, NULL
);
440 width
= box
->text
->max_width
+ box
->padding
*2 + box
->border_width
;
441 height
= box
->text
->height
* box
->text
->numlines
+ box
->padding
*2 +
445 * If elem->width (e.g. the new requested dimensions of this object
446 * from move_handle()) is smaller than the minimum width (i.e. the
447 * width calculated from text-width, padding and border), then
448 * set the width to the minimum. Else, keep the width.
450 if (width
> elem
->width
) elem
->width
= width
;
451 if (height
> elem
->height
) elem
->height
= height
;
453 /* move shape if necessary ... */
456 elem
->corner
.x
= center
.x
- elem
->width
/2; break;
458 elem
->corner
.x
= bottom_right
.x
- elem
->width
; break;
464 elem
->corner
.y
= center
.y
- elem
->height
/2; break;
466 elem
->corner
.y
= bottom_right
.y
- elem
->height
; break;
472 p
.x
+= elem
->width
/ 2.0;
473 p
.y
+= elem
->height
/ 2.0 - box
->text
->height
* box
->text
->numlines
/ 2 +
475 switch (box
->text
->alignment
) {
477 p
.x
-= (elem
->width
- box
->padding
*2 + box
->border_width
)/2;
480 p
.x
+= (elem
->width
- box
->padding
*2 + box
->border_width
)/2;
486 text_set_position(box
->text
, &p
);
488 radius
= box
->corner_radius
;
489 radius
= MIN(radius
, elem
->width
/2);
490 radius
= MIN(radius
, elem
->height
/2);
491 radius
*= (1-M_SQRT1_2
);
493 /* Update connections: */
494 connpoint_update(&box
->connections
[0],
495 elem
->corner
.x
+ radius
,
496 elem
->corner
.y
+ radius
,
498 connpoint_update(&box
->connections
[1],
499 elem
->corner
.x
+ elem
->width
/ 4.0,
502 connpoint_update(&box
->connections
[2],
503 elem
->corner
.x
+ elem
->width
/ 2.0,
506 connpoint_update(&box
->connections
[3],
507 elem
->corner
.x
+ elem
->width
* 3.0 / 4.0,
510 connpoint_update(&box
->connections
[4],
511 elem
->corner
.x
+ elem
->width
- radius
,
512 elem
->corner
.y
+ radius
,
514 connpoint_update(&box
->connections
[5],
516 elem
->corner
.y
+ elem
->height
/ 4.0,
518 connpoint_update(&box
->connections
[6],
519 elem
->corner
.x
+ elem
->width
,
520 elem
->corner
.y
+ elem
->height
/ 4.0,
522 connpoint_update(&box
->connections
[7],
524 elem
->corner
.y
+ elem
->height
/ 2.0,
526 connpoint_update(&box
->connections
[8],
527 elem
->corner
.x
+ elem
->width
,
528 elem
->corner
.y
+ elem
->height
/ 2.0,
530 connpoint_update(&box
->connections
[9],
532 elem
->corner
.y
+ elem
->height
* 3.0 / 4.0,
534 connpoint_update(&box
->connections
[10],
535 elem
->corner
.x
+ elem
->width
,
536 elem
->corner
.y
+ elem
->height
* 3.0 / 4.0,
538 connpoint_update(&box
->connections
[11],
539 elem
->corner
.x
+ radius
,
540 elem
->corner
.y
+ elem
->height
- radius
,
542 connpoint_update(&box
->connections
[12],
543 elem
->corner
.x
+ elem
->width
/ 4.0,
544 elem
->corner
.y
+ elem
->height
,
546 connpoint_update(&box
->connections
[13],
547 elem
->corner
.x
+ elem
->width
/ 2.0,
548 elem
->corner
.y
+ elem
->height
,
550 connpoint_update(&box
->connections
[14],
551 elem
->corner
.x
+ elem
->width
* 3.0 / 4.0,
552 elem
->corner
.y
+ elem
->height
,
554 connpoint_update(&box
->connections
[15],
555 elem
->corner
.x
+ elem
->width
- radius
,
556 elem
->corner
.y
+ elem
->height
- radius
,
558 connpoint_update(&box
->connections
[16],
559 elem
->corner
.x
+ elem
->width
/ 2,
560 elem
->corner
.y
+ elem
->height
/ 2,
563 extra
->border_trans
= box
->border_width
/ 2.0;
564 element_update_boundingbox(elem
);
566 obj
->position
= elem
->corner
;
568 element_update_handles(elem
);
571 /* Fix the handles, too */
572 elem
->resize_handles
[0].pos
.x
+= radius
;
573 elem
->resize_handles
[0].pos
.y
+= radius
;
574 elem
->resize_handles
[2].pos
.x
-= radius
;
575 elem
->resize_handles
[2].pos
.y
+= radius
;
576 elem
->resize_handles
[5].pos
.x
+= radius
;
577 elem
->resize_handles
[5].pos
.y
-= radius
;
578 elem
->resize_handles
[7].pos
.x
-= radius
;
579 elem
->resize_handles
[7].pos
.y
-= radius
;
584 box_create(Point
*startpoint
,
594 DiaFont
*font
= NULL
;
597 init_default_values();
599 box
= g_malloc0(sizeof(Box
));
600 elem
= &box
->element
;
603 obj
->type
= &fc_box_type
;
607 elem
->corner
= *startpoint
;
608 elem
->width
= DEFAULT_WIDTH
;
609 elem
->height
= DEFAULT_HEIGHT
;
611 box
->border_width
= attributes_get_default_linewidth();
612 box
->border_color
= attributes_get_foreground();
613 box
->inner_color
= attributes_get_background();
614 box
->show_background
= default_properties
.show_background
;
615 attributes_get_default_line_style(&box
->line_style
, &box
->dashlength
);
616 box
->corner_radius
= default_properties
.corner_radius
;
618 box
->padding
= default_properties
.padding
;
620 attributes_get_default_font(&font
, &font_height
);
622 p
.x
+= elem
->width
/ 2.0;
623 p
.y
+= elem
->height
/ 2.0 + font_height
/ 2;
624 box
->text
= new_text("", font
, font_height
, &p
, &box
->border_color
,
626 text_get_attributes(box
->text
,&box
->attrs
);
627 dia_font_unref(font
);
629 element_init(elem
, 8, NUM_CONNECTIONS
);
631 for (i
=0;i
<NUM_CONNECTIONS
;i
++) {
632 obj
->connections
[i
] = &box
->connections
[i
];
633 box
->connections
[i
].object
= obj
;
634 box
->connections
[i
].connected
= NULL
;
635 box
->connections
[i
].flags
= 0;
637 box
->connections
[16].flags
= CP_FLAGS_MAIN
;
639 box_update_data(box
, ANCHOR_MIDDLE
, ANCHOR_MIDDLE
);
642 *handle2
= obj
->handles
[7];
643 return &box
->element
.object
;
647 box_destroy(Box
*box
)
649 text_destroy(box
->text
);
651 element_destroy(&box
->element
);
655 box_save(Box
*box
, ObjectNode obj_node
, const char *filename
)
657 element_save(&box
->element
, obj_node
);
659 if (box
->border_width
!= 0.1)
660 data_add_real(new_attribute(obj_node
, "border_width"),
663 if (!color_equals(&box
->border_color
, &color_black
))
664 data_add_color(new_attribute(obj_node
, "border_color"),
667 if (!color_equals(&box
->inner_color
, &color_white
))
668 data_add_color(new_attribute(obj_node
, "inner_color"),
671 data_add_boolean(new_attribute(obj_node
, "show_background"),
672 box
->show_background
);
674 if (box
->line_style
!= LINESTYLE_SOLID
)
675 data_add_enum(new_attribute(obj_node
, "line_style"),
678 if (box
->line_style
!= LINESTYLE_SOLID
&&
679 box
->dashlength
!= DEFAULT_LINESTYLE_DASHLEN
)
680 data_add_real(new_attribute(obj_node
, "dashlength"),
682 if (box
->corner_radius
> 0.0)
683 data_add_real(new_attribute(obj_node
, "corner_radius"),
686 data_add_real(new_attribute(obj_node
, "padding"), box
->padding
);
688 data_add_text(new_attribute(obj_node
, "text"), box
->text
);
692 box_load(ObjectNode obj_node
, int version
, const char *filename
)
700 box
= g_malloc0(sizeof(Box
));
701 elem
= &box
->element
;
704 obj
->type
= &fc_box_type
;
707 element_load(elem
, obj_node
);
709 box
->border_width
= 0.1;
710 attr
= object_find_attribute(obj_node
, "border_width");
712 box
->border_width
= data_real( attribute_first_data(attr
) );
713 box
->border_color
= color_black
;
714 attr
= object_find_attribute(obj_node
, "border_color");
716 data_color(attribute_first_data(attr
), &box
->border_color
);
718 box
->inner_color
= color_white
;
719 attr
= object_find_attribute(obj_node
, "inner_color");
721 data_color(attribute_first_data(attr
), &box
->inner_color
);
723 box
->show_background
= TRUE
;
724 attr
= object_find_attribute(obj_node
, "show_background");
726 box
->show_background
= data_boolean( attribute_first_data(attr
) );
728 box
->line_style
= LINESTYLE_SOLID
;
729 attr
= object_find_attribute(obj_node
, "line_style");
731 box
->line_style
= data_enum( attribute_first_data(attr
) );
733 box
->dashlength
= DEFAULT_LINESTYLE_DASHLEN
;
734 attr
= object_find_attribute(obj_node
, "dashlength");
736 box
->dashlength
= data_real(attribute_first_data(attr
));
738 box
->corner_radius
= 0.0;
739 attr
= object_find_attribute(obj_node
, "corner_radius");
741 box
->corner_radius
= data_real( attribute_first_data(attr
) );
743 box
->padding
= default_properties
.padding
;
744 attr
= object_find_attribute(obj_node
, "padding");
746 box
->padding
= data_real( attribute_first_data(attr
) );
750 attr
= object_find_attribute(obj_node
, "text");
752 box
->text
= data_text(attribute_first_data(attr
));
754 element_init(elem
, 8, NUM_CONNECTIONS
);
756 for (i
=0;i
<NUM_CONNECTIONS
;i
++) {
757 obj
->connections
[i
] = &box
->connections
[i
];
758 box
->connections
[i
].object
= obj
;
759 box
->connections
[i
].connected
= NULL
;
760 box
->connections
[i
].flags
= 0;
762 box
->connections
[16].flags
= CP_FLAGS_MAIN
;
764 box_update_data(box
, ANCHOR_MIDDLE
, ANCHOR_MIDDLE
);
766 return &box
->element
.object
;