/** * @file logic_editor_widget.h * @brief 定义结构化梯形图编辑和运行轨迹画布 * @version 1.0.0 * @author suyu * @date 2026-08-22 */ #pragma once #include "domain/control_logic_model.h" #include "services/logic_editor_service.h" #include "services/software_logic_executor.h" #include #include #include #include class QGraphicsScene; class QResizeEvent; /** 将结构化梯形图表达式投影成网格图元;不保存自由线段,编辑通过服务提交 */ class LogicEditorWidget final : public QGraphicsView { Q_OBJECT public: /** 梯形图中的条件、输出、横线和辅助选择图元类型 */ class NodeItem; class WireItem; class WireCellItem; class VerticalConnectorItem; class RungItem; class EmptySlotItem; /** 创建梯形图画布并绑定编辑服务 */ explicit LogicEditorWidget( LogicEditorService &editor_service, QWidget *parent = nullptr); /** 切换当前显示的控制逻辑;不存在时显示空场景 */ void setLogicId(const std::string &logic_id); /** 设置是否允许编辑梯形图 */ void setEditingEnabled(bool enabled); /** 设置离线运行轨迹;真机模式应传入空轨迹,避免显示本地伪轨迹 */ void setRuntimeTrace( const LogicTraceSnapshot &trace, const std::string &fault_node_id = {}); /** 清除当前运行轨迹和故障节点标记 */ void clearRuntimeTrace(); /** 根据当前逻辑模型重建梯形图场景 */ void reloadLogic(); /** 选中指定节点并滚动到可见区域 */ void selectNode(const std::string &node_id); /** 返回当前选中的单个节点标识 */ std::string selectedNodeId() const; /** 返回当前选中的多个节点标识 */ std::vector selectedNodeIds() const; /** 返回当前选中的网络标识 */ std::string selectedRungId() const; /** 新增一个空的梯形图网络 */ LogicEditorResult addRung(); /** 将当前选择转换为服务调用并新增串联条件 */ LogicEditorResult addCondition(const LogicNodeConfig &config); /** 将当前选择转换为服务调用并新增并联支路 */ LogicEditorResult addParallelBranch(const LogicNodeConfig &config); /** 在当前选择位置新增横线 */ LogicEditorResult addHorizontalWire(); /** 在当前选择位置新增竖线 */ LogicEditorResult addVerticalWire(); /** 删除当前选择位置的横线 */ LogicEditorResult deleteHorizontalWire(); /** 删除当前选择位置的竖线 */ LogicEditorResult deleteVerticalWire(); /** 设置当前网络的输出线圈 */ LogicEditorResult setOutput( const LogicNodeConfig &config, bool configured = false); /** 按当前画布选择位置粘贴一组连续条件 */ LogicEditorResult pasteConditionNodes(const std::vector &nodes); /** 删除当前选中的节点、线段或网络 */ LogicEditorResult deleteSelected(); signals: /** 当前选中的节点发生变化时发出 */ void nodeSelected(const QString &node_id); /** 梯形图模型成功发生变化时发出 */ void graphChanged(); /** 编辑服务操作失败时发出可显示的错误信息 */ void editorError(const QString &message); protected: /** 在窗口大小变化后重新布局梯形图场景 */ void resizeEvent(QResizeEvent *event) override; private: /** 处理图形场景选择变化 */ void handleSelectionChanged(); /** 把编辑服务结果转换为错误信号 */ void reportFailure(const LogicEditorResult &result); /** 返回当前选中的网络标识 */ std::string currentRungId() const; /** 选中指定表达式图元 */ void selectExpression(const std::string &expression_id); /** 选中指定横线图元 */ void selectWire(const std::string &wire_id); /** 收集当前选中的表达式标识 */ std::vector selectedExpressionIds() const; /** 收集当前选中的横线标识 */ std::vector selectedWireIds() const; /** 收集当前选中的并联支路标识 */ std::vector selectedBranchIds() const; /** 收集当前选中的空网格位置 */ std::vector> selectedEmptySlots() const; /** 收集当前选中的横线网格位置 */ std::vector> selectedWireCells() const; /** 判断当前是否选中了网络内的图元 */ bool hasSelectedRungItem() const; /** 梯形图编辑服务,不由控件拥有 */ LogicEditorService &editor_service_; /** 承载梯形图图元的场景 */ QGraphicsScene *scene_ = nullptr; /** 当前显示的控制逻辑标识 */ std::string logic_id_; /** 当前选中的网络标识 */ std::string current_rung_id_; /** 最近一次收到的运行轨迹 */ LogicTraceSnapshot trace_; /** 最近一次运行故障节点标识 */ std::string fault_node_id_; /** 是否显示运行轨迹 */ bool runtime_trace_enabled_ = false; /** 是否允许编辑梯形图 */ bool editing_enabled_ = true; };