1 #include "AbstractBoxItem.h"
3 #include "Parameters.h"
5 #include "Dispatcher.h"
6 #include "InterfaceItem.h"
7 #include "ConnectionItem.h"
9 #include "AbstractBlock.h"
10 #include "GroupScene.h"
11 #include "GroupItem.h"
12 #include "AbstractInterface.h"
13 #include "ConnectedInterface.h"
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;
21 AbstractBoxItem::AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, int _lock, QGraphicsItem *parent) : QGraphicsItem(parent) {
22 dispatcher = _dispatcher;
26 QFontMetrics fmId(params->defaultBlockFont);
27 nameWidth = fmId.width(refBlock->getName());
28 nameHeight = fmId.height();
32 // the six following values will be override in subclass constructors
40 originPoint = QPointF(0.0,0.0);
43 currentInterface = NULL;
45 rstClkVisible = false;
46 wishboneVisible = false;
48 setAcceptHoverEvents(true);
50 // NOTE : initInterfaces() is only called in subclasses
53 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, int _lock, QGraphicsItem* parent) : QGraphicsItem(parent) {
54 dispatcher = _dispatcher;
63 // the six following values will be override in subclass constructors
71 originPoint = QPointF(0.0,0.0);
74 currentInterface = NULL;
76 rstClkVisible = false;
77 wishboneVisible = false;
79 setAcceptHoverEvents(true);
81 // NOTE : initInterfaces() is only called in subclasses
84 AbstractBoxItem::~AbstractBoxItem() {
85 foreach(InterfaceItem* inter, interfaces) {
91 bool AbstractBoxItem::isBoxItem() {
95 bool AbstractBoxItem::isGroupItem() {
99 bool AbstractBoxItem::isStimuliItem() {
103 void AbstractBoxItem::setRstClkVisible(bool b) {
105 foreach(InterfaceItem* ifaceItem, interfaces) {
106 if ((ifaceItem->refInter->getPurpose() == AbstractInterface::Clock) ||
107 (ifaceItem->refInter->getPurpose() == AbstractInterface::Reset) ) {
108 ifaceItem->visible = b;
111 resetInterfaceItemsPosition();
112 updateGeometry(InterfaceMove);
114 getScene()->updateConnectionItemsShape();
115 (getScene()->getGroupItem())->updateShape();
119 void AbstractBoxItem::setWishboneVisible(bool b) {
121 foreach(InterfaceItem* ifaceItem, interfaces) {
122 if (ifaceItem->refInter->getPurpose() == AbstractInterface::Wishbone) {
123 ifaceItem->visible = b;
126 resetInterfaceItemsPosition();
127 updateGeometry(InterfaceMove);
129 getScene()->updateConnectionItemsShape();
130 (getScene()->getGroupItem())->updateShape();
133 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
134 refBlock = _refBlock;
135 QFontMetrics fmId(params->defaultBlockFont);
136 nameWidth = fmId.width(refBlock->getName());
137 nameHeight = fmId.height();
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;
144 foreach(AbstractInterface *inter, refBlock->getInterfaces()){
146 /* NB: does not create InterfaceItem for control interfaces.
148 if (inter->getPurpose() != AbstractInterface::Control) {
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;
157 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
158 interfaces.append(item);
163 InterfaceItem* AbstractBoxItem::searchInterfaceItemByName(QString name) {
164 foreach(InterfaceItem *inter, interfaces){
165 if(inter->getName() == name)
171 InterfaceItem* AbstractBoxItem::searchInterfaceItemByRef(ConnectedInterface *ref) {
172 foreach(InterfaceItem *inter, interfaces){
173 if(inter->refInter == ref) {
180 void AbstractBoxItem::addInterfaceItem(InterfaceItem *i, bool resetPosition) {
181 interfaces.append(i);
182 if (resetPosition) resetInterfaceItemsPosition();
183 updateGeometry(InterfaceMove);
187 void AbstractBoxItem::removeInterfaceItem(InterfaceItem *i) {
188 // NB : removing from model is done in dispatcher
189 interfaces.removeAll(i);
192 //resetInterfacesPosition();
193 updateGeometry(InterfaceMove);
198 void AbstractBoxItem::resetInterfaceItemsPosition() {
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;
205 foreach(InterfaceItem* inter, interfaces) {
206 // only data interfaces and if needed time and reset
208 if(inter->getOrientation() == Parameters::North){
210 } else if(inter->getOrientation() == Parameters::South){
212 } else if(inter->getOrientation() == Parameters::East){
214 } else if(inter->getOrientation() == Parameters::West){
220 foreach(InterfaceItem* inter, interfaces) {
224 if(inter->getOrientation() == Parameters::North){
225 positionRatio = cntNorth/(double)(nbNorth+1);
227 } else if(inter->getOrientation() == Parameters::South){
228 positionRatio = cntSouth/(double)(nbSouth+1);
230 } else if(inter->getOrientation() == Parameters::East){
231 positionRatio = cntEast/(double)(nbEast+1);
233 } else if(inter->getOrientation() == Parameters::West){
234 positionRatio = cntWest/(double)(nbWest+1);
237 inter->setPositionRatio(positionRatio);
238 inter->updatePosition();
243 void AbstractBoxItem::moveInterfaceItemTo(QPointF pos) {
244 double positionRatio;
245 if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
248 if(pos.y() > 0 && pos.y() < boxHeight){
249 currentInterface->setOrientation(Parameters::West);
251 } else if(pos.x() > boxWidth){
253 if(pos.y() > 0 && pos.y() < boxHeight){
254 currentInterface->setOrientation(Parameters::East);
257 positionRatio = ((double) pos.x())/boxWidth;
263 if(pos.x() > 0 && pos.x() < boxWidth){
264 currentInterface->setOrientation(Parameters::North);
266 } else if(pos.y() > boxHeight){
268 if(pos.x() > 0 && pos.x() < boxWidth){
269 currentInterface->setOrientation(Parameters::South);
272 positionRatio = ((double) pos.y())/boxHeight;
275 currentInterface->setPositionRatio(positionRatio);
276 currentInterface->updatePosition();
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);
286 QRectF AbstractBoxItem::boundingRectInScene() {
287 /* returns a QRectF in scene coordinates, that contains the block plus
288 a margin of size arrowWidth+arrowLineLength
290 int marginConn = params->arrowLineLength+params->arrowWidth;
292 QPointF posBox = scenePos();
293 posBox.setX(posBox.x()+originPoint.x()-marginConn);
294 posBox.setY(posBox.y()+originPoint.y()-marginConn);
296 QSizeF sizeBox(totalWidth+2*marginConn,totalHeight+2*marginConn);
298 return QRectF(posBox,sizeBox);
302 /* isInterface() : return true if there are some interfaces
303 with the given orientation (N,S,E,O)
305 bool AbstractBoxItem::isInterfaces(int orientation) const {
306 foreach(InterfaceItem* inter, interfaces) {
307 if ((inter->visible) && (inter->getOrientation() == orientation)) return true;
312 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
314 foreach(InterfaceItem* inter, interfaces) {
315 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
320 void AbstractBoxItem::updateInterfaceAndConnectionItems() {
322 // update all interfaces positions
323 foreach(InterfaceItem *item, interfaces){
324 item->updatePosition();
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)) {
337 void AbstractBoxItem::setDimension(int x, int y) {
342 InterfaceItem* AbstractBoxItem::getInterfaceItemFromCursor(qreal x, qreal y) {
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())){
351 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */