1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * Fork type for UML diagrams
5 * Copyright (C) 2002 Alejandro Sierra <asierra@servidor.unam.mx>
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/fork.xpm"
42 typedef struct _Fork Fork
;
47 ConnectionPoint connections
[8];
50 static const double FORK_BORDERWIDTH
= 0.0;
51 static const double FORK_WIDTH
= 4.0;
52 static const double FORK_HEIGHT
= 0.4;
53 static const double FORK_MARGIN
= 0.125;
55 static real
fork_distance_from(Fork
*branch
, Point
*point
);
56 static void fork_select(Fork
*branch
, Point
*clicked_point
, DiaRenderer
*interactive_renderer
);
57 static ObjectChange
* fork_move_handle(Fork
*branch
, Handle
*handle
,
58 Point
*to
, ConnectionPoint
*cp
,
59 HandleMoveReason reason
, ModifierKeys modifiers
);
60 static ObjectChange
* fork_move(Fork
*branch
, Point
*to
);
61 static void fork_draw(Fork
*branch
, DiaRenderer
*renderer
);
62 static DiaObject
*fork_create(Point
*startpoint
,
66 static void fork_destroy(Fork
*branch
);
67 static DiaObject
*fork_load(ObjectNode obj_node
, int version
,
68 const char *filename
);
70 static PropDescription
*fork_describe_props(Fork
*branch
);
71 static void fork_get_props(Fork
*branch
, GPtrArray
*props
);
72 static void fork_set_props(Fork
*branch
, GPtrArray
*props
);
74 static void fork_update_data(Fork
*branch
);
76 static ObjectTypeOps fork_type_ops
=
78 (CreateFunc
) fork_create
,
79 (LoadFunc
) fork_load
,/*using_properties*/ /* load */
80 (SaveFunc
) object_save_using_properties
, /* save */
81 (GetDefaultsFunc
) NULL
,
82 (ApplyDefaultsFunc
) NULL
85 DiaObjectType fork_type
=
87 "UML - Fork", /* name */
89 (char **) fork_xpm
, /* pixmap */
91 &fork_type_ops
/* ops */
94 static ObjectOps fork_ops
=
96 (DestroyFunc
) fork_destroy
,
98 (DistanceFunc
) fork_distance_from
,
99 (SelectFunc
) fork_select
,
100 (CopyFunc
) object_copy_using_properties
,
101 (MoveFunc
) fork_move
,
102 (MoveHandleFunc
) fork_move_handle
,
103 (GetPropertiesFunc
) object_return_null
,
104 (ApplyPropertiesFunc
) object_return_void
,
105 (ObjectMenuFunc
) NULL
,
106 (DescribePropsFunc
) fork_describe_props
,
107 (GetPropsFunc
) fork_get_props
,
108 (SetPropsFunc
) fork_set_props
111 static PropDescription fork_props
[] = {
112 ELEMENT_COMMON_PROPERTIES
,
117 static PropDescription
*
118 fork_describe_props(Fork
*branch
)
120 if (fork_props
[0].quark
== 0) {
121 prop_desc_list_calculate_quarks(fork_props
);
126 static PropOffset fork_offsets
[] = {
127 ELEMENT_COMMON_PROPERTIES_OFFSETS
,
132 fork_get_props(Fork
* branch
, GPtrArray
*props
)
134 object_get_props_from_offsets(&branch
->element
.object
,
135 fork_offsets
, props
);
139 fork_set_props(Fork
*branch
, GPtrArray
*props
)
141 object_set_props_from_offsets(&branch
->element
.object
,
142 fork_offsets
, props
);
143 fork_update_data(branch
);
147 fork_distance_from(Fork
*branch
, Point
*point
)
149 DiaObject
*obj
= &branch
->element
.object
;
150 return distance_rectangle_point(&obj
->bounding_box
, point
);
154 fork_select(Fork
*branch
, Point
*clicked_point
, DiaRenderer
*interactive_renderer
)
156 element_update_handles(&branch
->element
);
160 fork_move_handle(Fork
*branch
, Handle
*handle
,
161 Point
*to
, ConnectionPoint
*cp
,
162 HandleMoveReason reason
, ModifierKeys modifiers
)
167 assert(branch
!=NULL
);
168 assert(handle
!=NULL
);
171 assert(handle
->id
< 8);
173 /* Only orizontal E/W movement are allowed */
174 if (handle
->id
==3 || handle
->id
==4) {
176 c
.x
= branch
->element
.corner
.x
+ branch
->element
.width
/ 2.;
177 dx
= fabs(to
->x
- c
.x
);
179 element_move_handle(&branch
->element
, 3, to
, cp
, reason
, modifiers
);
181 element_move_handle(&branch
->element
, 4, to
, cp
, reason
, modifiers
);
182 fork_update_data(branch
);
189 fork_move(Fork
*branch
, Point
*to
)
191 branch
->element
.corner
= *to
;
192 fork_update_data(branch
);
197 static void fork_draw(Fork
*branch
, DiaRenderer
*renderer
)
199 DiaRendererClass
*renderer_ops
= DIA_RENDERER_GET_CLASS (renderer
);
204 assert(branch
!= NULL
);
205 assert(renderer
!= NULL
);
207 elem
= &branch
->element
;
211 renderer_ops
->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
212 renderer_ops
->set_linewidth(renderer
, FORK_BORDERWIDTH
);
213 renderer_ops
->set_linestyle(renderer
, LINESTYLE_SOLID
);
215 p1
.x
= elem
->corner
.x
;
216 p1
.y
= elem
->corner
.y
;
217 p2
.x
= elem
->corner
.x
+ w
;
218 p2
.y
= elem
->corner
.y
+ h
;
220 renderer_ops
->fill_rect(renderer
,
225 static void fork_update_data(Fork
*branch
)
227 Element
*elem
= &branch
->element
;
228 DiaObject
*obj
= &elem
->object
;
230 /* Update connections: */
231 branch
->connections
[0].pos
.x
= elem
->corner
.x
+ FORK_MARGIN
*elem
->width
;
232 branch
->connections
[0].pos
.y
= elem
->corner
.y
;
233 branch
->connections
[1].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.;
234 branch
->connections
[1].pos
.y
= elem
->corner
.y
;
235 branch
->connections
[2].pos
.x
= elem
->corner
.x
+ elem
->width
- FORK_MARGIN
*elem
->width
;
236 branch
->connections
[2].pos
.y
= elem
->corner
.y
;
237 branch
->connections
[3].pos
.x
= elem
->corner
.x
+ FORK_MARGIN
*elem
->width
;
238 branch
->connections
[3].pos
.y
= elem
->corner
.y
+ elem
->height
;
239 branch
->connections
[4].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.;
240 branch
->connections
[4].pos
.y
= elem
->corner
.y
+ elem
->height
;
241 branch
->connections
[5].pos
.x
= elem
->corner
.x
+ elem
->width
- FORK_MARGIN
*elem
->width
;
242 branch
->connections
[5].pos
.y
= elem
->corner
.y
+ elem
->height
;
244 element_update_boundingbox(elem
);
245 obj
->position
= elem
->corner
;
247 element_update_handles(elem
);
250 static DiaObject
*fork_create(Point
*startpoint
, void *user_data
, Handle
**handle1
, Handle
**handle2
)
257 branch
= g_malloc0(sizeof(Fork
));
258 elem
= &branch
->element
;
261 obj
->type
= &fork_type
;
263 obj
->ops
= &fork_ops
;
265 elem
->corner
= *startpoint
;
266 elem
->width
= FORK_WIDTH
;
267 elem
->height
= FORK_HEIGHT
;
268 element_init(elem
, 8, 8);
272 obj
->connections
[i
] = &branch
->connections
[i
];
273 branch
->connections
[i
].object
= obj
;
274 branch
->connections
[i
].connected
= NULL
;
276 elem
->extra_spacing
.border_trans
= FORK_BORDERWIDTH
/ 2.0;
277 fork_update_data(branch
);
281 obj
->handles
[i
]->type
= HANDLE_NON_MOVABLE
;
285 *handle2
= obj
->handles
[0];
286 return &branch
->element
.object
;
289 static void fork_destroy(Fork
*branch
)
291 element_destroy(&branch
->element
);
294 static DiaObject
*fork_load(ObjectNode obj_node
, int version
, const char *filename
)
296 return object_load_using_properties(&fork_type
,
297 obj_node
,version
,filename
);