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