#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;
};