#pragma once #include "Common.h" #include "CommonDraw.h" #include "Pou.h" #include "VPCommand.h" class WindowAppBlockPort; class WindowAppBlockStandard; class WindowAppBlockGoto; class WindowAppItemInterface; class WindowAppItemLink; class WindowAppPouFrame; class WindowAppBlockComment; class WindowAppBlockParallel; class WindowAppBlockForloop; class WindowAppBlockWait; /// /// 核心类,用于管理所有的绘图功能块 /// class WindowAppPouScene : public QGraphicsScene { Q_OBJECT public: explicit WindowAppPouScene(const QString& strTitle, QObject* parent = nullptr, QWidget* parentparent = nullptr); // 生成新的运行时工具信息(拖拽方式) WindowAppBlockBase* addToolItem(const STATIC_TOOL* pNewTool, QPointF pos); // 生成新的运行时工具信息(反序列化方式) WindowAppBlockBase* addToolItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 移除一个ToolItem void delToolItem(WindowAppBlockBase* pBlock); // 直接增加一个Port,并且连接 void addPortAndAutolink(WindowAppItemInterface* pLinkInf, const QLineF infRealLine); // 建立link void addLink( WindowAppItemInterface* pStartInf, WindowAppItemInterface* pEndInf, LINK_MODE linkMode = LINK_MODE::LINK_NORMAL, QVector linePoints = QVector() ); // 建立Link(根据接口全名) void addLink( const QString& strStartInf, const QString& strEndInf, LINK_MODE linkMode = LINK_MODE::LINK_NORMAL, QVector linePoints = QVector() ); // 删除指定link连线 void delLink(WindowAppItemLink* pLinkItem); // 根据接口删除link连线 void delLink(WindowAppItemInterface* pInf); // 根据接口名字删除link连线 void delLink(const QString& strInf); // 执行SmartLink void smartLink(WindowAppItemInterface* pInf); // 建立Goto到Tool的Link void addGotoLink(_INTERFACE* pGotoInf, const TOOL* pTool); // 建立Parallel到Tool的Link void addParallelLink(_INTERFACE* pParaInf, const TOOL* pTool); // 功能块序号 减 1 void BlockMoveUp(); // 功能块序号 加 1 void BlockMoveDown(); // 功能块序号 置1 void BlockMoveFirst(); // 功能块序号 置底 void BlockMoveLast(); // 功能块左对齐 void BlockAlignLeft(); // 功能块顶对齐 void BlockAlignTop(); // 功能块右对齐 void BlockAlignRight(); // 功能块底对齐 void BlockAlignBottom(); // 根据接口查询对应的Link连线 QList getLinkItemsByInfItem(WindowAppItemInterface* pInfItem) { return this->m_itemInfLinks.values(pInfItem); } public: // 获得本Scene所在的PouFrame(目前主要用于PouFrame的序列化) WindowAppPouFrame* parentFrame() { return m_pPouFrame; } // 本Scene所有的Pou管理单元 POU m_Pou; // 2022-10-5,本Scene的Undo管理单元 VPCommandManager m_CommandManager; // 当前的模式 SCENE_MODE m_sceneMode; public slots: // 鼠标双击 // void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override; void mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) override; void mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent) override; // block被移动时 void onBlockMove(QGraphicsItem* item); // 移除内容为空的注释控件 void removeEmptyBlockComment(WindowAppBlockComment* item); // 接收来自Dll端的动态端口同步消息 virtual void customEvent(QEvent* event) override; // 接收键盘消息 void keyPressEvent(QKeyEvent* event)override; // 接收键盘释放消息 void keyReleaseEvent(QKeyEvent* event)override; signals: // 某个item被选中时 void itemSelected(QGraphicsItem* item); protected: // 添加一个标准工具 WindowAppBlockStandard* addStandardItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 添加一个Port工具 WindowAppBlockPort* addPortItem(TOOL* pNewPort, QPointF pos, bool bFromDoc = false); // 添加一个Goto工具 WindowAppBlockGoto* addGotoItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 添加一个Comment工具 WindowAppBlockComment* addCommentItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 添加一个Parallel工具 WindowAppBlockParallel* addParallelItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 添加一个ForLoop工具 WindowAppBlockForloop* addForloopItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 添加一个Wait工具 WindowAppBlockWait* addWaitItem(TOOL* pNewTool, QPointF pos, bool bFromDoc = false); // 创建功能块 WindowAppBlockBase* createBlock(TOOL* pTool, const QPointF& pos, TOOL_TYPE toolType); // 开始执行Link动作 void startLink(WindowAppItemInterface* pStartInf, QPointF ptMouse); // 移动Link连接 void moveLink(QPointF ptMouse, bool blink ); // 结束Link动作 void endLink(QPointF ptMouse); // 进行连接预检查 int preLinkCheck(QPointF ptMouse, WindowAppItemInterface*& startItem, WindowAppItemInterface*& endItem); // 检查所有的接口连线是否需要刷新 void updateLinkItemsByBlock(QGraphicsItem* item); // 2022-5-8,检查并行母线是否需要刷新 void updateParallelLineByBlock(QGraphicsItem* item); // 2022-6-20,检查是否正在是多选之后的批量移动操作 bool checkBatchMove(); // 2022-8-26,添加完功能块Item后,初始化对应参数(Index、InstanceName、ToolInterface Name等) void initBlockItem(TOOL*& pNewTool, bool bInitIndex, bool bInitInstName, bool bInitToolInfName); private: // 所属的组名 QString m_strPouName; // 用于Link预览的连接线 QGraphicsLineItem* m_tmpLinkLine; // 内部使用结构体,用于存储LinkItem相关的详细信息 typedef struct _tagItemLinkInfo { bool bStart; // 是否位于Link的起点位置 WindowAppItemLink* pLink; // Link的指针 _tagItemLinkInfo() { bStart = false; pLink = nullptr; } bool operator==(const _tagItemLinkInfo& info)const { return this->bStart == info.bStart && this->pLink == info.pLink; } } ITEM_LINK_INFO; // block和对应的link信息(用于接口随着block随动) // 每个link会存储两条记录,起点和终点分别保存 // 同一个block会有多条记录 QMultiHash m_itemBlockLinks; // 接口和Link的对应信息 // 同一个接口可能会有多条记录 QMultiHash m_itemInfLinks; // 记录批量移动的LinkItem,用于进行批量移动使用 QList m_batchMoveLinks; // 键盘移动功能块的步长(动态步长) int m_nMoveBlockSleep; // 2022-1-8增加,PouFrame的指针(父亲的父亲) WindowAppPouFrame* m_pPouFrame; };