2006-12-03 Dimitris Glezos <dimitris@glezos.com>
[dia.git] / objects / UML / large_package.c
blob466905e0e0556cfa053ac7e603cfe7b57cf61807
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.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <assert.h>
24 #include <math.h>
25 #include <string.h>
27 #include "intl.h"
28 #include "object.h"
29 #include "element.h"
30 #include "diarenderer.h"
31 #include "attributes.h"
32 #include "text.h"
33 #include "properties.h"
35 #include "uml.h"
36 #include "stereotype.h"
38 #include "pixmaps/largepackage.xpm"
40 typedef struct _LargePackage LargePackage;
42 #define NUM_CONNECTIONS 9
44 struct _LargePackage {
45 Element element;
47 ConnectionPoint connections[NUM_CONNECTIONS];
49 char *name;
50 char *stereotype; /* Can be NULL, including << and >> */
51 char *st_stereotype;
53 DiaFont *font;
55 Color text_color;
56 Color line_color;
57 Color fill_color;
59 real topwidth;
60 real topheight;
63 #define LARGEPACKAGE_BORDERWIDTH 0.1
64 #define LARGEPACKAGE_FONTHEIGHT 0.8
66 static real largepackage_distance_from(LargePackage *pkg, Point *point);
67 static void largepackage_select(LargePackage *pkg, Point *clicked_point,
68 DiaRenderer *interactive_renderer);
69 static ObjectChange* largepackage_move_handle(LargePackage *pkg, Handle *handle,
70 Point *to, ConnectionPoint *cp,
71 HandleMoveReason reason, ModifierKeys modifiers);
72 static ObjectChange* largepackage_move(LargePackage *pkg, Point *to);
73 static void largepackage_draw(LargePackage *pkg, DiaRenderer *renderer);
74 static DiaObject *largepackage_create(Point *startpoint,
75 void *user_data,
76 Handle **handle1,
77 Handle **handle2);
78 static void largepackage_destroy(LargePackage *pkg);
80 static void largepackage_update_data(LargePackage *pkg);
82 static PropDescription *largepackage_describe_props(LargePackage *largepackage);
83 static void largepackage_get_props(LargePackage *largepackage, GPtrArray *props);
84 static void largepackage_set_props(LargePackage *largepackage, GPtrArray *props);
85 static DiaObject *largepackage_load(ObjectNode obj_node, int version,
86 const char *filename);
88 static ObjectTypeOps largepackage_type_ops =
90 (CreateFunc) largepackage_create,
91 (LoadFunc) largepackage_load,/*using_properties*/ /* load */
92 (SaveFunc) object_save_using_properties, /* save */
93 (GetDefaultsFunc) NULL,
94 (ApplyDefaultsFunc) NULL
97 DiaObjectType largepackage_type =
99 "UML - LargePackage", /* name */
100 0, /* version */
101 (char **) largepackage_xpm, /* pixmap */
103 &largepackage_type_ops /* ops */
106 static ObjectOps largepackage_ops = {
107 (DestroyFunc) largepackage_destroy,
108 (DrawFunc) largepackage_draw,
109 (DistanceFunc) largepackage_distance_from,
110 (SelectFunc) largepackage_select,
111 (CopyFunc) object_copy_using_properties,
112 (MoveFunc) largepackage_move,
113 (MoveHandleFunc) largepackage_move_handle,
114 (GetPropertiesFunc) object_create_props_dialog,
115 (ApplyPropertiesFunc) object_apply_props_from_dialog,
116 (ObjectMenuFunc) NULL,
117 (DescribePropsFunc) largepackage_describe_props,
118 (GetPropsFunc) largepackage_get_props,
119 (SetPropsFunc) largepackage_set_props
122 static PropDescription largepackage_props[] = {
123 ELEMENT_COMMON_PROPERTIES,
124 PROP_STD_LINE_COLOUR_OPTIONAL,
125 PROP_STD_FILL_COLOUR_OPTIONAL,
126 /* can't use PROP_STD_TEXT_COLOUR_OPTIONAL cause it has PROP_FLAG_DONT_SAVE. It is designed to fill the Text object - not some subset */
127 PROP_STD_TEXT_COLOUR_OPTIONS(PROP_FLAG_VISIBLE|PROP_FLAG_STANDARD|PROP_FLAG_OPTIONAL),
128 { "stereotype", PROP_TYPE_STRING, PROP_FLAG_VISIBLE,
129 N_("Stereotype"), NULL, NULL },
130 { "name", PROP_TYPE_STRING, PROP_FLAG_VISIBLE,
131 N_("Name"), NULL, NULL },
132 PROP_DESC_END
135 static PropDescription *
136 largepackage_describe_props(LargePackage *largepackage)
138 if (largepackage_props[0].quark == 0) {
139 prop_desc_list_calculate_quarks(largepackage_props);
141 return largepackage_props;
144 static PropOffset largepackage_offsets[] = {
145 ELEMENT_COMMON_PROPERTIES_OFFSETS,
146 {"line_colour",PROP_TYPE_COLOUR,offsetof(LargePackage,line_color)},
147 {"fill_colour",PROP_TYPE_COLOUR,offsetof(LargePackage,fill_color)},
148 {"text_colour",PROP_TYPE_COLOUR,offsetof(LargePackage,text_color)},
149 {"stereotype", PROP_TYPE_STRING, offsetof(LargePackage , stereotype) },
150 {"name", PROP_TYPE_STRING, offsetof(LargePackage , name) },
152 { NULL, 0, 0 },
155 static void
156 largepackage_get_props(LargePackage * largepackage, GPtrArray *props)
158 object_get_props_from_offsets(&largepackage->element.object,
159 largepackage_offsets, props);
162 static void
163 largepackage_set_props(LargePackage *largepackage, GPtrArray *props)
165 object_set_props_from_offsets(&largepackage->element.object,
166 largepackage_offsets, props);
167 g_free(largepackage->st_stereotype);
168 largepackage->st_stereotype = NULL;
169 largepackage_update_data(largepackage);
172 static real
173 largepackage_distance_from(LargePackage *pkg, Point *point)
175 DiaObject *obj = &pkg->element.object;
176 return distance_rectangle_point(&obj->bounding_box, point);
179 static void
180 largepackage_select(LargePackage *pkg, Point *clicked_point,
181 DiaRenderer *interactive_renderer)
183 element_update_handles(&pkg->element);
186 static ObjectChange*
187 largepackage_move_handle(LargePackage *pkg, Handle *handle,
188 Point *to, ConnectionPoint *cp,
189 HandleMoveReason reason, ModifierKeys modifiers)
191 assert(pkg!=NULL);
192 assert(handle!=NULL);
193 assert(to!=NULL);
195 assert(handle->id < 8);
197 element_move_handle(&pkg->element, handle->id, to, cp, reason, modifiers);
198 largepackage_update_data(pkg);
200 return NULL;
203 static ObjectChange*
204 largepackage_move(LargePackage *pkg, Point *to)
206 pkg->element.corner = *to;
208 largepackage_update_data(pkg);
210 return NULL;
213 static void
214 largepackage_draw(LargePackage *pkg, DiaRenderer *renderer)
216 DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
217 Element *elem;
218 real x, y, w, h;
219 Point p1, p2;
221 assert(pkg != NULL);
222 assert(renderer != NULL);
224 elem = &pkg->element;
226 x = elem->corner.x;
227 y = elem->corner.y;
228 w = elem->width;
229 h = elem->height;
231 renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
232 renderer_ops->set_linewidth(renderer, LARGEPACKAGE_BORDERWIDTH);
233 renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
236 p1.x = x; p1.y = y;
237 p2.x = x+w; p2.y = y+h;
239 renderer_ops->fill_rect(renderer,
240 &p1, &p2,
241 &pkg->fill_color);
242 renderer_ops->draw_rect(renderer,
243 &p1, &p2,
244 &pkg->line_color);
246 p1.x= x; p1.y = y - pkg->topheight;
247 p2.x = x + pkg->topwidth; p2.y = y;
249 renderer_ops->fill_rect(renderer,
250 &p1, &p2,
251 &pkg->fill_color);
253 renderer_ops->draw_rect(renderer,
254 &p1, &p2,
255 &pkg->line_color);
258 renderer_ops->set_font(renderer, pkg->font, LARGEPACKAGE_FONTHEIGHT);
260 p1.x = x + 0.1;
261 p1.y = y - LARGEPACKAGE_FONTHEIGHT -
262 dia_font_descent(pkg->st_stereotype,
263 pkg->font, LARGEPACKAGE_FONTHEIGHT) - 0.1;
267 if (pkg->st_stereotype && pkg->st_stereotype[0] != '\0') {
268 renderer_ops->draw_string(renderer, pkg->st_stereotype, &p1,
269 ALIGN_LEFT, &pkg->text_color);
271 p1.y += LARGEPACKAGE_FONTHEIGHT;
273 if (pkg->name)
274 renderer_ops->draw_string(renderer, pkg->name, &p1,
275 ALIGN_LEFT, &pkg->text_color);
278 static void
279 largepackage_update_data(LargePackage *pkg)
281 Element *elem = &pkg->element;
282 DiaObject *obj = &elem->object;
284 pkg->stereotype = remove_stereotype_from_string(pkg->stereotype);
285 if (!pkg->st_stereotype) {
286 pkg->st_stereotype = string_to_stereotype(pkg->stereotype);
289 pkg->topheight = LARGEPACKAGE_FONTHEIGHT + 0.1*2;
291 pkg->topwidth = 2.0;
292 if (pkg->name != NULL)
293 pkg->topwidth = MAX(pkg->topwidth,
294 dia_font_string_width(pkg->name, pkg->font,
295 LARGEPACKAGE_FONTHEIGHT)+2*0.1);
296 if (pkg->st_stereotype != NULL && pkg->st_stereotype[0] != '\0') {
297 pkg->topwidth = MAX(pkg->topwidth,
298 dia_font_string_width(pkg->st_stereotype, pkg->font,
299 LARGEPACKAGE_FONTHEIGHT)+2*0.1);
300 pkg->topheight += LARGEPACKAGE_FONTHEIGHT;
303 if (elem->width < (pkg->topwidth + 0.2))
304 elem->width = pkg->topwidth + 0.2;
305 if (elem->height < 1.0)
306 elem->height = 1.0;
308 /* Update connections: */
309 element_update_connections_rectangle(elem, pkg->connections);
311 element_update_boundingbox(elem);
312 /* fix boundingbox for top rectangle: */
313 obj->bounding_box.top -= pkg->topheight;
315 obj->position = elem->corner;
317 element_update_handles(elem);
320 static DiaObject *
321 largepackage_create(Point *startpoint,
322 void *user_data,
323 Handle **handle1,
324 Handle **handle2)
326 LargePackage *pkg;
327 Element *elem;
328 DiaObject *obj;
329 int i;
331 pkg = g_malloc0(sizeof(LargePackage));
332 elem = &pkg->element;
333 obj = &elem->object;
335 obj->type = &largepackage_type;
337 obj->ops = &largepackage_ops;
339 obj->flags |= DIA_OBJECT_CAN_PARENT;
341 elem->corner = *startpoint;
343 element_init(elem, 8, NUM_CONNECTIONS);
345 elem->width = 4.0;
346 elem->height = 4.0;
348 pkg->text_color = color_black;
349 pkg->line_color = attributes_get_foreground();
350 pkg->fill_color = attributes_get_background();
351 pkg->font = dia_font_new_from_style(DIA_FONT_MONOSPACE,
352 LARGEPACKAGE_FONTHEIGHT);
354 pkg->stereotype = NULL;
355 pkg->st_stereotype = NULL;
356 pkg->name = g_strdup("");
358 pkg->topwidth = 2.0;
359 pkg->topheight = LARGEPACKAGE_FONTHEIGHT*2 + 0.1*2;
361 for (i=0;i<NUM_CONNECTIONS;i++) {
362 obj->connections[i] = &pkg->connections[i];
363 pkg->connections[i].object = obj;
364 pkg->connections[i].connected = NULL;
366 pkg->connections[8].flags = CP_FLAGS_MAIN;
367 pkg->element.extra_spacing.border_trans = LARGEPACKAGE_BORDERWIDTH/2.0;
368 largepackage_update_data(pkg);
370 *handle1 = NULL;
371 *handle2 = obj->handles[7];
372 return &pkg->element.object;
375 static void
376 largepackage_destroy(LargePackage *pkg)
378 dia_font_unref(pkg->font);
379 g_free(pkg->stereotype);
380 g_free(pkg->st_stereotype);
381 g_free(pkg->name);
383 element_destroy(&pkg->element);
386 static DiaObject *
387 largepackage_load(ObjectNode obj_node, int version, const char *filename)
389 return object_load_using_properties(&largepackage_type,
390 obj_node,version,filename);