1 /* AADL plugin for DIA
2 *
3 * Copyright (C) 2005 Laboratoire d'Informatique de Paris 6
4 * Author: Pierre Duquesne
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21
22 #include "aadl.h"
23 #include "pixmaps/aadlbus.xpm"
24
25 /***********************************************
26 ** AADL BUS **
27 ***********************************************/
28
aadlbus_draw_borders(Aadlbox * aadlbox,DiaRenderer * renderer)29 static void aadlbus_draw_borders(Aadlbox *aadlbox, DiaRenderer *renderer)
30 {
31 DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
32 Element *elem;
33 real x, y, w, h;
34 Point points[10];
35
36 assert(aadlbox != NULL);
37 assert(renderer != NULL);
38
39 elem = &aadlbox->element;
40
41 x = elem->corner.x;
42 y = elem->corner.y;
43 w = elem->width;
44 h = elem->height;
45
46 points[0].x = x;
47 points[0].y = y + h*0.5;
48
49 points[1].x = x + w*AADL_BUS_ARROW_SIZE_FACTOR;
50 points[1].y = y;
51
52 points[2].x = x + w*AADL_BUS_ARROW_SIZE_FACTOR;
53 points[2].y = y + h*AADL_BUS_HEIGHT_FACTOR;
54
55 points[3].x = x + w - w*AADL_BUS_ARROW_SIZE_FACTOR;
56 points[3].y = y + h*AADL_BUS_HEIGHT_FACTOR;
57
58 points[4].x = x + w - w*AADL_BUS_ARROW_SIZE_FACTOR;
59 points[4].y = y;
60
61 points[5].x = x + w;
62 points[5].y = y + h*0.5;
63
64 points[6].x = x + w - w*AADL_BUS_ARROW_SIZE_FACTOR;
65 points[6].y = y + h ;
66
67 points[7].x = x + w - w*AADL_BUS_ARROW_SIZE_FACTOR;
68 points[7].y = y + h*(1-AADL_BUS_HEIGHT_FACTOR);
69
70 points[8].x = x + w*AADL_BUS_ARROW_SIZE_FACTOR;
71 points[8].y = y + h*(1-AADL_BUS_HEIGHT_FACTOR);
72
73 points[9].x = x + w*AADL_BUS_ARROW_SIZE_FACTOR;
74 points[9].y = y + h;
75
76
77 renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
78 renderer_ops->set_linewidth(renderer, AADLBOX_BORDERWIDTH);
79 renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
80
81 renderer_ops->fill_polygon(renderer, points, 10, &aadlbox->fill_color);
82 renderer_ops->draw_polygon(renderer, points, 10, &aadlbox->line_color);
83 }
84
aadlbus_draw(Aadlbox * aadlbox,DiaRenderer * renderer)85 static void aadlbus_draw(Aadlbox *aadlbox, DiaRenderer *renderer)
86 {
87 aadlbus_draw_borders(aadlbox, renderer);
88 aadlbox_draw(aadlbox, renderer);
89 }
90
91 void
aadlbus_project_point_on_nearest_border(Aadlbox * aadlbox,Point * p,real * angle)92 aadlbus_project_point_on_nearest_border(Aadlbox *aadlbox,Point *p,
93 real *angle)
94 {
95 Element *element = &aadlbox->element;
96
97 real w = element->width;
98 real h = element->height;
99
100 /* top left corner */
101 coord x1 = element->corner.x;
102 coord y1 = element->corner.y;
103
104 /* bottom right corner */
105 coord x2 = element->corner.x + w;
106 coord y2 = element->corner.y + h;
107
108
109 if ( p->x >= x1 + w*AADL_BUS_ARROW_SIZE_FACTOR
110 && p->x <= x2 - w*AADL_BUS_ARROW_SIZE_FACTOR)
111 {
112 Rectangle rectangle;
113
114 rectangle.left = x1 + w*AADL_BUS_ARROW_SIZE_FACTOR;
115 rectangle.top = y1 + h*AADL_BUS_HEIGHT_FACTOR;
116 rectangle.right = x2 - w*AADL_BUS_ARROW_SIZE_FACTOR;
117 rectangle.bottom = y2 - h*AADL_BUS_HEIGHT_FACTOR;
118
119 aadlbox_project_point_on_rectangle(&rectangle, p, angle);
120 }
121 else
122 {
123 Point a, b, c, m;
124 real k1, k2;
125
126 /* left arrow */
127 if (p->x < x1 + w*AADL_BUS_ARROW_SIZE_FACTOR) {
128
129 *angle = M_PI;
130
131 /* m b
132 � /|
133 / |
134 / |
135 a---c
136 */
137
138 a.x = x1;
139 a.y = y1 + h*0.5;
140
141 b.x = x1 + w*AADL_BUS_ARROW_SIZE_FACTOR;
142 b.y = (p->y<y1+0.5*h)?y1:y2; /* up or down */
143
144 c.x = b.x;
145 c.y = a.y;
146 }
147
148 /* right arrow */
149 else {
150
151 *angle = 0;
152
153 a.x = x2;
154 a.y = y1 + h*0.5;
155
156 b.x = x2 - w*AADL_BUS_ARROW_SIZE_FACTOR;
157 b.y = (p->y<y1+0.5*h)?y1:y2; /* up or down */
158
159 c.x = b.x;
160 c.y = a.y;
161 }
162
163 point_copy(&m, p);
164
165 /* intersection between (AB) and (MC) */
166
167 k1 = (b.y - a.y) / (b.x - a.x);
168 k2 = (m.y - c.y) / (m.x - c.x);
169
170 p->x = (m.y - a.y + k1*a.x - k2*m.x) / (k1 - k2);
171 p->y = a.y + k1 * (p->x - a.x);
172 }
173 }
174
175
176
177
178 static Aadlbox_specific aadlbus_specific =
179 {
180 (AadlProjectionFunc) aadlbus_project_point_on_nearest_border,
181 (AadlTextPosFunc) aadlbus_text_position,
182 (AadlSizeFunc) aadlbus_minsize
183 };
184
185 extern ObjectTypeOps aadlbus_type_ops;
186
187 DiaObjectType aadlbus_type =
188 {
189 "AADL - Bus", /* name */
190 0, /* version */
191 (char **) aadlbus_xpm, /* pixmap */
192
193 &aadlbus_type_ops, /* ops */
194 NULL,
195 &aadlbus_specific /* user data */
196 };
197
198 static ObjectOps aadlbus_ops =
199 {
200 (DestroyFunc) aadlbox_destroy,
201 (DrawFunc) aadlbus_draw, /* redefined */
202 (DistanceFunc) aadlbox_distance_from,
203 (SelectFunc) aadlbox_select,
204 (CopyFunc) aadlbox_copy,
205 (MoveFunc) aadlbox_move,
206 (MoveHandleFunc) aadlbox_move_handle,
207 (GetPropertiesFunc) object_create_props_dialog,
208 (ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
209 (ObjectMenuFunc) aadlbox_get_object_menu,
210 (DescribePropsFunc) aadlbox_describe_props,
211 (GetPropsFunc) aadlbox_get_props,
212 (SetPropsFunc) aadlbox_set_props,
213 (TextEditFunc) 0,
214 (ApplyPropertiesListFunc) object_apply_props,
215 };
216
217
218
aadlbus_create(Point * startpoint,void * user_data,Handle ** handle1,Handle ** handle2)219 static DiaObject *aadlbus_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2)
220 {
221 DiaObject *obj = aadlbox_create(startpoint, user_data, handle1, handle2);
222
223 obj->type = &aadlbus_type;
224 obj->ops = &aadlbus_ops;
225
226 return obj;
227 }
228
aadlbus_load(ObjectNode obj_node,int version,const char * filename)229 static DiaObject *aadlbus_load(ObjectNode obj_node, int version, const char *filename)
230 {
231 DiaObject *obj;
232 Point startpoint = {0.0,0.0};
233 Handle *handle1,*handle2;
234
235 obj = aadlbus_create(&startpoint,&aadlbus_specific, &handle1,&handle2);
236 aadlbox_load(obj_node, version, filename, (Aadlbox *) obj);
237 return obj;
238 }
239
240
241 ObjectTypeOps aadlbus_type_ops =
242 {
243 (CreateFunc) aadlbus_create,
244 (LoadFunc) aadlbus_load,/*using_properties*/ /* load */
245 (SaveFunc) aadlbox_save, /* save */
246 (GetDefaultsFunc) NULL,
247 (ApplyDefaultsFunc) NULL
248 };
249