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.
30 #include "diarenderer.h"
31 #include "attributes.h"
33 #include "properties.h"
36 #include "stereotype.h"
38 #include "pixmaps/largepackage.xpm"
40 typedef struct _LargePackage LargePackage
;
42 #define NUM_CONNECTIONS 9
44 struct _LargePackage
{
47 ConnectionPoint connections
[NUM_CONNECTIONS
];
50 char *stereotype
; /* Can be NULL, including << and >> */
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
,
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 */
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
},
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
) },
156 largepackage_get_props(LargePackage
* largepackage
, GPtrArray
*props
)
158 object_get_props_from_offsets(&largepackage
->element
.object
,
159 largepackage_offsets
, props
);
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
);
173 largepackage_distance_from(LargePackage
*pkg
, Point
*point
)
175 DiaObject
*obj
= &pkg
->element
.object
;
176 return distance_rectangle_point(&obj
->bounding_box
, point
);
180 largepackage_select(LargePackage
*pkg
, Point
*clicked_point
,
181 DiaRenderer
*interactive_renderer
)
183 element_update_handles(&pkg
->element
);
187 largepackage_move_handle(LargePackage
*pkg
, Handle
*handle
,
188 Point
*to
, ConnectionPoint
*cp
,
189 HandleMoveReason reason
, ModifierKeys modifiers
)
192 assert(handle
!=NULL
);
195 assert(handle
->id
< 8);
197 element_move_handle(&pkg
->element
, handle
->id
, to
, cp
, reason
, modifiers
);
198 largepackage_update_data(pkg
);
204 largepackage_move(LargePackage
*pkg
, Point
*to
)
206 pkg
->element
.corner
= *to
;
208 largepackage_update_data(pkg
);
214 largepackage_draw(LargePackage
*pkg
, DiaRenderer
*renderer
)
216 DiaRendererClass
*renderer_ops
= DIA_RENDERER_GET_CLASS (renderer
);
222 assert(renderer
!= NULL
);
224 elem
= &pkg
->element
;
231 renderer_ops
->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
232 renderer_ops
->set_linewidth(renderer
, LARGEPACKAGE_BORDERWIDTH
);
233 renderer_ops
->set_linestyle(renderer
, LINESTYLE_SOLID
);
237 p2
.x
= x
+w
; p2
.y
= y
+h
;
239 renderer_ops
->fill_rect(renderer
,
242 renderer_ops
->draw_rect(renderer
,
246 p1
.x
= x
; p1
.y
= y
- pkg
->topheight
;
247 p2
.x
= x
+ pkg
->topwidth
; p2
.y
= y
;
249 renderer_ops
->fill_rect(renderer
,
253 renderer_ops
->draw_rect(renderer
,
258 renderer_ops
->set_font(renderer
, pkg
->font
, LARGEPACKAGE_FONTHEIGHT
);
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
;
274 renderer_ops
->draw_string(renderer
, pkg
->name
, &p1
,
275 ALIGN_LEFT
, &pkg
->text_color
);
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;
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)
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
);
321 largepackage_create(Point
*startpoint
,
331 pkg
= g_malloc0(sizeof(LargePackage
));
332 elem
= &pkg
->element
;
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
);
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("");
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
);
371 *handle2
= obj
->handles
[7];
372 return &pkg
->element
.object
;
376 largepackage_destroy(LargePackage
*pkg
)
378 dia_font_unref(pkg
->font
);
379 g_free(pkg
->stereotype
);
380 g_free(pkg
->st_stereotype
);
383 element_destroy(&pkg
->element
);
387 largepackage_load(ObjectNode obj_node
, int version
, const char *filename
)
389 return object_load_using_properties(&largepackage_type
,
390 obj_node
,version
,filename
);