void DataVisualizer::setItemPos(QGraphicsItem * item, QPointF pos) { typedef QList<QGraphicsItem *> QGraphicsItemList; SceneType scene(gvDisplay->scene()); if (!item || !scene) return; // set the desired position item->setPos(pos); // check for collisions with other items QList<QGraphicsItem *> collides = scene->collidingItems(item); if (collides.size() == 0) return; QGraphicsItem * cItem = 0; QGraphicsItemList::const_iterator it = collides.constBegin(); while(it != collides.constEnd()) { cItem = *it; if (cItem && !cItem->parentItem()) break; it++; } if (!cItem || cItem->parentItem()) return; // item has no parent => top-level, bounding rect qreal newYPos = cItem->y() + 0.5*cItem->boundingRect().height() + 0.5*item->boundingRect().height() + itemMargin; QPointF newPos(pos); newPos.setY(newYPos); setItemPos(item, newPos); }
QGraphicsItem * Node::findRootParent() { QGraphicsItem * root = this->parentItem(); while (root->parentItem() != 0 && root->parentItem() != nullptr) root = root->parentItem(); return root; }
PianoKey* PianoScene::getKeyForPos( const QPointF& p ) const { QGraphicsItem *itm = itemAt(p); while (itm != NULL && itm->parentItem() != NULL) itm = itm->parentItem(); if (itm != NULL) { PianoKey* key = dynamic_cast<PianoKey*>(itm); return key; } return NULL; }
void TupGraphicsScene::addGraphicObject(TupGraphicObject *object, double opacity) { /* #ifdef K_DEBUG T_FUNCINFO; #endif */ QGraphicsItem *item = object->item(); k->onionSkin.opacityMap.insert(item, opacity); if (TupItemGroup *group = qgraphicsitem_cast<TupItemGroup *>(item)) group->recoverChilds(); if (! qgraphicsitem_cast<TupItemGroup *>(item->parentItem())) { item->setSelected(false); TupLayer *layer = k->scene->layer(k->framePosition.layer); if (layer) { TupFrame *frame = layer->frame(k->framePosition.frame); if (frame) { item->setOpacity(opacity); // k->objectCounter++; addItem(item); } } } }
void RotateTool::mousePressEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem * item = scene()->itemAt(event->buttonDownScenePos(Qt::LeftButton)); if (!item) return; if (item->type() == Atom::Type) item = item->parentItem(); if (item->type() == Bond::Type) item = item->parentItem(); QPointF rotatePoint = item->boundingRect().center(); QPointF rotatePointAbs = item->mapToScene(rotatePoint); m_rotationCenter = rotatePointAbs; m_rotationItem = item; m_lastRotationVect = event->buttonDownScenePos(Qt::LeftButton) - rotatePointAbs ; //save vector for relative rotation step }
bool KWidget::hasTheme() { Q_D(KWidget); if(d->themePolicy == NoTheme) return false; if(d->themePolicy == ThemeWithParent) { if(d->bThemeCheck) { return d->bThemeResult; } d->bThemeCheck = true; QGraphicsItem *itemParent = parentItem(); while(itemParent) { KWidget *widgetParent = qobject_cast<KWidget*>(itemParent->toGraphicsObject()); if(widgetParent == NULL) { itemParent = itemParent->parentItem(); continue; } QString objName = widgetParent->objectName(); ThemePolicy scp = widgetParent->themePolicy(); if(scp == NoTheme) { d->bThemeResult = false; return false; } if(scp == ThemeWithParent) { itemParent = itemParent->parentItem(); continue; } d->bThemeResult = true; return true; } d->bThemeResult = false; return false; } return true; }
void GraphicsClientItem::focusInEvent(QFocusEvent *) { QGraphicsItem *topSibling = 0; if (parentItem()) { topSibling = parentItem()->childItems().first(); } else { topSibling = scene()->items().first()->topLevelItem(); } Q_ASSERT(topSibling->parentItem() == parentItem()); setZValue(topSibling->zValue() + 1); }
bool MInverseMouseArea::isClickedOnSoftwareInputPanel(QGraphicsSceneMouseEvent *event) const { QGraphicsItem * item = scene()->itemAt(event->scenePos()); while(item != NULL) { QDeclarativeItem * declItem = dynamic_cast<QDeclarativeItem *>(item); if(declItem != NULL && declItem->objectName() == "softwareInputPanel") return true; item = item->parentItem(); } return false; }
bool ControlFlowItem::showAsControlFlow() const { QGraphicsItem* item = parentItem(); while (item) { VMethodCF* met = dynamic_cast<VMethodCF*> (item); if (met) return met->style()->showAsControlFlow(); item = item->parentItem(); } return false; }
int ThymioScene::getFocusItemId() const { QGraphicsItem *item = focusItem(); while( item != 0 ) { if( item->data(0).toString() == "buttonset" ) return thymioCompiler.buttonToCode(item->data(1).toInt()); else item = item->parentItem(); } return -1; }
// Object Observer Interface void dmz::QtPluginCanvasLink::link_objects ( const Handle LinkHandle, const Handle AttributeHandle, const UUID &SuperIdentity, const Handle SuperHandle, const UUID &SubIdentity, const Handle SubHandle) { if (_canvasModule) { if (_linkAttrTable.lookup (AttributeHandle)) { QGraphicsItem *superItem (_canvasModule->lookup_item (SuperHandle)); QGraphicsItem *subItem (_canvasModule->lookup_item (SubHandle)); if (superItem && subItem) { LinkStruct *os (new LinkStruct ( LinkHandle, AttributeHandle, SuperHandle, SubHandle, _penWidth, _arrowMultiplier)); if (_linkTable.store (LinkHandle, os)) { Float32 minZ (qMin (superItem->zValue (), subItem->zValue ())); os->item->setZValue (minZ - 1.0f); String name ("Link"); name << "." << AttributeHandle << "." << LinkHandle; os->item->setData (QtCanvasObjectNameIndex, name.get_buffer ()); _store_edge (SuperHandle, os->item); _store_edge (SubHandle, os->item); _canvasModule->add_item (LinkHandle, os->item); QGraphicsItem *superParent = superItem->parentItem (); if (superParent) { os->item->setParentItem (superParent); } } else { delete os; os = 0; } } } } }
void QGraphicsMozView::forceViewActiveFocus() { QGraphicsItem *parent = parentItem(); while (parent) { if (parent->flags() & QGraphicsItem::ItemIsFocusScope) parent->setFocus(Qt::OtherFocusReason); parent = parent->parentItem(); } setFocus(Qt::OtherFocusReason); if (d->mViewInitialized) { d->mView->SetIsActive(true); } }
void GraphViewer::onSceneMouseRelease(QGraphicsSceneMouseEvent *mouseEvent) { // need to put the connecting line on the background otherwise it is detected under the mouse _drawingEdge->setZValue(EDGE_LINE_Z); QGraphicsItem * item = _scene.itemAt(mouseEvent->scenePos(), QTransform()); if (qgraphicsitem_cast<QGraphicsEllipseItem*>(item) || qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)) { QGraphicsEllipseItem* vertex = qgraphicsitem_cast<QGraphicsEllipseItem*>(item->parentItem()); if (!vertex) vertex = qgraphicsitem_cast<QGraphicsEllipseItem*>(item); if (vertex) { double x = _drawingEdge->transform().dx(); double y = _drawingEdge->transform().dy(); _drawingEdge->setLine(0.0,0.0, vertex->scenePos().x()-x, vertex->scenePos().y()-y); _drawingEdge->setZValue(EDGE_LINE_Z); if (_drawingEdge->data(KEY_EDGE_VERTEX1) == vertex->data(KEY_EDGE_VERTEX1)) _scene.removeItem(_drawingEdge); else { int defaultWeight = 1; _drawingEdge->setData(KEY_EDGE_VERTEX2, vertex->data(KEY_VERTEX_ID)); _drawingEdge->setData(KEY_EDGE_WEIGHT, defaultWeight); // draw edge weight QGraphicsSimpleTextItem * edgeWeight = _scene.addSimpleText(QString("%1").arg(defaultWeight)); edgeWeight->setParentItem(_drawingEdge); edgeWeight->setBrush(Qt::blue); QLineF line = _drawingEdge->line(); edgeWeight->setTransform( QTransform::fromScale(0.005, 0.005) * QTransform::fromTranslate(line.x2()*0.5, line.y2()*0.5) ); edgeWeight->setZValue(EDGE_TEXT_Z); // add to graph edges _edges << _drawingEdge; } } } else { _scene.removeItem(_drawingEdge); } _isDrawingEdge=false; _drawingEdge=0; }
void neuralScene::mouseMoveEvent( QGraphicsSceneMouseEvent * event ) { if (mode == STANDARD) { QGraphicsScene::mouseMoveEvent(event); } if (mode == SYNAPSECREATION) { QGraphicsItem *item = itemAt(event->scenePos(), QTransform()); neuronItem* neuron = qgraphicsitem_cast<neuronItem*>(item); if (item!=0 and neuron==0) neuron = qgraphicsitem_cast<neuronItem*>(item->parentItem()); if (neuron==0) { tempSynapse->setTempPos(event->scenePos()); } else { tempSynapse->setTempPos(neuron->pos()); } } }
bool StarView::event (QEvent* e) { if (e->type() != QEvent::ToolTip) return QWidget::event(e); QPoint p (static_cast<QHelpEvent*>(e)->pos()); HostItem *item = 0; QGraphicsItem* graphicsItem = m_canvasView->itemAt(p); if (graphicsItem) item = dynamic_cast<HostItem*>(graphicsItem->parentItem()); if (item) { HostInfo *hostInfo = item->hostInfo(); const QPoint gp(static_cast<QHelpEvent*>(e)->globalPos()); const QRect itemRect = m_canvasView->mapFromScene(graphicsItem->sceneBoundingRect()).boundingRect(); if (hostInfo) { QToolTip::showText(gp+QPoint(10,10), "<p><table><tr><td>" "<img align=\"right\" source=\":/computer.png\"><br><b>" + item->hostName() + "</b><br>" + "<table>" + "<tr><td>" + tr("IP:") + "</td><td>" + hostInfo->ip() + "</td></tr>" + "<tr><td>" + tr("Platform:") + "</td><td>" + hostInfo->platform() + "</td></tr>" + "<tr><td>" + tr("Id:") + "</td><td>" + QString::number(hostInfo->id()) + "</td></tr>" + "<tr><td>" + tr("Speed:") + "</td><td>" + QString::number(hostInfo->serverSpeed()) + "</td></tr>" + "</table>" "</td></tr></table></p>", this, itemRect); } else { QToolTip::showText(gp+QPoint(10,10), "<p><table><tr><td>" "<img align=\"right\" source=\":/computer.png\"><br><b>" + tr("Scheduler") + "</b><br/>" "<table>" + "<tr><td>" + tr("Host: %1").arg(hostInfoManager()->schedulerName()) + "</td></tr>" + "<tr><td>" + tr("Network name: %1").arg(hostInfoManager()->networkName()) + "</td></tr>" + "</table>" "</td></tr></table></p>", this, itemRect); } } else { QToolTip::hideText(); } return QWidget::event(e); }
QPointF RenderedItemInterface::absolutePixelPos() const { QGraphicsItem * parent = parentItem(); QPointF itemPixelpos = convertUnit(d_ptr->rect.topLeft(), d_ptr->unit, Pixel, d_ptr->dpi); while (parent) { if (parent->type() == RenderedPageInterface::Type) { // QPointF pageAbsPos = parent->mapToScene(QPointF(0,0)); QPointF itemMapped = parent->mapToScene(itemPixelpos); return itemMapped; } parent = parent->parentItem(); } return itemPixelpos; }
void BezierDisplay::initDisplay(QGraphicsItem * master, Bezier *bezier) { //DebugDialog::debug("adding bezier display"); static int activeColor = 0xffffff; static int inactiveColor = 0xb0b0b0; QPen pen; pen.setWidth(0); QGraphicsItem * parent = master; while (parent->parentItem()) { parent = master->parentItem(); } // put the feeback on top double z = parent->zValue() + 100; // (ViewLayer::getZIncrement() / 2) m_itemL0 = new QGraphicsLineItem(); pen.setColor(QColor(bezier->drag0() ? activeColor : inactiveColor)); m_itemL0->setPen(pen); m_itemL0->setPos(0, 0); m_itemL0->setZValue(z); master->scene()->addItem(m_itemL0); //m_itemE0 = new QGraphicsEllipseItem(); //m_itemE0->setPen(pen); //m_itemE0->setPos(0, 0); //m_itemE0->setZValue(z); //master->scene()->addItem(m_itemE0); m_itemL1 = new QGraphicsLineItem(); pen.setColor(QColor(bezier->drag0() == false ? activeColor : inactiveColor)); m_itemL1->setPen(pen); m_itemL1->setPos(0, 0); m_itemL1->setZValue(z); master->scene()->addItem(m_itemL1); //m_itemE1 = new QGraphicsEllipseItem(); //m_itemE1->setPen(pen); //m_itemE1->setPos(0, 0); //m_itemE1->setZValue(z); //master->scene()->addItem(m_itemE1); updateDisplay(master, bezier); ProcessEventBlocker::processEvents(); }
AcaoMover::AcaoMover(QList<QGraphicsItem *> selecionados, QPointF deslocamento) { _items = selecionados; foreach(QGraphicsItem * item, _items) { QGraphicsItem * parent = item->parentItem(); while(parent) { if(_items.contains(parent)) { _items.removeOne(item); break; } parent = parent->parentItem(); } }
/*! \overload Handles the given mouse \a event. */ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); if (d->focusOnPress){ QGraphicsItem *p = parentItem();//###Is there a better way to find my focus scope? while(p) { if(p->flags() & QGraphicsItem::ItemIsFocusScope){ p->setFocus(); break; } p = p->parentItem(); } setFocus(true); } d->control->processEvent(event, QPointF(0, 0)); if (!event->isAccepted()) QDeclarativePaintedItem::mousePressEvent(event); }
void neuralScene::mousePressEvent( QGraphicsSceneMouseEvent* event) { if (mode == SYNAPSECREATION) { QGraphicsItem * item = itemAt(event->scenePos(), QTransform()); neuronItem* post = qgraphicsitem_cast<neuronItem*>(item); if (item!=0 and post==0) post = qgraphicsitem_cast<neuronItem*>(item->parentItem()); if (post != 0) { neuronItem* pre = tempSynapse->getPre(); emit synapseToAdd( post, pre); } //removeSynapseItem(tempSynapse); removeItem(tempSynapse); delete tempSynapse; tempSynapse = 0; mode = STANDARD; } else { QGraphicsScene::mousePressEvent(event); } }
void KReportDesignerSectionScene::mousePressEvent(QGraphicsSceneMouseEvent * e) { // clear the selection if Shift Key has not been pressed and it's a left mouse button and // if the right mouse button has been pressed over an item which is not part of selected items if (((e->modifiers() & Qt::ShiftModifier) == 0 && e->button() == Qt::LeftButton) || (!(selectedItems().contains(itemAt(e->scenePos(), QTransform()))) && e->button() == Qt::RightButton)) clearSelection(); //This will be caught by the section to display its properties, if an item is under the cursor then they will display their properties QGraphicsItem* itemUnderCursor = itemAt(e->scenePos(), QTransform()); if (!itemUnderCursor) { emit clicked(); } KReportDesignerItemRectBase *rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor); if (itemUnderCursor && !rectUnderCursor) { rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor->parentItem()); } exitInlineEditingModeInItems(rectUnderCursor); QGraphicsScene::mousePressEvent(e); }
void ezQtNodeScene::contextMenuEvent(QGraphicsSceneContextMenuEvent* contextMenuEvent) { QTransform id; QGraphicsItem* pItem = itemAt(contextMenuEvent->scenePos(), id); int iType = pItem != nullptr ? pItem->type() : -1; while (pItem && !(iType >= Type::Node && iType <= Type::Connection)) { pItem = pItem->parentItem(); iType = pItem != nullptr ? pItem->type() : -1; } ezQtSearchableMenu* pSearchMenu = nullptr; QMenu menu; if (iType == Type::Pin) { ezQtPin* pPin = static_cast<ezQtPin*>(pItem); QAction* pAction = new QAction("Disconnect Pin", &menu); menu.addAction(pAction); connect(pAction, &QAction::triggered, this, [this, pPin](bool bChecked) { DisconnectPinsAction(pPin); }); } else if (iType == Type::Node) { ezQtNode* pNode = static_cast<ezQtNode*>(pItem); // if we clicked on an unselected item, make it the only selected item if (!pNode->isSelected()) { clearSelection(); pNode->setSelected(true); } // Delete Node { QAction* pAction = new QAction("Remove", &menu); menu.addAction(pAction); connect(pAction, &QAction::triggered, this, [this](bool bChecked) { RemoveSelectedNodesAction(); }); } } else if (iType == Type::Connection) { ezQtConnection* pConnection = static_cast<ezQtConnection*>(pItem); QAction* pAction = new QAction("Delete Connection", &menu); menu.addAction(pAction); connect(pAction, &QAction::triggered, this, [this, pConnection](bool bChecked) { DisconnectPinsAction(pConnection); }); } else { pSearchMenu = new ezQtSearchableMenu(&menu); menu.addAction(pSearchMenu); connect(pSearchMenu, &ezQtSearchableMenu::MenuItemTriggered, this, &ezQtNodeScene::OnMenuItemTriggered); connect(pSearchMenu, &ezQtSearchableMenu::MenuItemTriggered, this, [&menu]() { menu.close(); }); ezStringBuilder sFullName; ezHybridArray<const ezRTTI*, 32> types; m_pManager->GetCreateableTypes(types); auto pos = contextMenuEvent->scenePos(); m_vPos = ezVec2(pos.x(), pos.y()); for (const ezRTTI* pRtti : types) { const char* szCleanName = pRtti->GetTypeName(); const char* szColonColon = ezStringUtils::FindLastSubString(szCleanName, "::"); if (szColonColon != nullptr) szCleanName = szColonColon + 2; const char* szUnderscore = ezStringUtils::FindLastSubString(szCleanName, "_"); if (szUnderscore != nullptr) szCleanName = szUnderscore + 1; sFullName = m_pManager->GetTypeCategory(pRtti); sFullName.AppendPath(szCleanName); pSearchMenu->AddItem(sFullName, qVariantFromValue((void*)pRtti)); } pSearchMenu->Finalize(m_sContextMenuSearchText); } menu.exec(contextMenuEvent->screenPos()); if (pSearchMenu) { m_sContextMenuSearchText = pSearchMenu->GetSearchText(); } }
bool QtPrinterTableView::print() { Q_D(QtPrinterTableView); if (! d->printer->isValid()) { qWarning() << "QtPrinterTableView::print: printer not valid, please setup the printer before calling print"; return false; } // next use a view just for the filling of the options... QGraphicsScene scene; QtGraphicsTableView view; scene.addItem(&view); view.setModel(d->model); class QTableHeaderDataProvider2 : public QtGraphicsHeaderDataProvider { public: QTableHeaderDataProvider2(QtTableModelInterface *model_) : model(model_) {} QHash<int,QVariant> data(int logicalIndex, const QList<int> &roles) const { // ### call the model - temporary implementation QHash<int,QVariant> hash; for (int i = 0; i < roles.count(); ++i) if (roles.at(i) == Qt::DisplayRole) hash.insert(Qt::DisplayRole, logicalIndex + 1); return hash; } QtTableModelInterface *model; }; if (d->horizontalHeader) { QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Horizontal, &view); header->setDataProvider(new QTableHeaderDataProvider2(d->model)); header->copySections(*d->horizontalHeader); view.setHorizontalHeader(header); } if (d->verticalHeader) { QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Vertical, &view); header->setDataProvider(new QTableHeaderDataProvider2(d->model)); header->copySections(*d->verticalHeader); view.setVerticalHeader(header); } QPainter painter; if (!painter.begin(d->printer)) { qWarning() << "QtPrinterTableView::print: printer fails to begin(), sorry can't print"; return false; } // re-layout the header footer to the current page size. if (d->header) { d->header->documentLayout()->setPaintDevice(d->printer); d->header->setPageSize(d->printer->pageRect().size()); } if (d->footer) { d->footer->documentLayout()->setPaintDevice(d->printer); d->footer->setPageSize(d->printer->pageRect().size()); } const qreal headerSize = d->printHeader(painter); const qreal footerSize = d->printFooter(painter); const bool vertical = d->orientation == Qt::Vertical; const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); painter.scale(scaleX, scaleY); const QRect rect = d->printer->pageRect(); QSizeF visibleSize(rect.width() / scaleX, rect.height() / scaleY); if (vertical) visibleSize = QSizeF(visibleSize.width(), visibleSize.height() - headerSize - footerSize); else // then rotate it. visibleSize = QSizeF(visibleSize.height() - headerSize - footerSize, visibleSize.width()); view.setGeometry(0, 0, visibleSize.width(), visibleSize.height()); view.setHorizontalOffset(0); int row = 0; int column; bool first = true; qreal offsetInColumn = 0; // for those columns too wide and thus split over more than one page while (row < d->model->rowCount()) { column = 0; view.setFirstRow(row); qreal height = visibleSize.height(); while (true) { const qreal rowHeight = view.rowHeight(row); if (height - rowHeight < 0) break; if (row >= d->model->rowCount()) break; ++row; height -= rowHeight; } while (column < d->model->columnCount()) { if (!first) { d->printer->newPage(); d->printHeader(painter); d->printFooter(painter); } first = false; view.setFirstColumn(column); view.setHorizontalOffset(offsetInColumn); qreal width = visibleSize.width(); while (true) { const qreal columnWidth = view.columnWidth(column); if (width == visibleSize.width() && columnWidth - offsetInColumn > visibleSize.width()) { // the column doesn't fit on a page. Lets split it. offsetInColumn += visibleSize.width(); width = 0; break; } else if (offsetInColumn > 0) { // we still have a part of a split column to print! width -= columnWidth - offsetInColumn; offsetInColumn = 0; ++column; continue; } if (width - columnWidth + offsetInColumn < 0) break; if (column >= d->model->columnCount()) break; ++column; width -= columnWidth; } view.doLayout(); painter.save(); // for each page painter.translate(0, headerSize); if (!vertical) { painter.translate(0, visibleSize.width()); painter.rotate(-90); } #ifdef DEBUG_TABLES painter.setPen(QPen(QColor(Qt::green))); painter.drawRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); #endif painter.setClipRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); // find and paint children which are the cells QList<QGraphicsItem*> items = scene.items(view.rect()); QList<QGraphicsItem*>::Iterator iter = items.begin(); for (;iter != items.end(); ++iter) { QGraphicsItem *parent = *iter; while (parent != &view && parent != 0) // only draw children of our view parent = parent->parentItem(); if (parent == 0) continue; if (!(*iter)->isVisible()) continue; painter.save(); painter.translate((*iter)->mapToItem(&view, QPointF())); #ifdef DEBUG_TABLES QGraphicsWidget *w = dynamic_cast<QGraphicsWidget*>(*iter); if (w) { painter.save(); painter.setPen(QPen(QColor(Qt::red))); painter.drawRect(QRectF(QPointF(), w->size())); painter.restore(); } #endif (*iter)->paint(&painter, 0); painter.restore(); } painter.restore(); // for each page } } return true; }
void GraphViewer::onSceneMousePress(QGraphicsSceneMouseEvent *mouseEvent) { if (_vertices.isEmpty()) _initialText->setVisible(false); if (_scene.items(QRectF( mouseEvent->scenePos().x() - VERTEX_SIZE*0.5, mouseEvent->scenePos().y() - VERTEX_SIZE*0.5, VERTEX_SIZE, VERTEX_SIZE) ).isEmpty()) { // Create new vertex QGraphicsEllipseItem * vertex = _scene.addEllipse( QRectF(-VERTEX_SIZE*0.5, -VERTEX_SIZE*0.5, VERTEX_SIZE, VERTEX_SIZE), QPen(Qt::black, 0), QBrush(Qt::white) ); vertex->setTransform( QTransform::fromTranslate(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()) ); vertex->setZValue(VERTEX_CIRCLE_Z); _vertices << vertex; int id = _vertices.size()-1; vertex->setData(KEY_VERTEX_ID, id); QGraphicsSimpleTextItem * vertexId = _scene.addSimpleText(QString("%1").arg(id+1)); vertexId->setParentItem(vertex); vertexId->setTransform( QTransform::fromScale(0.005, 0.005) * QTransform::fromTranslate(-VERTEX_SIZE*( (id < 9) ? 0.18 : 0.28 ), -VERTEX_SIZE*0.35) ); vertexId->setZValue(VERTEX_TEXT_Z); } else { // Propose to draw new edge QGraphicsItem * item = _scene.itemAt(mouseEvent->scenePos(), QTransform()); if (qgraphicsitem_cast<QGraphicsEllipseItem*>(item) || qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)) { QGraphicsEllipseItem* vertex = qgraphicsitem_cast<QGraphicsEllipseItem*>(item->parentItem()); if (!vertex) vertex = qgraphicsitem_cast<QGraphicsEllipseItem*>(item); if (vertex) { _isDrawingEdge=true; _drawingEdge = _scene.addLine(0.0, 0.0, mouseEvent->scenePos().x()-vertex->scenePos().x(), mouseEvent->scenePos().y()-vertex->scenePos().y(), QPen(Qt::black, 0)); _drawingEdge->setTransform(QTransform::fromTranslate(vertex->scenePos().x(), vertex->scenePos().y())); _drawingEdge->setZValue(VERTEX_CIRCLE_Z); _drawingEdge->setData(KEY_EDGE_VERTEX1, vertex->data(KEY_VERTEX_ID)); } } } }
/* * TODO: * ==== * - display value of a port (nice to have) * - triangle port (nice to have) * - mouse over (over a node or port) (nice to have) * - round shaped nodes (nice to have) */ namespace Magus { //****************************************************************************/ QtNodeEditor::QtNodeEditor(QWidget* parent) : QWidget(parent) { QVBoxLayout* mainLayout = new QVBoxLayout; mView = new QGraphicsView(this); mScene = new QtNodeGraphicsScene(); mScene->installEventFilter(this); mView->setScene(mScene); mView->setRenderHint(QPainter::Antialiasing, true); mView->setInteractive(true); mView->setMouseTracking(true); mainLayout->addWidget(mView); mLastRemovedNode = 0; mRubberBand = 0; mZoom = 1.0f; mFisheyeViewEnabled = false; mFisheyeMaxZoom = 1.0f; mFisheyeSteps = 5; mHeaderTitleIcon = NODE_HEADER_COMPOUND_ICON; mAction1Icon = NODE_HEADER_ACTION1_ICON; mAction2Icon = NODE_HEADER_ACTION2_ICON; mCompoundNodeDropped = 0; mRubberbandSelection = false; mContextMenuEnabled = true; mContextMenu = new QMenu(this); mContextMenu->addAction(new QAction(NODE_ACTION_DELETE, this)); mContextMenu->addAction(new QAction(NODE_ACTION_CENTER, this)); mZoomSubMenu = mContextMenu->addMenu(NODE_ACTION_ZOOM); QAction* action; QActionGroup actionGroupZoom(mZoomSubMenu); actionGroupZoom.setExclusive(true); action = new QAction(NODE_ACTION_ZOOM_10, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_25, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_50, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_75, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_90, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_100, this); action->setCheckable(true); action->setChecked(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_150, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_200, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_250, this); action->setCheckable(true); actionGroupZoom.addAction(action); action = new QAction(NODE_ACTION_ZOOM_300, this); action->setCheckable(true); actionGroupZoom.addAction(action); mZoomSubMenu->addActions(actionGroupZoom.actions()); mFisheyeViewSubMenu = mContextMenu->addMenu(NODE_ACTION_FISHEY_VIEW); QActionGroup actionGroupFisheye(mFisheyeViewSubMenu); actionGroupFisheye.setExclusive(true); action = new QAction(NODE_ACTION_FISHEYE_DISABLED, this); action->setCheckable(true); action->setChecked(true); actionGroupFisheye.addAction(action); action = new QAction(NODE_ACTION_FISHEYE_NORMAL, this); action->setCheckable(true); actionGroupFisheye.addAction(action); action = new QAction(NODE_ACTION_FISHEYE_NORMAL_SUBTLE, this); action->setCheckable(true); actionGroupFisheye.addAction(action); action = new QAction(NODE_ACTION_FISHEYE_LARGE, this); action->setCheckable(true); actionGroupFisheye.addAction(action); action = new QAction(NODE_ACTION_FISHEYE_LARGE_SUBTLE, this); action->setCheckable(true); actionGroupFisheye.addAction(action); mFisheyeViewSubMenu->addActions(actionGroupFisheye.actions()); mContextMenu->addAction(new QAction(NODE_ACTION_SELECTED_TO_COMPOUND, this)); mContextMenu->addAction(new QAction(NODE_ACTION_COLLAPSE_ALL, this)); mContextMenu->addAction(new QAction(NODE_ACTION_EXPAND_ALL, this)); mContextMenu->addAction(new QAction(NODE_ACTION_EXPAND_COMPOUNDS, this)); mContextMenu->addAction(new QAction(NODE_ACTION_CENTER, this)); setMenuZoomEnabled(true); setMenuSelectionToCompoundEnabled(true); setMenuCollapseExpandEnabled(true); setMenuExpandCompoundsEnabled(true); setMenuFisheyeViewEnabled(true); setContextMenuPolicy(Qt::CustomContextMenu); connect(mContextMenu, SIGNAL(triggered(QAction*)), this, SLOT(contextMenuItemSelected(QAction*))); setLayout(mainLayout); } //****************************************************************************/ QtNodeEditor::~QtNodeEditor(void) { } //****************************************************************************/ void QtNodeEditor::setContextMenuEnabled(bool enabled) { mContextMenuEnabled = enabled; } //****************************************************************************/ void QtNodeEditor::setCompoundHeaderTitleIcon(const QString& fileNameIcon) { mHeaderTitleIcon = fileNameIcon; } //****************************************************************************/ void QtNodeEditor::setCompoundAction1Icon(const QString& fileNameIcon) { mAction1Icon = fileNameIcon; } //****************************************************************************/ void QtNodeEditor::setCompoundAction2Icon(const QString& fileNameIcon) { mAction2Icon = fileNameIcon; } //****************************************************************************/ bool QtNodeEditor::isContextMenuEnabled(void) { return mContextMenuEnabled; } //****************************************************************************/ void QtNodeEditor::setMenuZoomEnabled(bool enabled) { mMenuZoomEnabled = enabled; QAction* action = getActionFromContextMenu(NODE_ACTION_ZOOM); if (action) action->setVisible(enabled); } //****************************************************************************/ bool QtNodeEditor::isMenuZoomEnabled(void) { return mMenuZoomEnabled; } //****************************************************************************/ void QtNodeEditor::setMenuSelectionToCompoundEnabled(bool enabled) { mMenuSelectionToCompoundEnabled = enabled; QAction* action = getActionFromContextMenu(NODE_ACTION_SELECTED_TO_COMPOUND); if (action) action->setVisible(enabled); } //****************************************************************************/ bool QtNodeEditor::isMenuSelectionToCompoundEnabled(void) { return mMenuSelectionToCompoundEnabled; } //****************************************************************************/ void QtNodeEditor::setMenuCollapseExpandEnabled(bool enabled) { mMenuCollapseExpandEnabled = enabled; QAction* action = getActionFromContextMenu(NODE_ACTION_EXPAND_ALL); if (action) action->setVisible(enabled); action = getActionFromContextMenu(NODE_ACTION_COLLAPSE_ALL); if (action) action->setVisible(enabled); } //****************************************************************************/ bool QtNodeEditor::isMenuCollapseExpandEnabled(void) { return mMenuCollapseExpandEnabled; } //****************************************************************************/ void QtNodeEditor::setMenuExpandCompoundsEnabled(bool enabled) { mMenuExpandCompoundsEnabled = enabled; QAction* action = getActionFromContextMenu(NODE_ACTION_EXPAND_COMPOUNDS); if (action) action->setVisible(enabled); } //****************************************************************************/ bool QtNodeEditor::isMenuExpandCompoundsEnabled(void) { return mMenuExpandCompoundsEnabled; } //****************************************************************************/ void QtNodeEditor::setMenuFisheyeViewEnabled(bool enabled) { mMenuFisheyeViewEnabled = enabled; QAction* action = getActionFromContextMenu(NODE_ACTION_FISHEY_VIEW); if (action) action->setVisible(enabled); } //****************************************************************************/ bool QtNodeEditor::isMenuFisheyeViewEnabled(void) { return mMenuFisheyeViewEnabled; } //****************************************************************************/ void QtNodeEditor::setFisheyeView(bool enabled, qreal maxZoom, unsigned int steps) { mFisheyeViewEnabled = enabled; mFisheyeMaxZoom = maxZoom; mFisheyeSteps = steps; } //****************************************************************************/ QGraphicsItem* QtNodeEditor::itemAtExceptActiveConnection(const QPointF& pos) { QList<QGraphicsItem*> items = mScene->items(QRectF(pos - QPointF(1,1), QSize(3,3))); bool isActive = isActiveConnection(); foreach(QGraphicsItem* item, items) { // If there is an active connection, it is not returned as a selected item // Finalized (established) connections are returned if (item->isVisible()) { if (isConnection(item)) { if (!isActive) return item; } else return item; } } return 0; } //****************************************************************************/ QtCompoundNode* QtNodeEditor::nodeOverCompound(QtNode* node) { if (!node) return 0; QtCompoundNode* compound; QList<QGraphicsItem*> items = mScene->items(); int subType; qreal halfWidth; foreach(QGraphicsItem* item, items) { if (isCompoundNode(item) && item->isVisible()) { compound = static_cast<QtCompoundNode*>(item); if (node != compound && !compound->isSelected()) { halfWidth = 0.5 * compound->getWidth(); if (node->scenePos().x() > compound->scenePos().x() - halfWidth && node->scenePos().x() < compound->scenePos().x() + halfWidth && node->scenePos().y() > compound->scenePos().y() && node->scenePos().y() < compound->scenePos().y() + compound->getHeigth()) { return compound; } } } } return 0; } //****************************************************************************/ bool QtNodeEditor::eventFilter(QObject* object, QEvent* event) { QGraphicsSceneMouseEvent* mouseEvent = (QGraphicsSceneMouseEvent*) event; QGraphicsItem* item = 0; switch ((int) event->type()) { case QEvent::GraphicsSceneMousePress: mouseClickHandler(mouseEvent); break; case QEvent::GraphicsSceneMouseDoubleClick: mouseDoubleClickHandler(mouseEvent); break; case QEvent::GraphicsSceneMouseMove: { mouseMoveHandler(mouseEvent); } break; case QEvent::GraphicsSceneMouseRelease: { mouseReleaseHandler(mouseEvent); } break; } return QObject::eventFilter(object, event); } //****************************************************************************/ bool QtNodeEditor::mouseClickHandler(QGraphicsSceneMouseEvent* mouseEvent) { switch ((int) mouseEvent->button()) { case Qt::LeftButton: { QGraphicsItem* item = itemAtExceptActiveConnection(mouseEvent->scenePos()); if (!item) { // Left-click on the canvas, but no item clicked, so deselect nodes and connections deselectAll(); mRubberbandSelection = true; mLastMousePosition.setX(mouseEvent->lastScenePos().x()); mLastMousePosition.setY(mouseEvent->lastScenePos().y()); return true; } mRubberbandSelection = false; // Delegate to the node; either the node itself is clicked, one of its children or a connection QtNode* node; int type = 0; if (item->data(NODE_KEY_GRAPHIC_ITEM_TYPE).isValid()) { type = item->data(NODE_KEY_GRAPHIC_ITEM_TYPE).toInt(); if (NODE_VALUE_TYPE_CONNECTION == type) { // ======================= Handle selected connection ======================= QtConnection* connection = static_cast<QtConnection*>(item); selectConnection(connection); } else if (NODE_VALUE_TYPE_NODE == type) { // ======================= The node itself is clicked ======================= node = static_cast<QtNode*>(item); selectNode(node, mouseEvent); } else if (NODE_VALUE_TYPE_HEADER_ICON == type || NODE_VALUE_TYPE_HEADER_TITLE == type) { // ======================= The header title or header icon is clicked ======================= node = static_cast<QtNode*>(item->parentItem()); selectNode(node, mouseEvent); } else { // A child item of the node is clicked deselectNodes(); deselectConnections(); node = static_cast<QtNode*>(item->parentItem()); if (NODE_VALUE_TYPE_PORT == type) { // ======================= Port is clicked ======================= // Either make a connection to another port, or create a new connection QtNode* baseNode = getNodeWithActiveConnection(); if (baseNode == 0) { // There is no active connection, so start one node->mouseLeftClickHandler(mouseEvent, item, NODE_ACTION_BASE); setCursor(Qt::ClosedHandCursor); } else if (baseNode != node) { // There is an active connection and the selected port is not part of the baseNode, // so try to establish a connection with the other node if (node->mouseLeftClickHandler(mouseEvent, item, NODE_ACTION_TARGET, baseNode->mActiveConnection)) { // The connection was established, so the active connection on the basenode can be set to 0 baseNode->mActiveConnection = 0; setCursor(Qt::ArrowCursor); } } } else { node->mouseLeftClickHandler(mouseEvent, item); // Don't do anything with the node after this; it may be deleted } } return true; } } break; case Qt::RightButton: { if (mContextMenuEnabled) { QPoint pos; pos.setX(mouseEvent->lastScreenPos().x()); pos.setY(mouseEvent->lastScreenPos().y()); showContextMenu(pos); } else deselectAll(); return true; } break; } //mouseEvent->accept(); return true; }