276 lines
7.8 KiB
C++
276 lines
7.8 KiB
C++
|
|
#include "designerScene.h"
|
|||
|
|
#include "util/selectorManager.h"
|
|||
|
|
#include "graphicsItem/graphicsItemGroup.h"
|
|||
|
|
#include "drawingPanel.h"
|
|||
|
|
|
|||
|
|
#include <QPainter>
|
|||
|
|
#include <QGraphicsSceneMouseEvent>
|
|||
|
|
#include <QtCore/QBuffer>
|
|||
|
|
#include <QtCore/QByteArray>
|
|||
|
|
#include <QtCore/QDataStream>
|
|||
|
|
#include <QtCore/QDebug>
|
|||
|
|
#include <QtCore/QFile>
|
|||
|
|
#include <QtCore/QJsonArray>
|
|||
|
|
#include <QtCore/QJsonDocument>
|
|||
|
|
#include <QtCore/QJsonObject>
|
|||
|
|
#include <QtCore/QtGlobal>
|
|||
|
|
|
|||
|
|
#include <QtWidgets/QFileDialog>
|
|||
|
|
#include <QtWidgets/QGraphicsSceneMoveEvent>
|
|||
|
|
#include <QtWidgets/QHeaderView>
|
|||
|
|
#include <QtWidgets/QLineEdit>
|
|||
|
|
#include <QtWidgets/QTreeWidget>
|
|||
|
|
#include <QtWidgets/QWidgetAction>
|
|||
|
|
|
|||
|
|
DesignerScene::DesignerScene(DataFlowGraphModel &graphModel, QObject *parent)
|
|||
|
|
: BasicGraphicsScene(graphModel,parent),
|
|||
|
|
m_pDrawingPanel(NULL),
|
|||
|
|
_graphModel(graphModel)
|
|||
|
|
{
|
|||
|
|
m_bGridVisible = true;
|
|||
|
|
m_pView = nullptr;
|
|||
|
|
m_pDrawingPanel = dynamic_cast<DrawingPanel*>(parent);
|
|||
|
|
|
|||
|
|
connect(&_graphModel,
|
|||
|
|
&DataFlowGraphModel::inPortDataWasSet,
|
|||
|
|
[this](NodeId const nodeId, PortType const, PortIndex const) { onNodeUpdated(nodeId); });
|
|||
|
|
}
|
|||
|
|
DesignerScene::~DesignerScene()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::drawBackground(QPainter* painter, const QRectF& rect)
|
|||
|
|
{
|
|||
|
|
QGraphicsScene::drawBackground(painter, rect);
|
|||
|
|
painter->fillRect(sceneRect(), Qt::white);
|
|||
|
|
if(!m_bGridVisible)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
QRectF sceneRect = this->sceneRect();
|
|||
|
|
QPen pen;
|
|||
|
|
pen.setBrush(Qt::darkCyan);//藏青色
|
|||
|
|
pen.setStyle(Qt::DashLine);
|
|||
|
|
pen.setWidthF(0.2);
|
|||
|
|
painter->setPen(pen);
|
|||
|
|
int nGridSpace = 20; //暂时写死
|
|||
|
|
//竖线
|
|||
|
|
for(int nX = sceneRect.left(); nX < sceneRect.right(); nX += nGridSpace)
|
|||
|
|
painter->drawLine(nX,sceneRect.top(),nX,sceneRect.bottom());
|
|||
|
|
//横线
|
|||
|
|
for(int nY = sceneRect.top(); nY < sceneRect.bottom(); nY += nGridSpace)
|
|||
|
|
painter->drawLine(sceneRect.left(),nY,sceneRect.right(),nY);
|
|||
|
|
//补齐最后两条
|
|||
|
|
painter->drawLine(sceneRect.right(), sceneRect.top(), sceneRect.right(), sceneRect.bottom());
|
|||
|
|
painter->drawLine(sceneRect.left(), sceneRect.bottom(), sceneRect.right(), sceneRect.bottom());
|
|||
|
|
|
|||
|
|
//原点
|
|||
|
|
// painter->setPen(Qt::red);
|
|||
|
|
// painter->setBrush(Qt::red);
|
|||
|
|
// painter->drawEllipse(0, 0, 50, 50);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)
|
|||
|
|
{
|
|||
|
|
if(m_pDrawingPanel)
|
|||
|
|
{
|
|||
|
|
m_pDrawingPanel->selectorManager()->getWorkingSelector()->mousePressEvent(mouseEvent, this);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
QGraphicsScene::mousePressEvent(mouseEvent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
|
|||
|
|
{
|
|||
|
|
if(m_pDrawingPanel)
|
|||
|
|
{
|
|||
|
|
m_pDrawingPanel->selectorManager()->getWorkingSelector()->mouseMoveEvent(mouseEvent, this);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent)
|
|||
|
|
{
|
|||
|
|
if(m_pDrawingPanel)
|
|||
|
|
{
|
|||
|
|
m_pDrawingPanel->selectorManager()->getWorkingSelector()->mouseReleaseEvent(mouseEvent, this);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent)
|
|||
|
|
{
|
|||
|
|
if(m_pDrawingPanel)
|
|||
|
|
{
|
|||
|
|
m_pDrawingPanel->selectorManager()->getWorkingSelector()->mouseDoubleClickEvent(mouseEvent, this);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::keyPressEvent(QKeyEvent* event)
|
|||
|
|
{
|
|||
|
|
QGraphicsScene::keyPressEvent(event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::keyReleaseEvent(QKeyEvent* event)
|
|||
|
|
{
|
|||
|
|
QGraphicsScene::keyReleaseEvent(event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::setGridVisible(bool bVisible)
|
|||
|
|
{
|
|||
|
|
m_bGridVisible = bVisible;
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::callParentEvent(QGraphicsSceneMouseEvent* mouseEvent)
|
|||
|
|
{
|
|||
|
|
//调用QGraphicsScene的函数,会直接触发一些操作,比如取消item的selected状态,从而触发item的一些函数(itemChange),然后在item的相应函数中书写执行一些操作
|
|||
|
|
switch (mouseEvent->type())
|
|||
|
|
{
|
|||
|
|
case QEvent::GraphicsSceneMousePress:
|
|||
|
|
QGraphicsScene::mousePressEvent(mouseEvent);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case QEvent::GraphicsSceneMouseMove:
|
|||
|
|
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case QEvent::GraphicsSceneMouseRelease:
|
|||
|
|
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GraphicsItemGroup* DesignerScene::createGroup()
|
|||
|
|
{
|
|||
|
|
QList<QGraphicsItem*> listItem = selectedItems();
|
|||
|
|
if(listItem.isEmpty())
|
|||
|
|
return nullptr;
|
|||
|
|
else if(listItem.count() == 1) //判断只选中了一个时是不是已经打组,如果是不做操作,防止循环打组
|
|||
|
|
{
|
|||
|
|
AbstractShape* item = qgraphicsitem_cast<AbstractShape*>(listItem.first());
|
|||
|
|
if(item && item->getType()==T_group)
|
|||
|
|
return nullptr;
|
|||
|
|
}
|
|||
|
|
else //如果选择的有组群,则拆散该组群,并和其它单独的itme组合成新组群,防止多层组群出现,方便管理和计算
|
|||
|
|
{
|
|||
|
|
for(int n=0; n<listItem.count(); n++)
|
|||
|
|
{
|
|||
|
|
AbstractShape* shape = qgraphicsitem_cast<AbstractShape*>(listItem[n]);
|
|||
|
|
if(shape && shape->getType()==T_group)
|
|||
|
|
{
|
|||
|
|
GraphicsItemGroup* group = qgraphicsitem_cast<GraphicsItemGroup*>(listItem[n]);
|
|||
|
|
QList<QGraphicsItem*> childItems = group->childItems();
|
|||
|
|
foreach (QGraphicsItem* child, childItems)
|
|||
|
|
{
|
|||
|
|
if(qgraphicsitem_cast<ItemControlHandle*>(child))
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
group->removeFromGroup(child);
|
|||
|
|
listItem.push_back(child);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
listItem.takeAt(n);
|
|||
|
|
removeItem(group);
|
|||
|
|
delete group;
|
|||
|
|
n--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GraphicsItemGroup* group = new GraphicsItemGroup();
|
|||
|
|
group->addItems(listItem);
|
|||
|
|
addItem(group);
|
|||
|
|
return group;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerScene::destroyGroup()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::vector<NodeId> DesignerScene::selectedNodes() const
|
|||
|
|
{
|
|||
|
|
QList<QGraphicsItem *> graphicsItems = selectedItems();
|
|||
|
|
|
|||
|
|
std::vector<NodeId> result;
|
|||
|
|
result.reserve(graphicsItems.size());
|
|||
|
|
|
|||
|
|
/*for (QGraphicsItem *obj : graphicsItems) {
|
|||
|
|
auto ngo = qgraphicsitem_cast<NodeGraphicsObject *>(obj);
|
|||
|
|
|
|||
|
|
if (ngo != nullptr) {
|
|||
|
|
result.push_back(ngo->nodeId());
|
|||
|
|
}
|
|||
|
|
}*/
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QMenu *DesignerScene::createSceneMenu(QPointF const scenePos)
|
|||
|
|
{
|
|||
|
|
QMenu *modelMenu = new QMenu();
|
|||
|
|
|
|||
|
|
// QMenu's instance auto-destruction
|
|||
|
|
modelMenu->setAttribute(Qt::WA_DeleteOnClose);
|
|||
|
|
|
|||
|
|
return modelMenu;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool DesignerScene::save() const
|
|||
|
|
{
|
|||
|
|
QString fileName = QFileDialog::getSaveFileName(nullptr,
|
|||
|
|
tr("Open Flow Scene"),
|
|||
|
|
QDir::homePath(),
|
|||
|
|
tr("Flow Scene Files (*.flow)"));
|
|||
|
|
|
|||
|
|
if (!fileName.isEmpty()) {
|
|||
|
|
if (!fileName.endsWith("flow", Qt::CaseInsensitive))
|
|||
|
|
fileName += ".flow";
|
|||
|
|
|
|||
|
|
QFile file(fileName);
|
|||
|
|
if (file.open(QIODevice::WriteOnly)) {
|
|||
|
|
file.write(QJsonDocument(_graphModel.save()).toJson());
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool DesignerScene::load()
|
|||
|
|
{
|
|||
|
|
QString fileName = QFileDialog::getOpenFileName(nullptr,
|
|||
|
|
tr("Open Flow Scene"),
|
|||
|
|
QDir::homePath(),
|
|||
|
|
tr("Flow Scene Files (*.flow)"));
|
|||
|
|
|
|||
|
|
if (!QFileInfo::exists(fileName))
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
QFile file(fileName);
|
|||
|
|
|
|||
|
|
if (!file.open(QIODevice::ReadOnly))
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
clearScene();
|
|||
|
|
|
|||
|
|
QByteArray const wholeFile = file.readAll();
|
|||
|
|
|
|||
|
|
_graphModel.load(QJsonDocument::fromJson(wholeFile).object());
|
|||
|
|
|
|||
|
|
Q_EMIT sceneLoaded();
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|