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, QGraphicsItem *parent) : QGraphicsItem(parent) {
17 dispatcher = _dispatcher;
20 QFontMetrics fmId(params->defaultBlockFont);
21 nameWidth = fmId.width(refBlock->getName());
22 nameHeight = fmId.height();
26 // the six following values will be override in subclass constructors
34 originPoint = QPointF(0.0,0.0);
37 currentInterface = NULL;
38 rstClkVisible = false;
39 wishboneVisible = false;
41 setAcceptHoverEvents(true);
43 // NOTE : initInterfaces() is only called in subclasses
46 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent) : QGraphicsItem(parent) {
47 dispatcher = _dispatcher;
55 // the six following values will be override in subclass constructors
63 originPoint = QPointF(0.0,0.0);
66 currentInterface = NULL;
67 rstClkVisible = false;
68 wishboneVisible = false;
70 setAcceptHoverEvents(true);
72 // NOTE : initInterfaces() is only called in subclasses
75 AbstractBoxItem::~AbstractBoxItem() {
76 foreach(InterfaceItem* inter, interfaces) {
82 bool AbstractBoxItem::isBoxItem() {
86 bool AbstractBoxItem::isGroupItem() {
90 bool AbstractBoxItem::isSourceItem() {
94 void AbstractBoxItem::setRstClkVisible(bool b) {
96 foreach(InterfaceItem* ifaceItem, interfaces) {
97 if ((ifaceItem->refInter->getPurpose() == AbstractInterface::Clock) ||
98 (ifaceItem->refInter->getPurpose() == AbstractInterface::Reset) ) {
99 ifaceItem->visible = b;
102 resetInterfacesPosition();
103 updateGeometry(InterfaceMove);
105 getScene()->updateConnectionItemsShape();
106 (getScene()->getGroupItem())->updateShape();
110 void AbstractBoxItem::setWishboneVisible(bool b) {
112 foreach(InterfaceItem* ifaceItem, interfaces) {
113 if (ifaceItem->refInter->getPurpose() == AbstractInterface::Wishbone) {
114 ifaceItem->visible = b;
117 resetInterfacesPosition();
118 updateGeometry(InterfaceMove);
120 getScene()->updateConnectionItemsShape();
121 (getScene()->getGroupItem())->updateShape();
124 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
125 refBlock = _refBlock;
126 QFontMetrics fmId(params->defaultBlockFont);
127 nameWidth = fmId.width(refBlock->getName());
128 nameHeight = fmId.height();
131 void AbstractBoxItem::initInterfaces() {
132 /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
133 int orientation = Parameters::West;
135 foreach(AbstractInterface *inter, refBlock->getInterfaces()){
137 /* NB: does not create InterfaceItem for control interfaces.
139 if (inter->getPurpose() != AbstractInterface::Control) {
141 if(inter->getDirection() == AbstractInterface::Input){
142 orientation = Parameters::West;
143 } else if(inter->getDirection() == AbstractInterface::Output){
144 orientation = Parameters::East;
145 } else if(inter->getDirection() == AbstractInterface::InOut){
146 orientation = Parameters::North;
148 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
149 interfaces.append(item);
154 InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) {
155 foreach(InterfaceItem *inter, interfaces){
156 if(inter->getName() == name)
162 InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) {
163 foreach(InterfaceItem *inter, interfaces){
164 if(inter->refInter == ref) {
171 void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
172 interfaces.append(i);
173 if (resetPosition) resetInterfacesPosition();
174 updateGeometry(InterfaceMove);
178 void AbstractBoxItem::removeInterface(InterfaceItem *i) {
179 // NB : removing from model is done in dispatcher
180 interfaces.removeOne(i);
183 //resetInterfacesPosition();
184 updateGeometry(InterfaceMove);
189 void AbstractBoxItem::resetInterfacesPosition() {
191 int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
192 double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
193 double positionRatio = 1.0;
196 foreach(InterfaceItem* inter, interfaces) {
197 // only data interfaces and if needed time and reset
199 if(inter->getOrientation() == Parameters::North){
201 } else if(inter->getOrientation() == Parameters::South){
203 } else if(inter->getOrientation() == Parameters::East){
205 } else if(inter->getOrientation() == Parameters::West){
211 foreach(InterfaceItem* inter, interfaces) {
215 if(inter->getOrientation() == Parameters::North){
216 positionRatio = cntNorth/(double)(nbNorth+1);
218 } else if(inter->getOrientation() == Parameters::South){
219 positionRatio = cntSouth/(double)(nbSouth+1);
221 } else if(inter->getOrientation() == Parameters::East){
222 positionRatio = cntEast/(double)(nbEast+1);
224 } else if(inter->getOrientation() == Parameters::West){
225 positionRatio = cntWest/(double)(nbWest+1);
228 inter->setPositionRatio(positionRatio);
229 inter->updatePosition();
234 void AbstractBoxItem::moveInterfaceTo(QPointF pos) {
235 double positionRatio;
236 if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
239 if(pos.y() > 0 && pos.y() < boxHeight){
240 currentInterface->setOrientation(Parameters::West);
242 } else if(pos.x() > boxWidth){
244 if(pos.y() > 0 && pos.y() < boxHeight){
245 currentInterface->setOrientation(Parameters::East);
248 positionRatio = ((double) pos.x())/boxWidth;
254 if(pos.x() > 0 && pos.x() < boxWidth){
255 currentInterface->setOrientation(Parameters::North);
257 } else if(pos.y() > boxHeight){
259 if(pos.x() > 0 && pos.x() < boxWidth){
260 currentInterface->setOrientation(Parameters::South);
263 positionRatio = ((double) pos.y())/boxHeight;
266 currentInterface->setPositionRatio(positionRatio);
267 currentInterface->updatePosition();
270 QRectF AbstractBoxItem::boundingRect() const {
271 // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
272 QPointF p = originPoint;
273 QSizeF s(totalWidth,totalHeight);
277 QRectF AbstractBoxItem::boundingRectInScene() {
278 /* returns a QRectF in scene coordinates, that contains the block plus
279 a margin of size arrowWidth+arrowLineLength
281 int marginConn = params->arrowLineLength+params->arrowWidth;
283 QPointF posBox = scenePos();
284 posBox.setX(posBox.x()+originPoint.x()-marginConn);
285 posBox.setY(posBox.y()+originPoint.y()-marginConn);
287 QSizeF sizeBox(totalWidth+2*marginConn,totalHeight+2*marginConn);
289 return QRectF(posBox,sizeBox);
293 /* isInterface() : return true if there are some interfaces
294 with the given orientation (N,S,E,O)
296 bool AbstractBoxItem::isInterfaces(int orientation) const {
297 foreach(InterfaceItem* inter, interfaces) {
298 if (inter->getOrientation() == orientation) return true;
303 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
305 foreach(InterfaceItem* inter, interfaces) {
306 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
311 void AbstractBoxItem::updateInterfacesAndConnections() {
313 // update all interfaces positions
314 foreach(InterfaceItem *item, interfaces){
315 item->updatePosition();
317 // NB: dunno the utility of this test !!
318 if (getScene() != NULL) {
319 // update all connections from/to this block
320 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
321 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
328 void AbstractBoxItem::setDimension(int x, int y) {
333 InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
335 foreach(InterfaceItem* inter, interfaces) {
336 if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
337 if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
342 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */