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

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