1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * Activity 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.
22 /** \file objects/UML/activity.c Implementation of the 'UML - Activity' type */
34 #include "diarenderer.h"
35 #include "attributes.h"
37 #include "properties.h"
39 #include "pixmaps/activity.xpm"
41 typedef struct _State State
;
46 ConnectionPoint connections
[8];
57 #define STATE_HEIGHT 3
58 #define STATE_LINEWIDTH 0.1
59 #define STATE_MARGIN_X 0.5
60 #define STATE_MARGIN_Y 0.5
62 static real
state_distance_from(State
*state
, Point
*point
);
63 static void state_select(State
*state
, Point
*clicked_point
,
64 DiaRenderer
*interactive_renderer
);
65 static ObjectChange
* state_move_handle(State
*state
, Handle
*handle
,
66 Point
*to
, ConnectionPoint
*cp
,
67 HandleMoveReason reason
, ModifierKeys modifiers
);
68 static ObjectChange
* state_move(State
*state
, Point
*to
);
69 static void state_draw(State
*state
, DiaRenderer
*renderer
);
70 static DiaObject
*state_create_activity(Point
*startpoint
,
74 static void state_destroy(State
*state
);
75 static DiaObject
*state_load(ObjectNode obj_node
, int version
,
76 const char *filename
);
77 static PropDescription
*state_describe_props(State
*state
);
78 static void state_get_props(State
*state
, GPtrArray
*props
);
79 static void state_set_props(State
*state
, GPtrArray
*props
);
80 static void state_update_data(State
*state
);
83 static ObjectTypeOps activity_type_ops
=
85 (CreateFunc
) state_create_activity
,
86 (LoadFunc
) state_load
,/*using_properties*/ /* load */
87 (SaveFunc
) object_save_using_properties
, /* save */
88 (GetDefaultsFunc
) NULL
,
89 (ApplyDefaultsFunc
) NULL
92 DiaObjectType activity_type
=
94 "UML - Activity", /* name */
96 (char **) activity_xpm
, /* pixmap */
98 &activity_type_ops
/* ops */
102 static ObjectOps state_ops
= {
103 (DestroyFunc
) state_destroy
,
104 (DrawFunc
) state_draw
,
105 (DistanceFunc
) state_distance_from
,
106 (SelectFunc
) state_select
,
107 (CopyFunc
) object_copy_using_properties
,
108 (MoveFunc
) state_move
,
109 (MoveHandleFunc
) state_move_handle
,
110 (GetPropertiesFunc
) object_create_props_dialog
,
111 (ApplyPropertiesFunc
) object_apply_props_from_dialog
,
112 (ObjectMenuFunc
) NULL
,
113 (DescribePropsFunc
) state_describe_props
,
114 (GetPropsFunc
) state_get_props
,
115 (SetPropsFunc
) state_set_props
119 static PropDescription activity_props
[] = {
120 ELEMENT_COMMON_PROPERTIES
,
122 PROP_STD_LINE_COLOUR_OPTIONAL
,
123 PROP_STD_FILL_COLOUR_OPTIONAL
,
125 PROP_STD_TEXT_HEIGHT
,
126 PROP_STD_TEXT_COLOUR_OPTIONAL
,
127 { "text", PROP_TYPE_TEXT
, 0, N_("Text"), NULL
, NULL
},
132 static PropDescription
*
133 state_describe_props(State
*state
)
135 if (activity_props
[0].quark
== 0) {
136 prop_desc_list_calculate_quarks(activity_props
);
138 return activity_props
;
141 static PropOffset state_offsets
[] = {
142 ELEMENT_COMMON_PROPERTIES_OFFSETS
,
143 {"line_colour",PROP_TYPE_COLOUR
,offsetof(State
,line_color
)},
144 {"fill_colour",PROP_TYPE_COLOUR
,offsetof(State
,fill_color
)},
145 {"text",PROP_TYPE_TEXT
,offsetof(State
,text
)},
146 {"text_font",PROP_TYPE_FONT
,offsetof(State
,attrs
.font
)},
147 {"text_height",PROP_TYPE_REAL
,offsetof(State
,attrs
.height
)},
148 {"text_colour",PROP_TYPE_COLOUR
,offsetof(State
,attrs
.color
)},
153 state_get_props(State
* state
, GPtrArray
*props
)
155 text_get_attributes(state
->text
,&state
->attrs
);
156 object_get_props_from_offsets(&state
->element
.object
,
157 state_offsets
,props
);
161 state_set_props(State
*state
, GPtrArray
*props
)
163 object_set_props_from_offsets(&state
->element
.object
,
164 state_offsets
,props
);
165 apply_textattr_properties(props
,state
->text
,"text",&state
->attrs
);
166 state_update_data(state
);
170 state_distance_from(State
*state
, Point
*point
)
172 DiaObject
*obj
= &state
->element
.object
;
173 return distance_rectangle_point(&obj
->bounding_box
, point
);
177 state_select(State
*state
, Point
*clicked_point
,
178 DiaRenderer
*interactive_renderer
)
180 text_set_cursor(state
->text
, clicked_point
, interactive_renderer
);
181 text_grab_focus(state
->text
, &state
->element
.object
);
182 element_update_handles(&state
->element
);
186 state_move_handle(State
*state
, Handle
*handle
,
187 Point
*to
, ConnectionPoint
*cp
,
188 HandleMoveReason reason
, ModifierKeys modifiers
)
191 assert(handle
!=NULL
);
194 assert(handle
->id
< 8);
200 state_move(State
*state
, Point
*to
)
202 state
->element
.corner
= *to
;
203 state_update_data(state
);
209 state_draw(State
*state
, DiaRenderer
*renderer
)
211 DiaRendererClass
*renderer_ops
= DIA_RENDERER_GET_CLASS (renderer
);
216 assert(state
!= NULL
);
217 assert(renderer
!= NULL
);
219 elem
= &state
->element
;
226 renderer_ops
->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
227 renderer_ops
->set_linewidth(renderer
, STATE_LINEWIDTH
);
228 renderer_ops
->set_linestyle(renderer
, LINESTYLE_SOLID
);
234 renderer_ops
->fill_rounded_rect(renderer
, &p1
, &p2
,
235 &state
->fill_color
, 1.0);
236 renderer_ops
->draw_rounded_rect(renderer
, &p1
, &p2
,
237 &state
->line_color
, 1.0);
239 text_draw(state
->text
, renderer
);
244 state_update_data(State
*state
)
248 Element
*elem
= &state
->element
;
249 DiaObject
*obj
= &elem
->object
;
252 text_calc_boundingbox(state
->text
, NULL
);
253 w
= state
->text
->max_width
+ 2*STATE_MARGIN_X
;
254 h
= state
->text
->height
*state
->text
->numlines
+2*STATE_MARGIN_Y
;
257 p
.x
= elem
->corner
.x
+ w
/2.0;
258 p
.y
= elem
->corner
.y
+ STATE_MARGIN_Y
+ state
->text
->ascent
;
259 text_set_position(state
->text
, &p
);
265 /* Update connections: */
266 state
->connections
[0].pos
= elem
->corner
;
267 state
->connections
[1].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.0;
268 state
->connections
[1].pos
.y
= elem
->corner
.y
;
269 state
->connections
[2].pos
.x
= elem
->corner
.x
+ elem
->width
;
270 state
->connections
[2].pos
.y
= elem
->corner
.y
;
271 state
->connections
[3].pos
.x
= elem
->corner
.x
;
272 state
->connections
[3].pos
.y
= elem
->corner
.y
+ elem
->height
/ 2.0;
273 state
->connections
[4].pos
.x
= elem
->corner
.x
+ elem
->width
;
274 state
->connections
[4].pos
.y
= elem
->corner
.y
+ elem
->height
/ 2.0;
275 state
->connections
[5].pos
.x
= elem
->corner
.x
;
276 state
->connections
[5].pos
.y
= elem
->corner
.y
+ elem
->height
;
277 state
->connections
[6].pos
.x
= elem
->corner
.x
+ elem
->width
/ 2.0;
278 state
->connections
[6].pos
.y
= elem
->corner
.y
+ elem
->height
;
279 state
->connections
[7].pos
.x
= elem
->corner
.x
+ elem
->width
;
280 state
->connections
[7].pos
.y
= elem
->corner
.y
+ elem
->height
;
282 state
->connections
[0].directions
= DIR_NORTH
|DIR_WEST
;
283 state
->connections
[1].directions
= DIR_NORTH
;
284 state
->connections
[2].directions
= DIR_NORTH
|DIR_EAST
;
285 state
->connections
[3].directions
= DIR_WEST
;
286 state
->connections
[4].directions
= DIR_EAST
;
287 state
->connections
[5].directions
= DIR_SOUTH
|DIR_WEST
;
288 state
->connections
[6].directions
= DIR_SOUTH
;
289 state
->connections
[7].directions
= DIR_SOUTH
|DIR_EAST
;
291 element_update_boundingbox(elem
);
293 obj
->position
= elem
->corner
;
295 element_update_handles(elem
);
300 state_create_activity(Point
*startpoint
,
312 state
= g_malloc0(sizeof(State
));
313 elem
= &state
->element
;
316 obj
->type
= &activity_type
;
317 obj
->ops
= &state_ops
;
318 elem
->corner
= *startpoint
;
319 elem
->width
= STATE_WIDTH
;
320 elem
->height
= STATE_HEIGHT
;
322 state
->line_color
= attributes_get_foreground();
323 state
->fill_color
= attributes_get_background();
325 font
= dia_font_new_from_style (DIA_FONT_SANS
, 0.8);
327 p
.x
+= STATE_WIDTH
/2.0;
328 p
.y
+= STATE_HEIGHT
/2.0;
330 state
->text
= new_text("", font
, 0.8, &p
, &color_black
, ALIGN_CENTER
);
331 text_get_attributes(state
->text
,&state
->attrs
);
332 element_init(elem
, 8, 8);
335 obj
->connections
[i
] = &state
->connections
[i
];
336 state
->connections
[i
].object
= obj
;
337 state
->connections
[i
].connected
= NULL
;
339 elem
->extra_spacing
.border_trans
= 0.0;
340 state_update_data(state
);
343 obj
->handles
[i
]->type
= HANDLE_NON_MOVABLE
;
348 return &state
->element
.object
;;
352 state_destroy(State
*state
)
354 text_destroy(state
->text
);
356 element_destroy(&state
->element
);
360 state_load(ObjectNode obj_node
, int version
, const char *filename
)
362 return object_load_using_properties(&activity_type
,
363 obj_node
,version
,filename
);