// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "diagramscene.h" #include "arrow.h" #include #include //! [0] DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent) : QGraphicsScene(parent) { myItemMenu = itemMenu; myMode = MoveItem; myItemType = DiagramItem::Step; line = nullptr; textItem = nullptr; myItemColor = Qt::white; myTextColor = Qt::black; myLineColor = Qt::black; } //! [0] //! [1] void DiagramScene::setLineColor(const QColor &color) { myLineColor = color; if (isItemChange(Arrow::Type)) { Arrow *item = qgraphicsitem_cast(selectedItems().first()); item->setColor(myLineColor); update(); } } //! [1] //! [2] void DiagramScene::setTextColor(const QColor &color) { myTextColor = color; if (isItemChange(DiagramTextItem::Type)) { DiagramTextItem *item = qgraphicsitem_cast(selectedItems().first()); item->setDefaultTextColor(myTextColor); } } //! [2] //! [3] void DiagramScene::setItemColor(const QColor &color) { myItemColor = color; if (isItemChange(DiagramItem::Type)) { DiagramItem *item = qgraphicsitem_cast(selectedItems().first()); item->setBrush(myItemColor); } } //! [3] //! [4] void DiagramScene::setFont(const QFont &font) { myFont = font; if (isItemChange(DiagramTextItem::Type)) { QGraphicsTextItem *item = qgraphicsitem_cast(selectedItems().first()); //At this point the selection can change so the first selected item might not be a DiagramTextItem if (item) item->setFont(myFont); } } //! [4] void DiagramScene::setMode(Mode mode) { myMode = mode; } void DiagramScene::setItemType(DiagramItem::DiagramType type) { myItemType = type; } //! [5] void DiagramScene::editorLostFocus(DiagramTextItem *item) { QTextCursor cursor = item->textCursor(); cursor.clearSelection(); item->setTextCursor(cursor); if (item->toPlainText().isEmpty()) { removeItem(item); item->deleteLater(); } } //! [5] //! [6] void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (mouseEvent->button() != Qt::LeftButton) return; DiagramItem *item; switch (myMode) { case InsertItem: item = new DiagramItem(myItemType, myItemMenu); item->setBrush(myItemColor); addItem(item); item->setPos(mouseEvent->scenePos()); emit itemInserted(item); break; //! [6] //! [7] case InsertLine: line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(), mouseEvent->scenePos())); line->setPen(QPen(myLineColor, 2)); addItem(line); break; //! [7] //! [8] case InsertText: textItem = new DiagramTextItem(); textItem->setFont(myFont); textItem->setTextInteractionFlags(Qt::TextEditorInteraction); textItem->setZValue(1000.0); connect(textItem, &DiagramTextItem::lostFocus, this, &DiagramScene::editorLostFocus); connect(textItem, &DiagramTextItem::selectedChange, this, &DiagramScene::itemSelected); addItem(textItem); textItem->setDefaultTextColor(myTextColor); textItem->setPos(mouseEvent->scenePos()); emit textInserted(textItem); //! [8] //! [9] default: ; } QGraphicsScene::mousePressEvent(mouseEvent); } //! [9] //! [10] void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (myMode == InsertLine && line != nullptr) { QLineF newLine(line->line().p1(), mouseEvent->scenePos()); line->setLine(newLine); } else if (myMode == MoveItem) { QGraphicsScene::mouseMoveEvent(mouseEvent); } } //! [10] //! [11] void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (line != nullptr && myMode == InsertLine) { QList startItems = items(line->line().p1()); if (startItems.count() && startItems.first() == line) startItems.removeFirst(); QList endItems = items(line->line().p2()); if (endItems.count() && endItems.first() == line) endItems.removeFirst(); removeItem(line); delete line; //! [11] //! [12] if (startItems.count() > 0 && endItems.count() > 0 && startItems.first()->type() == DiagramItem::Type && endItems.first()->type() == DiagramItem::Type && startItems.first() != endItems.first()) { DiagramItem *startItem = qgraphicsitem_cast(startItems.first()); DiagramItem *endItem = qgraphicsitem_cast(endItems.first()); Arrow *arrow = new Arrow(startItem, endItem); arrow->setColor(myLineColor); startItem->addArrow(arrow); endItem->addArrow(arrow); arrow->setZValue(-1000.0); addItem(arrow); arrow->updatePosition(); } } //! [12] //! [13] line = nullptr; QGraphicsScene::mouseReleaseEvent(mouseEvent); } //! [13] //! [14] bool DiagramScene::isItemChange(int type) const { const QList items = selectedItems(); const auto cb = [type](const QGraphicsItem *item) { return item->type() == type; }; return std::find_if(items.begin(), items.end(), cb) != items.end(); } //! [14]