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

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