1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * node type for UML diagrams
5 * Copyright (C) 2000 Stefan Seefeld <stefan@berlin-consortium.org>
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.
33 #include "diarenderer.h"
34 #include "attributes.h"
36 #include "properties.h"
40 #include "pixmaps/branch.xpm"
42 typedef struct _Branch Branch
;
47 ConnectionPoint connections
[8];
52 static const double BRANCH_BORDERWIDTH
= 0.1;
53 static const double BRANCH_WIDTH
= 2.0;
54 static const double BRANCH_HEIGHT
= 2.0;
56 static real
branch_distance_from(Branch
*branch
, Point
*point
);
57 static void branch_select(Branch
*branch
, Point
*clicked_point
, DiaRenderer
*interactive_renderer
);
58 static ObjectChange
* branch_move_handle(Branch
*branch
, Handle
*handle
,
59 Point
*to
, ConnectionPoint
*cp
,
60 HandleMoveReason reason
, ModifierKeys modifiers
);
61 static ObjectChange
* branch_move(Branch
*branch
, Point
*to
);
62 static void branch_draw(Branch
*branch
, DiaRenderer
*renderer
);
63 static DiaObject
*branch_create(Point
*startpoint
,
67 static void branch_destroy(Branch
*branch
);
68 static DiaObject
*branch_load(ObjectNode obj_node
, int version
,
69 const char *filename
);
71 static PropDescription
*branch_describe_props(Branch
*branch
);
72 static void branch_get_props(Branch
*branch
, GPtrArray
*props
);
73 static void branch_set_props(Branch
*branch
, GPtrArray
*props
);
75 static void branch_update_data(Branch
*branch
);
77 static ObjectTypeOps branch_type_ops
=
79 (CreateFunc
) branch_create
,
80 (LoadFunc
) branch_load
,/*using_properties*/ /* load */
81 (SaveFunc
) object_save_using_properties
, /* save */
82 (GetDefaultsFunc
) NULL
,
83 (ApplyDefaultsFunc
) NULL
86 DiaObjectType branch_type
=
88 "UML - Branch", /* name */
90 (char **) branch_xpm
, /* pixmap */
92 &branch_type_ops
/* ops */
95 static ObjectOps branch_ops
=
97 (DestroyFunc
) branch_destroy
,
98 (DrawFunc
) branch_draw
,
99 (DistanceFunc
) branch_distance_from
,
100 (SelectFunc
) branch_select
,
101 (CopyFunc
) object_copy_using_properties
,
102 (MoveFunc
) branch_move
,
103 (MoveHandleFunc
) branch_move_handle
,
104 (GetPropertiesFunc
) object_create_props_dialog
,
105 (ApplyPropertiesFunc
) object_apply_props_from_dialog
,
106 (ObjectMenuFunc
) NULL
,
107 (DescribePropsFunc
) branch_describe_props
,
108 (GetPropsFunc
) branch_get_props
,
109 (SetPropsFunc
) branch_set_props
112 static PropDescription branch_props
[] = {
113 ELEMENT_COMMON_PROPERTIES
,
114 PROP_STD_LINE_COLOUR_OPTIONAL
,
115 PROP_STD_FILL_COLOUR_OPTIONAL
,
120 static PropDescription
*
121 branch_describe_props(Branch
*branch
)
123 if (branch_props
[0].quark
== 0) {
124 prop_desc_list_calculate_quarks(branch_props
);
129 static PropOffset branch_offsets
[] = {
130 ELEMENT_COMMON_PROPERTIES_OFFSETS
,
131 {"line_colour",PROP_TYPE_COLOUR
,offsetof(Branch
,line_color
)},
132 {"fill_colour",PROP_TYPE_COLOUR
,offsetof(Branch
,fill_color
)},
137 branch_get_props(Branch
* branch
, GPtrArray
*props
)
139 object_get_props_from_offsets(&branch
->element
.object
,
140 branch_offsets
, props
);
144 branch_set_props(Branch
*branch
, GPtrArray
*props
)
146 object_set_props_from_offsets(&branch
->element
.object
,
147 branch_offsets
, props
);
148 branch_update_data(branch
);
152 branch_distance_from(Branch
*branch
, Point
*point
)
154 DiaObject
*obj
= &branch
->element
.object
;
155 return distance_rectangle_point(&obj
->bounding_box
, point
);
159 branch_select(Branch
*branch
, Point
*clicked_point
, DiaRenderer
*interactive_renderer
)
161 element_update_handles(&branch
->element
);
165 branch_move_handle(Branch
*branch
, Handle
*handle
,
166 Point
*to
, ConnectionPoint
*cp
,
167 HandleMoveReason reason
, ModifierKeys modifiers
)
169 assert(branch
!=NULL
);
170 assert(handle
!=NULL
);
173 assert(handle
->id
< 8);
175 /* It smashes size info in update_data anyway. And none of its siblings
176 * resizable, so until that changes, this should be properly unresizable
180 element_move_handle(&branch->element, handle->id, to, cp, reason, modifiers);
181 branch_update_data(branch);
188 branch_move(Branch
*branch
, Point
*to
)
190 branch
->element
.corner
= *to
;
191 branch_update_data(branch
);
196 static void branch_draw(Branch
*branch
, DiaRenderer
*renderer
)
198 DiaRendererClass
*renderer_ops
= DIA_RENDERER_GET_CLASS (renderer
);
203 assert(branch
!= NULL
);
204 assert(renderer
!= NULL
);
206 elem
= &branch
->element
;
209 points
[0].x
= elem
->corner
.x
, points
[0].y
= elem
->corner
.y
+ h
;
210 points
[1].x
= elem
->corner
.x
+ w
, points
[1].y
= elem
->corner
.y
;
211 points
[2].x
= elem
->corner
.x
+ 2*w
, points
[2].y
= elem
->corner
.y
+ h
;
212 points
[3].x
= elem
->corner
.x
+ w
, points
[3].y
= elem
->corner
.y
+ 2*h
;
214 renderer_ops
->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
215 renderer_ops
->set_linewidth(renderer
, BRANCH_BORDERWIDTH
);
216 renderer_ops
->set_linestyle(renderer
, LINESTYLE_SOLID
);
218 renderer_ops
->fill_polygon(renderer
, points
, 4, &branch
->fill_color
);
219 renderer_ops
->draw_polygon(renderer
, points
, 4, &branch
->line_color
);
222 static void branch_update_data(Branch
*branch
)
224 Element
*elem
= &branch
->element
;
225 DiaObject
*obj
= &elem
->object
;
227 elem
->width
= BRANCH_WIDTH
;
228 elem
->height
= BRANCH_HEIGHT
;
230 /* Update connections: */
231 branch
->connections
[0].pos
.x
= elem
->corner
.x
;
232 branch
->connections
[0].pos
.y
= elem
->corner
.y
+ elem
->height
/ 2.;
233 branch
->connections
[0].directions
= DIR_WEST
;
234 branch
->connections
[1].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.;
235 branch
->connections
[1].pos
.y
= elem
->corner
.y
;
236 branch
->connections
[1].directions
= DIR_NORTH
;
237 branch
->connections
[2].pos
.x
= elem
->corner
.x
+ elem
->width
;
238 branch
->connections
[2].pos
.y
= elem
->corner
.y
+ elem
->height
/ 2.;
239 branch
->connections
[2].directions
= DIR_EAST
;
240 branch
->connections
[3].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.;;
241 branch
->connections
[3].pos
.y
= elem
->corner
.y
+ elem
->height
;
242 branch
->connections
[3].directions
= DIR_SOUTH
;
244 element_update_boundingbox(elem
);
245 obj
->position
= elem
->corner
;
247 element_update_handles(elem
);
250 static DiaObject
*branch_create(Point
*startpoint
, void *user_data
, Handle
**handle1
, Handle
**handle2
)
257 branch
= g_malloc0(sizeof(Branch
));
258 elem
= &branch
->element
;
261 obj
->type
= &branch_type
;
263 obj
->ops
= &branch_ops
;
265 elem
->corner
= *startpoint
;
266 element_init(elem
, 8, 8);
268 branch
->line_color
= attributes_get_foreground();
269 branch
->fill_color
= attributes_get_background();
273 obj
->connections
[i
] = &branch
->connections
[i
];
274 branch
->connections
[i
].object
= obj
;
275 branch
->connections
[i
].connected
= NULL
;
277 elem
->extra_spacing
.border_trans
= BRANCH_BORDERWIDTH
/ 2.0;
278 branch_update_data(branch
);
281 obj
->handles
[i
]->type
= HANDLE_NON_MOVABLE
;
286 return &branch
->element
.object
;
289 static void branch_destroy(Branch
*branch
)
291 element_destroy(&branch
->element
);
294 static DiaObject
*branch_load(ObjectNode obj_node
, int version
, const char *filename
)
296 return object_load_using_properties(&branch_type
,
297 obj_node
,version
,filename
);