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 "AbstractInterface.h"
12 #include "ConnectedInterface.h"
15 AbstractBoxItem:: AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem *parent) : QGraphicsItem(parent) {
16 dispatcher = _dispatcher;
19 QFontMetrics fmId(params->defaultBlockFont);
20 nameWidth = fmId.width(refBlock->getName());
21 nameHeight = fmId.height();
25 // the six following values will be override in subclass constructors
33 originPoint = QPointF(0.0,0.0);
36 currentInterface = NULL;
37 rstClkVisible = false;
39 setAcceptHoverEvents(true);
41 // NOTE : initInterfaces() is only called in subclasses
44 AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent) : QGraphicsItem(parent) {
45 dispatcher = _dispatcher;
53 // the six following values will be override in subclass constructors
61 originPoint = QPointF(0.0,0.0);
64 currentInterface = NULL;
65 rstClkVisible = false;
67 setAcceptHoverEvents(true);
69 // NOTE : initInterfaces() is only called in subclasses
72 AbstractBoxItem::~AbstractBoxItem() {
73 foreach(InterfaceItem* inter, interfaces) {
79 bool AbstractBoxItem::isBoxItem() {
83 bool AbstractBoxItem::isGroupItem() {
87 void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
89 QFontMetrics fmId(params->defaultBlockFont);
90 nameWidth = fmId.width(refBlock->getName());
91 nameHeight = fmId.height();
94 void AbstractBoxItem::initInterfaces() {
95 /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
96 int orientation = Parameters::West;
98 foreach(AbstractInterface *inter, refBlock->getInterfaces()){
99 if(inter->getPurpose() != AbstractInterface::Wishbone){
101 if(inter->getDirection() == AbstractInterface::Input){
102 orientation = Parameters::West;
103 } else if(inter->getDirection() == AbstractInterface::Output){
104 orientation = Parameters::East;
105 } else if(inter->getDirection() == AbstractInterface::InOut){
106 orientation = Parameters::North;
108 item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
109 interfaces.append(item);
114 InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) {
115 foreach(InterfaceItem *inter, interfaces){
116 if(inter->getName() == name)
122 InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) {
123 foreach(InterfaceItem *inter, interfaces){
124 if(inter->refInter == ref) {
131 void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
132 interfaces.append(i);
133 if (resetPosition) resetInterfacesPosition();
134 updateGeometry(InterfaceMove);
138 void AbstractBoxItem::removeInterface(InterfaceItem *i) {
139 // NB : removing from model is done in dispatcher
140 interfaces.removeOne(i);
143 //resetInterfacesPosition();
144 updateGeometry(InterfaceMove);
149 void AbstractBoxItem::resetInterfacesPosition() {
151 int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
152 double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
153 double positionRatio = 1.0;
156 foreach(InterfaceItem* inter, interfaces) {
157 // only data interfaces and if needed time and reset
158 if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
159 if(inter->getOrientation() == Parameters::North){
161 } else if(inter->getOrientation() == Parameters::South){
163 } else if(inter->getOrientation() == Parameters::East){
165 } else if(inter->getOrientation() == Parameters::West){
171 foreach(InterfaceItem* inter, interfaces) {
173 if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
175 if(inter->getOrientation() == Parameters::North){
176 positionRatio = cntNorth/(double)(nbNorth+1);
178 } else if(inter->getOrientation() == Parameters::South){
179 positionRatio = cntSouth/(double)(nbSouth+1);
181 } else if(inter->getOrientation() == Parameters::East){
182 positionRatio = cntEast/(double)(nbEast+1);
184 } else if(inter->getOrientation() == Parameters::West){
185 positionRatio = cntWest/(double)(nbWest+1);
188 inter->setPositionRatio(positionRatio);
189 inter->updatePosition();
194 void AbstractBoxItem::moveInterfaceTo(QPointF pos) {
195 double positionRatio;
196 if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
199 if(pos.y() > 0 && pos.y() < boxHeight){
200 currentInterface->setOrientation(Parameters::West);
202 } else if(pos.x() > boxWidth){
204 if(pos.y() > 0 && pos.y() < boxHeight){
205 currentInterface->setOrientation(Parameters::East);
208 positionRatio = ((double) pos.x())/boxWidth;
214 if(pos.x() > 0 && pos.x() < boxWidth){
215 currentInterface->setOrientation(Parameters::North);
217 } else if(pos.y() > boxHeight){
219 if(pos.x() > 0 && pos.x() < boxWidth){
220 currentInterface->setOrientation(Parameters::South);
223 positionRatio = ((double) pos.y())/boxHeight;
226 currentInterface->setPositionRatio(positionRatio);
227 currentInterface->updatePosition();
230 QRectF AbstractBoxItem::boundingRect() const {
231 // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
232 QPointF p = originPoint - QPointF(nameHeight,nameHeight);
233 QSizeF s(totalWidth+2*nameHeight,totalHeight+2*nameHeight);
238 /* isInterface() : return true if there are some interfaces
239 with the given orientation (N,S,E,O)
241 bool AbstractBoxItem::isInterfaces(int orientation) const {
242 foreach(InterfaceItem* inter, interfaces) {
243 if (inter->getOrientation() == orientation) return true;
248 int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
250 foreach(InterfaceItem* inter, interfaces) {
251 if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
256 void AbstractBoxItem::updateInterfacesAndConnections() {
258 // update all interfaces positions
259 foreach(InterfaceItem *item, interfaces){
260 item->updatePosition();
262 // NB: dunno the utility of this test !!
263 if (getScene() != NULL) {
264 // update all connections from/to this block
265 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
266 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
273 void AbstractBoxItem::setDimension(int x, int y) {
278 InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
280 foreach(InterfaceItem* inter, interfaces) {
281 if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
282 if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
287 /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */