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() {
89 void AbstractBoxItem::setRstClkVisible(bool b) {
91 foreach(InterfaceItem* ifaceItem, interfaces) {
92 if ((ifaceItem->refInter->getPurpose() == AbstractInterface::Clock) ||
93 (ifaceItem->refInter->getPurpose() == AbstractInterface::Reset) ) {
94 ifaceItem->visible = b;
97 resetInterfacesPosition();
98 updateGeometry(InterfaceMove);
100 getScene()->updateConnectionItemsShape();
101 (getScene()->getGroupItem())->updateShape();
105 void AbstractBoxItem::setWishboneVisible(bool b) {
107 foreach(InterfaceItem* ifaceItem, interfaces) {
108 if (ifaceItem->refInter->getPurpose() == AbstractInterface::Wishbone) {
109 ifaceItem->visible = b;
112 resetInterfacesPosition();
113 updateGeometry(InterfaceMove);
115 getScene()->updateConnectionItemsShape();
116 (getScene()->getGroupItem())->updateShape();
119 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
120 refBlock = _refBlock;
121 QFontMetrics fmId(params->defaultBlockFont);
122 nameWidth = fmId.width(refBlock->getName());
123 nameHeight = fmId.height();
126 void AbstractBoxItem::initInterfaces() {
127 /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
128 int orientation = Parameters::West;
130 foreach(AbstractInterface *inter, refBlock->getInterfaces()){
132 /* NB: create InterfaceItem for every interfaces, even if they do not have a graphical representation
133 It will allow to save them in the XML project file and thus to create their equivalent
134 in the graph while the file is loaded.
137 if(inter->getDirection() == AbstractInterface::Input){
138 orientation = Parameters::West;
139 } else if(inter->getDirection() == AbstractInterface::Output){
140 orientation = Parameters::East;
141 } else if(inter->getDirection() == AbstractInterface::InOut){
142 orientation = Parameters::North;
144 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
145 interfaces.append(item);
149 InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) {
150 foreach(InterfaceItem *inter, interfaces){
151 if(inter->getName() == name)
157 InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) {
158 foreach(InterfaceItem *inter, interfaces){
159 if(inter->refInter == ref) {
166 void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
167 interfaces.append(i);
168 if (resetPosition) resetInterfacesPosition();
169 updateGeometry(InterfaceMove);
173 void AbstractBoxItem::removeInterface(InterfaceItem *i) {
174 // NB : removing from model is done in dispatcher
175 interfaces.removeOne(i);
178 //resetInterfacesPosition();
179 updateGeometry(InterfaceMove);
184 void AbstractBoxItem::resetInterfacesPosition() {
186 int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
187 double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
188 double positionRatio = 1.0;
191 foreach(InterfaceItem* inter, interfaces) {
192 // only data interfaces and if needed time and reset
194 if(inter->getOrientation() == Parameters::North){
196 } else if(inter->getOrientation() == Parameters::South){
198 } else if(inter->getOrientation() == Parameters::East){
200 } else if(inter->getOrientation() == Parameters::West){
206 foreach(InterfaceItem* inter, interfaces) {
210 if(inter->getOrientation() == Parameters::North){
211 positionRatio = cntNorth/(double)(nbNorth+1);
213 } else if(inter->getOrientation() == Parameters::South){
214 positionRatio = cntSouth/(double)(nbSouth+1);
216 } else if(inter->getOrientation() == Parameters::East){
217 positionRatio = cntEast/(double)(nbEast+1);
219 } else if(inter->getOrientation() == Parameters::West){
220 positionRatio = cntWest/(double)(nbWest+1);
223 inter->setPositionRatio(positionRatio);
224 inter->updatePosition();
229 void AbstractBoxItem::moveInterfaceTo(QPointF pos) {
230 double positionRatio;
231 if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
234 if(pos.y() > 0 && pos.y() < boxHeight){
235 currentInterface->setOrientation(Parameters::West);
237 } else if(pos.x() > boxWidth){
239 if(pos.y() > 0 && pos.y() < boxHeight){
240 currentInterface->setOrientation(Parameters::East);
243 positionRatio = ((double) pos.x())/boxWidth;
249 if(pos.x() > 0 && pos.x() < boxWidth){
250 currentInterface->setOrientation(Parameters::North);
252 } else if(pos.y() > boxHeight){
254 if(pos.x() > 0 && pos.x() < boxWidth){
255 currentInterface->setOrientation(Parameters::South);
258 positionRatio = ((double) pos.y())/boxHeight;
261 currentInterface->setPositionRatio(positionRatio);
262 currentInterface->updatePosition();
265 QRectF AbstractBoxItem::boundingRect() const {
266 // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
267 QPointF p = originPoint - QPointF(nameHeight,nameHeight);
268 QSizeF s(totalWidth+2*nameHeight,totalHeight+2*nameHeight);
273 /* isInterface() : return true if there are some interfaces
274 with the given orientation (N,S,E,O)
276 bool AbstractBoxItem::isInterfaces(int orientation) const {
277 foreach(InterfaceItem* inter, interfaces) {
278 if (inter->getOrientation() == orientation) return true;
283 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
285 foreach(InterfaceItem* inter, interfaces) {
286 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
291 void AbstractBoxItem::updateInterfacesAndConnections() {
293 // update all interfaces positions
294 foreach(InterfaceItem *item, interfaces){
295 item->updatePosition();
297 // NB: dunno the utility of this test !!
298 if (getScene() != NULL) {
299 // update all connections from/to this block
300 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
301 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
308 void AbstractBoxItem::setDimension(int x, int y) {
313 InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
315 foreach(InterfaceItem* inter, interfaces) {
316 if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
317 if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
322 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */