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

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