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: create InterfaceItem for every interfaces, even if they do not have a graphical representation
138 It will allow to save them in the XML project file and thus to create their equivalent
139 in the graph while the file is loaded.
142 if(inter->getDirection() == AbstractInterface::Input){
143 orientation = Parameters::West;
144 } else if(inter->getDirection() == AbstractInterface::Output){
145 orientation = Parameters::East;
146 } else if(inter->getDirection() == AbstractInterface::InOut){
147 orientation = Parameters::North;
149 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
150 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 - QPointF(nameHeight,nameHeight);
273 QSizeF s(totalWidth+2*nameHeight,totalHeight+2*nameHeight);
278 /* isInterface() : return true if there are some interfaces
279 with the given orientation (N,S,E,O)
281 bool AbstractBoxItem::isInterfaces(int orientation) const {
282 foreach(InterfaceItem* inter, interfaces) {
283 if (inter->getOrientation() == orientation) return true;
288 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
290 foreach(InterfaceItem* inter, interfaces) {
291 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
296 void AbstractBoxItem::updateInterfacesAndConnections() {
298 // update all interfaces positions
299 foreach(InterfaceItem *item, interfaces){
300 item->updatePosition();
302 // NB: dunno the utility of this test !!
303 if (getScene() != NULL) {
304 // update all connections from/to this block
305 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
306 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
313 void AbstractBoxItem::setDimension(int x, int y) {
318 InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
320 foreach(InterfaceItem* inter, interfaces) {
321 if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
322 if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
327 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */