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

Private GIT Repository
added impl xsd + patterns in impls
[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 "AbstractInterface.h"
12 #include "ConnectedInterface.h"
13
14
15 AbstractBoxItem::  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem *parent) : QGraphicsItem(parent) {
16   dispatcher = _dispatcher;
17   params = _params;
18   refBlock = _refBlock;  
19   QFontMetrics fmId(params->defaultBlockFont);
20   nameWidth = fmId.width(refBlock->getName());
21   nameHeight = fmId.height();
22   nameMargin = 10;
23   ifaceMargin = 10;
24
25   // the six following values will be override in subclass constructors
26   minimumBoxWidth = 0;
27   minimumBoxHeight = 0;
28   boxWidth = 0;
29   boxHeight = 0;
30   totalWidth = 0;
31   totalHeight = 0;
32
33   originPoint = QPointF(0.0,0.0);
34
35   selected = false;
36   currentInterface = NULL;
37   rstClkVisible = false;
38
39   setAcceptHoverEvents(true);
40
41   // NOTE : initInterfaces() is only called in subclasses
42 }
43
44 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent) : QGraphicsItem(parent) {
45   dispatcher = _dispatcher;
46   params = _params;
47   refBlock = NULL;
48   nameWidth = 0;
49   nameHeight = 0;
50   nameMargin = 10;
51   ifaceMargin = 10;
52
53   // the six following values will be override in subclass constructors
54   minimumBoxWidth = 0;
55   minimumBoxHeight = 0;
56   boxWidth = 0;
57   boxHeight = 0;
58   totalWidth = 0;
59   totalHeight = 0;
60
61   originPoint = QPointF(0.0,0.0);
62
63   selected = false;
64   currentInterface = NULL;
65   rstClkVisible = false;
66
67   setAcceptHoverEvents(true);
68
69   // NOTE : initInterfaces() is only called in subclasses
70 }
71
72 AbstractBoxItem::~AbstractBoxItem() {
73   foreach(InterfaceItem* inter, interfaces) {
74     delete inter;
75   }
76   interfaces.clear();
77 }
78
79 bool AbstractBoxItem::isBoxItem() {
80   return false;
81 }
82
83 bool AbstractBoxItem::isGroupItem() {
84   return false;
85 }
86
87 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
88   refBlock = _refBlock;
89   QFontMetrics fmId(params->defaultBlockFont);
90   nameWidth = fmId.width(refBlock->getName());
91   nameHeight = fmId.height();
92 }
93
94 void AbstractBoxItem::initInterfaces() {
95   /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
96   int orientation = Parameters::West;
97
98   foreach(AbstractInterface *inter, refBlock->getInterfaces()){
99     if(inter->getPurpose() != AbstractInterface::Wishbone){
100       InterfaceItem *item;
101       if(inter->getDirection() == AbstractInterface::Input){
102         orientation = Parameters::West;
103       } else if(inter->getDirection() == AbstractInterface::Output){
104         orientation = Parameters::East;
105       } else if(inter->getDirection() == AbstractInterface::InOut){
106         orientation = Parameters::North;
107       }
108       item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
109       interfaces.append(item);
110     }
111   }  
112 }
113
114 InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) {
115   foreach(InterfaceItem *inter, interfaces){
116     if(inter->getName() == name)
117       return inter;
118   }
119   return NULL;
120 }
121
122 InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) {
123   foreach(InterfaceItem *inter, interfaces){
124     if(inter->refInter == ref) {
125       return inter;
126     }
127   }
128   return NULL;
129 }
130
131 void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
132   interfaces.append(i);
133   if (resetPosition) resetInterfacesPosition();
134   updateGeometry(InterfaceMove);
135   update();
136 }
137
138 void AbstractBoxItem::removeInterface(InterfaceItem *i) {
139   // NB : removing from model is done in dispatcher
140   interfaces.removeOne(i);
141   delete i;
142
143   //resetInterfacesPosition();
144   updateGeometry(InterfaceMove);
145   update();
146 }
147
148
149 void AbstractBoxItem::resetInterfacesPosition() {
150
151   int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
152   double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
153   double positionRatio = 1.0;
154
155
156   foreach(InterfaceItem* inter, interfaces) {
157     // only data interfaces and if needed time and reset
158     if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
159       if(inter->getOrientation() == Parameters::North){
160         nbNorth++;
161       } else if(inter->getOrientation() == Parameters::South){
162         nbSouth++;
163       } else if(inter->getOrientation() == Parameters::East){
164         nbEast++;
165       } else if(inter->getOrientation() == Parameters::West){
166         nbWest++;
167       }
168     }
169   }
170
171   foreach(InterfaceItem* inter, interfaces) {
172
173     if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
174
175       if(inter->getOrientation() == Parameters::North){
176         positionRatio = cntNorth/(double)(nbNorth+1);
177         cntNorth += 1.0;
178       } else if(inter->getOrientation() == Parameters::South){
179         positionRatio = cntSouth/(double)(nbSouth+1);
180         cntSouth += 1.0;
181       } else if(inter->getOrientation() == Parameters::East){
182         positionRatio = cntEast/(double)(nbEast+1);
183         cntEast += 1.0;
184       } else if(inter->getOrientation() == Parameters::West){
185         positionRatio = cntWest/(double)(nbWest+1);
186         cntWest += 1.0;
187       }
188       inter->setPositionRatio(positionRatio);
189       inter->updatePosition();
190     }
191   }
192 }
193
194 void AbstractBoxItem::moveInterfaceTo(QPointF pos) {
195   double positionRatio;
196   if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
197     if(pos.x() < 0){
198       positionRatio = 0;
199       if(pos.y() > 0 && pos.y() < boxHeight){
200         currentInterface->setOrientation(Parameters::West);
201       }
202     } else if(pos.x() > boxWidth){
203       positionRatio = 1;
204       if(pos.y() > 0 && pos.y() < boxHeight){
205         currentInterface->setOrientation(Parameters::East);
206       }
207     } else {
208       positionRatio = ((double) pos.x())/boxWidth;
209     }
210   } else {
211
212     if(pos.y() < 0){
213       positionRatio = 0;
214       if(pos.x() > 0 && pos.x() < boxWidth){
215         currentInterface->setOrientation(Parameters::North);
216       }
217     } else if(pos.y() > boxHeight){
218       positionRatio = 1;
219       if(pos.x() > 0 && pos.x() < boxWidth){
220         currentInterface->setOrientation(Parameters::South);
221       }
222     } else {
223       positionRatio = ((double) pos.y())/boxHeight;
224     }
225   }
226   currentInterface->setPositionRatio(positionRatio);
227   currentInterface->updatePosition();
228 }
229
230 QRectF AbstractBoxItem::boundingRect() const {
231   // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
232   QPointF p = originPoint - QPointF(nameHeight,nameHeight);
233   QSizeF s(totalWidth+2*nameHeight,totalHeight+2*nameHeight);
234   return QRectF(p,s);
235 }
236
237
238 /* isInterface() : return true if there are some interfaces
239    with the given orientation (N,S,E,O)
240 */
241 bool AbstractBoxItem::isInterfaces(int orientation) const {
242   foreach(InterfaceItem* inter, interfaces) {
243     if (inter->getOrientation() == orientation) return true;
244   }
245   return false;
246 }
247
248 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
249   int nb = 0;
250   foreach(InterfaceItem* inter, interfaces) {
251     if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
252   }
253   return nb;
254 }
255
256 void AbstractBoxItem::updateInterfacesAndConnections() {
257
258   // update all interfaces positions
259   foreach(InterfaceItem *item, interfaces){
260     item->updatePosition();
261   }
262   // NB: dunno the utility of this test !!
263   if (getScene() != NULL) {
264     // update all connections from/to this block
265     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
266       if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
267         item->setPath();
268       }
269     }
270   }
271 }
272
273 void AbstractBoxItem::setDimension(int x, int y) {
274   boxWidth = x;
275   boxHeight = y;
276 }
277
278 InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
279
280   foreach(InterfaceItem* inter, interfaces) {
281     if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
282       if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
283         return inter;
284       }
285     }
286   }
287   /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */
288   return NULL;
289 }