]> AND Private Git Repository - blast.git/blob - AbstractBoxItem.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
9fafc8fbc4b5b7dea39e0675b5c20913af3fdd0e
[blast.git] / AbstractBoxItem.cpp
1 #include "AbstractBoxItem.h"
2
3 #include "Parameters.h"
4
5 #include "Dispatcher.h"
6 #include "InterfaceItem.h"
7 #include "ConnectionItem.h"
8
9 #include "AbstractBlock.h"
10 #include "GroupScene.h"
11 #include "GroupItem.h"
12 #include "AbstractInterface.h"
13 #include "ConnectedInterface.h"
14
15
16 AbstractBoxItem::  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem *parent) : QGraphicsItem(parent) {
17   dispatcher = _dispatcher;
18   params = _params;
19   refBlock = _refBlock;  
20   lock = _lock;
21   QFontMetrics fmId(params->defaultBlockFont);
22   nameWidth = fmId.width(refBlock->getName());
23   nameHeight = fmId.height();
24   nameMargin = 5;
25   ifaceMargin = 10;
26
27   // the six following values will be override in subclass constructors
28   minimumBoxWidth = 0;
29   minimumBoxHeight = 0;
30   boxWidth = 0;
31   boxHeight = 0;
32   totalWidth = 0;
33   totalHeight = 0;
34
35   originPoint = QPointF(0.0,0.0);
36
37   selected = false;
38   currentInterface = NULL;
39   rstClkVisible = false;
40   wishboneVisible = false;
41
42   setAcceptHoverEvents(true);
43
44   // NOTE : initInterfaces() is only called in subclasses
45 }
46
47 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem* parent) : QGraphicsItem(parent) {
48   dispatcher = _dispatcher;
49   params = _params;  
50   refBlock = NULL;
51   lock = _lock;
52   nameWidth = 0;
53   nameHeight = 0;
54   nameMargin = 10;
55   ifaceMargin = 10;
56
57   // the six following values will be override in subclass constructors
58   minimumBoxWidth = 0;
59   minimumBoxHeight = 0;
60   boxWidth = 0;
61   boxHeight = 0;
62   totalWidth = 0;
63   totalHeight = 0;
64
65   originPoint = QPointF(0.0,0.0);
66
67   selected = false;
68   currentInterface = NULL;
69   rstClkVisible = false;
70   wishboneVisible = false;
71   
72   setAcceptHoverEvents(true);
73
74   // NOTE : initInterfaces() is only called in subclasses
75 }
76
77 AbstractBoxItem::~AbstractBoxItem() {
78   foreach(InterfaceItem* inter, interfaces) {
79     delete inter;
80   }
81   interfaces.clear();
82 }
83
84 bool AbstractBoxItem::isBoxItem() {
85   return false;
86 }
87
88 bool AbstractBoxItem::isGroupItem() {
89   return false;
90 }
91
92 bool AbstractBoxItem::isSourceItem() {
93   return false;
94 }
95
96 void AbstractBoxItem::setRstClkVisible(bool b) { 
97   rstClkVisible = b;
98   foreach(InterfaceItem* ifaceItem, interfaces) {
99     if ((ifaceItem->refInter->getPurpose() == AbstractInterface::Clock) ||
100         (ifaceItem->refInter->getPurpose() == AbstractInterface::Reset) ) {
101       ifaceItem->visible = b;
102     }
103   }
104   resetInterfaceItemsPosition();
105   updateGeometry(InterfaceMove);
106   update();
107   getScene()->updateConnectionItemsShape();
108   (getScene()->getGroupItem())->updateShape();
109   
110 }
111
112 void AbstractBoxItem::setWishboneVisible(bool b) { 
113   wishboneVisible = b;
114   foreach(InterfaceItem* ifaceItem, interfaces) {
115     if (ifaceItem->refInter->getPurpose() == AbstractInterface::Wishbone) {
116       ifaceItem->visible = b;
117     }
118   }
119   resetInterfaceItemsPosition();
120   updateGeometry(InterfaceMove);
121   update();
122   getScene()->updateConnectionItemsShape();
123   (getScene()->getGroupItem())->updateShape();
124 }
125
126 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
127   refBlock = _refBlock;
128   QFontMetrics fmId(params->defaultBlockFont);
129   nameWidth = fmId.width(refBlock->getName());
130   nameHeight = fmId.height();
131 }
132
133 void AbstractBoxItem::initInterfaceItems() {
134   /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
135   int orientation = Parameters::West;
136
137   foreach(AbstractInterface *inter, refBlock->getInterfaces()){
138    
139     /* NB: does not create InterfaceItem for control interfaces.
140     */
141     if (inter->getPurpose() != AbstractInterface::Control) {
142       InterfaceItem *item;
143       if(inter->getDirection() == AbstractInterface::Input){
144         orientation = Parameters::West;
145       } else if(inter->getDirection() == AbstractInterface::Output){
146         orientation = Parameters::East;
147       } else if(inter->getDirection() == AbstractInterface::InOut){
148         orientation = Parameters::North;
149       }
150       item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
151       interfaces.append(item);        
152     }
153   }
154 }
155
156 InterfaceItem* AbstractBoxItem::searchInterfaceItemByName(QString name) {
157   foreach(InterfaceItem *inter, interfaces){
158     if(inter->getName() == name)
159       return inter;
160   }
161   return NULL;
162 }
163
164 InterfaceItem* AbstractBoxItem::searchInterfaceItemByRef(ConnectedInterface *ref) {
165   foreach(InterfaceItem *inter, interfaces){
166     if(inter->refInter == ref) {
167       return inter;
168     }
169   }
170   return NULL;
171 }
172
173 void AbstractBoxItem::addInterfaceItem(InterfaceItem *i, bool resetPosition) {
174   interfaces.append(i);
175   if (resetPosition) resetInterfaceItemsPosition();
176   updateGeometry(InterfaceMove);
177   update();
178 }
179
180 void AbstractBoxItem::removeInterfaceItem(InterfaceItem *i) {
181   // NB : removing from model is done in dispatcher
182   interfaces.removeAll(i);
183   delete i;
184
185   //resetInterfacesPosition();
186   updateGeometry(InterfaceMove);
187   update();
188 }
189
190
191 void AbstractBoxItem::resetInterfaceItemsPosition() {
192
193   int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
194   double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
195   double positionRatio = 1.0;
196
197
198   foreach(InterfaceItem* inter, interfaces) {
199     // only data interfaces and if needed time and reset
200     if(inter->visible) {
201       if(inter->getOrientation() == Parameters::North){
202         nbNorth++;
203       } else if(inter->getOrientation() == Parameters::South){
204         nbSouth++;
205       } else if(inter->getOrientation() == Parameters::East){
206         nbEast++;
207       } else if(inter->getOrientation() == Parameters::West){
208         nbWest++;
209       }
210     }
211   }
212
213   foreach(InterfaceItem* inter, interfaces) {
214
215     if(inter->visible){
216
217       if(inter->getOrientation() == Parameters::North){
218         positionRatio = cntNorth/(double)(nbNorth+1);
219         cntNorth += 1.0;
220       } else if(inter->getOrientation() == Parameters::South){
221         positionRatio = cntSouth/(double)(nbSouth+1);
222         cntSouth += 1.0;
223       } else if(inter->getOrientation() == Parameters::East){
224         positionRatio = cntEast/(double)(nbEast+1);
225         cntEast += 1.0;
226       } else if(inter->getOrientation() == Parameters::West){
227         positionRatio = cntWest/(double)(nbWest+1);
228         cntWest += 1.0;
229       }
230       inter->setPositionRatio(positionRatio);
231       inter->updatePosition();
232     }
233   }
234 }
235
236 void AbstractBoxItem::moveInterfaceItemTo(QPointF pos) {
237   double positionRatio;
238   if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
239     if(pos.x() < 0){
240       positionRatio = 0;
241       if(pos.y() > 0 && pos.y() < boxHeight){
242         currentInterface->setOrientation(Parameters::West);
243       }
244     } else if(pos.x() > boxWidth){
245       positionRatio = 1;
246       if(pos.y() > 0 && pos.y() < boxHeight){
247         currentInterface->setOrientation(Parameters::East);
248       }
249     } else {
250       positionRatio = ((double) pos.x())/boxWidth;
251     }
252   } else {
253
254     if(pos.y() < 0){
255       positionRatio = 0;
256       if(pos.x() > 0 && pos.x() < boxWidth){
257         currentInterface->setOrientation(Parameters::North);
258       }
259     } else if(pos.y() > boxHeight){
260       positionRatio = 1;
261       if(pos.x() > 0 && pos.x() < boxWidth){
262         currentInterface->setOrientation(Parameters::South);
263       }
264     } else {
265       positionRatio = ((double) pos.y())/boxHeight;
266     }
267   }
268   currentInterface->setPositionRatio(positionRatio);
269   currentInterface->updatePosition();
270 }
271
272 QRectF AbstractBoxItem::boundingRect() const {
273   // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
274   QPointF p = originPoint;
275   QSizeF s(totalWidth,totalHeight);
276   return QRectF(p,s);
277 }
278
279 QRectF AbstractBoxItem::boundingRectInScene() {
280   /* returns a QRectF in scene coordinates, that contains the block plus
281      a margin of size arrowWidth+arrowLineLength
282   */
283   int marginConn = params->arrowLineLength+params->arrowWidth;  
284   
285   QPointF posBox = scenePos();
286   posBox.setX(posBox.x()+originPoint.x()-marginConn);
287   posBox.setY(posBox.y()+originPoint.y()-marginConn);
288   
289   QSizeF sizeBox(totalWidth+2*marginConn,totalHeight+2*marginConn);     
290   
291   return QRectF(posBox,sizeBox);
292 }
293
294
295 /* isInterface() : return true if there are some interfaces
296    with the given orientation (N,S,E,O)
297 */
298 bool AbstractBoxItem::isInterfaces(int orientation) const {
299   foreach(InterfaceItem* inter, interfaces) {
300     if (inter->getOrientation() == orientation) return true;
301   }
302   return false;
303 }
304
305 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
306   int nb = 0;
307   foreach(InterfaceItem* inter, interfaces) {
308     if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
309   }
310   return nb;
311 }
312
313 void AbstractBoxItem::updateInterfaceAndConnectionItems() {
314
315   // update all interfaces positions
316   foreach(InterfaceItem *item, interfaces){
317     item->updatePosition();
318   }
319   // NB: dunno the utility of this test !!
320   if (getScene() != NULL) {
321     // update all connections from/to this block
322     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
323       if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
324         item->setPath();
325       }
326     }
327   }
328 }
329
330 void AbstractBoxItem::setDimension(int x, int y) {
331   boxWidth = x;
332   boxHeight = y;
333 }
334
335 InterfaceItem* AbstractBoxItem::getInterfaceItemFromCursor(qreal x, qreal y) {
336
337   foreach(InterfaceItem* inter, interfaces) {
338     if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
339       if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
340         return inter;
341       }
342     }
343   }
344   /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */
345   return NULL;
346 }