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"
16 AbstractBoxItem:: AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem *parent) : QGraphicsItem(parent) {
17 dispatcher = _dispatcher;
21 QFontMetrics fmId(params->defaultBlockFont);
22 nameWidth = fmId.width(refBlock->getName());
23 nameHeight = fmId.height();
27 // the six following values will be override in subclass constructors
35 originPoint = QPointF(0.0,0.0);
38 currentInterface = NULL;
39 rstClkVisible = false;
40 wishboneVisible = false;
42 setAcceptHoverEvents(true);
44 // NOTE : initInterfaces() is only called in subclasses
47 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem* parent) : QGraphicsItem(parent) {
48 dispatcher = _dispatcher;
57 // the six following values will be override in subclass constructors
65 originPoint = QPointF(0.0,0.0);
68 currentInterface = NULL;
69 rstClkVisible = false;
70 wishboneVisible = false;
72 setAcceptHoverEvents(true);
74 // NOTE : initInterfaces() is only called in subclasses
77 AbstractBoxItem::~AbstractBoxItem() {
78 foreach(InterfaceItem* inter, interfaces) {
84 bool AbstractBoxItem::isBoxItem() {
88 bool AbstractBoxItem::isGroupItem() {
92 bool AbstractBoxItem::isSourceItem() {
96 void AbstractBoxItem::setRstClkVisible(bool b) {
98 foreach(InterfaceItem* ifaceItem, interfaces) {
99 if ((ifaceItem->refInter->getPurpose() == AbstractInterface::Clock) ||
100 (ifaceItem->refInter->getPurpose() == AbstractInterface::Reset) ) {
101 ifaceItem->visible = b;
104 resetInterfaceItemsPosition();
105 updateGeometry(InterfaceMove);
107 getScene()->updateConnectionItemsShape();
108 (getScene()->getGroupItem())->updateShape();
112 void AbstractBoxItem::setWishboneVisible(bool b) {
114 foreach(InterfaceItem* ifaceItem, interfaces) {
115 if (ifaceItem->refInter->getPurpose() == AbstractInterface::Wishbone) {
116 ifaceItem->visible = b;
119 resetInterfaceItemsPosition();
120 updateGeometry(InterfaceMove);
122 getScene()->updateConnectionItemsShape();
123 (getScene()->getGroupItem())->updateShape();
126 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
127 refBlock = _refBlock;
128 QFontMetrics fmId(params->defaultBlockFont);
129 nameWidth = fmId.width(refBlock->getName());
130 nameHeight = fmId.height();
133 void AbstractBoxItem::initInterfaceItems() {
134 /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
135 int orientation = Parameters::West;
137 foreach(AbstractInterface *inter, refBlock->getInterfaces()){
139 /* NB: does not create InterfaceItem for control interfaces.
141 if (inter->getPurpose() != AbstractInterface::Control) {
143 if(inter->getDirection() == AbstractInterface::Input){
144 orientation = Parameters::West;
145 } else if(inter->getDirection() == AbstractInterface::Output){
146 orientation = Parameters::East;
147 } else if(inter->getDirection() == AbstractInterface::InOut){
148 orientation = Parameters::North;
150 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
151 interfaces.append(item);
156 InterfaceItem* AbstractBoxItem::searchInterfaceItemByName(QString name) {
157 foreach(InterfaceItem *inter, interfaces){
158 if(inter->getName() == name)
164 InterfaceItem* AbstractBoxItem::searchInterfaceItemByRef(ConnectedInterface *ref) {
165 foreach(InterfaceItem *inter, interfaces){
166 if(inter->refInter == ref) {
173 void AbstractBoxItem::addInterfaceItem(InterfaceItem *i, bool resetPosition) {
174 interfaces.append(i);
175 if (resetPosition) resetInterfaceItemsPosition();
176 updateGeometry(InterfaceMove);
180 void AbstractBoxItem::removeInterfaceItem(InterfaceItem *i) {
181 // NB : removing from model is done in dispatcher
182 interfaces.removeAll(i);
185 //resetInterfacesPosition();
186 updateGeometry(InterfaceMove);
191 void AbstractBoxItem::resetInterfaceItemsPosition() {
193 int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
194 double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
195 double positionRatio = 1.0;
198 foreach(InterfaceItem* inter, interfaces) {
199 // only data interfaces and if needed time and reset
201 if(inter->getOrientation() == Parameters::North){
203 } else if(inter->getOrientation() == Parameters::South){
205 } else if(inter->getOrientation() == Parameters::East){
207 } else if(inter->getOrientation() == Parameters::West){
213 foreach(InterfaceItem* inter, interfaces) {
217 if(inter->getOrientation() == Parameters::North){
218 positionRatio = cntNorth/(double)(nbNorth+1);
220 } else if(inter->getOrientation() == Parameters::South){
221 positionRatio = cntSouth/(double)(nbSouth+1);
223 } else if(inter->getOrientation() == Parameters::East){
224 positionRatio = cntEast/(double)(nbEast+1);
226 } else if(inter->getOrientation() == Parameters::West){
227 positionRatio = cntWest/(double)(nbWest+1);
230 inter->setPositionRatio(positionRatio);
231 inter->updatePosition();
236 void AbstractBoxItem::moveInterfaceItemTo(QPointF pos) {
237 double positionRatio;
238 if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
241 if(pos.y() > 0 && pos.y() < boxHeight){
242 currentInterface->setOrientation(Parameters::West);
244 } else if(pos.x() > boxWidth){
246 if(pos.y() > 0 && pos.y() < boxHeight){
247 currentInterface->setOrientation(Parameters::East);
250 positionRatio = ((double) pos.x())/boxWidth;
256 if(pos.x() > 0 && pos.x() < boxWidth){
257 currentInterface->setOrientation(Parameters::North);
259 } else if(pos.y() > boxHeight){
261 if(pos.x() > 0 && pos.x() < boxWidth){
262 currentInterface->setOrientation(Parameters::South);
265 positionRatio = ((double) pos.y())/boxHeight;
268 currentInterface->setPositionRatio(positionRatio);
269 currentInterface->updatePosition();
272 QRectF AbstractBoxItem::boundingRect() const {
273 // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
274 QPointF p = originPoint;
275 QSizeF s(totalWidth,totalHeight);
279 QRectF AbstractBoxItem::boundingRectInScene() {
280 /* returns a QRectF in scene coordinates, that contains the block plus
281 a margin of size arrowWidth+arrowLineLength
283 int marginConn = params->arrowLineLength+params->arrowWidth;
285 QPointF posBox = scenePos();
286 posBox.setX(posBox.x()+originPoint.x()-marginConn);
287 posBox.setY(posBox.y()+originPoint.y()-marginConn);
289 QSizeF sizeBox(totalWidth+2*marginConn,totalHeight+2*marginConn);
291 return QRectF(posBox,sizeBox);
295 /* isInterface() : return true if there are some interfaces
296 with the given orientation (N,S,E,O)
298 bool AbstractBoxItem::isInterfaces(int orientation) const {
299 foreach(InterfaceItem* inter, interfaces) {
300 if (inter->getOrientation() == orientation) return true;
305 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
307 foreach(InterfaceItem* inter, interfaces) {
308 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
313 void AbstractBoxItem::updateInterfaceAndConnectionItems() {
315 // update all interfaces positions
316 foreach(InterfaceItem *item, interfaces){
317 item->updatePosition();
319 // NB: dunno the utility of this test !!
320 if (getScene() != NULL) {
321 // update all connections from/to this block
322 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
323 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
330 void AbstractBoxItem::setDimension(int x, int y) {
335 InterfaceItem* AbstractBoxItem::getInterfaceItemFromCursor(qreal x, qreal y) {
337 foreach(InterfaceItem* inter, interfaces) {
338 if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
339 if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
344 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */