#include "common/core_model/diagram.h" #include "diagramEditor/editorLayoutConfig.h" #include // layout_engine.h /********editor布局生成核心类**********/ class DiagramEditorModel; class DiagramLayoutEngine { public: struct Context { int sourceId = 0; QString currentRouteId; // 当前正在处理的线路ID bool isRemovingRoute = false; // 是否为删除操作 bool saveToModel = false; QMap itemCache; QMap componentsCache; QMap> branchUsedDirections; //key: 组件名 value: 已被支线占用的方向集合 QMap> directionOccupancyMap; QMap routeDirectionMap; void initComponentsCache(const QMap& compos) { componentsCache = compos; } void initDirectionOccupancyCache(const QMap>& occus){ directionOccupancyMap = occus; } void initRouteDirectionMapCache(const QMap& routes){ routeDirectionMap = routes; } }; enum class DirectionOperation { ADD, // 添加方向 REMOVE, // 移除方向 SET // 设置方向(替换) }; explicit DiagramLayoutEngine(DiagramEditorModel* model) : m_model(model) {} QRectF executeLayout( QMap& routes, QMap& components, QMap>& directionOccupancyMap, QMap& routeDirectionMap, const LayoutConfig& config, Context& context ); bool clearRouteDirectionOccupancy(const QString& routeId,Context& context); private: // 主线相关 QString findMainRoute(const QMap& routes); void layoutMainRoute(DiagramEditorRouteInfo& route, const LayoutConfig& config, Context& context); void layoutMainRouteInternal(DiagramEditorRouteInfo& route,const LayoutConfig& config,Context& context); // 支线相关 void layoutBranchRoute(DiagramEditorRouteInfo& route, const LayoutConfig& config, Context& context); void splitBranchRoute(DiagramEditorRouteInfo& route, Context& context); void layoutBranchSequence(QList& sequence, Direction branchDir, const LayoutConfig& config, Context& context, bool isOrder, int polarity); // 组件相关 Direction determineBranchDirection(const DiagramEditorComponentInfo& currentNode, Direction preferredDir, Context& context); QPoint getComponentPosition(const QString& componentName, Context& context); void updateComponent(DiagramEditorComponentInfo& compo, int dir, const QPoint& position, int rotate, Context& context); //记录线路在组件上的方向占用 bool recordRouteDirectionOccupancy(const QString& routeId,const QString& compoName,int directionMask,Context& context); //线路ID,组件名称,方向位掩码 /** * @brief 统一更新组件方向占用 * @param compoName 组件名称 * @param directionMask 方向掩码 (8上,4下,2左,1右) * @param operation 操作类型: 添加、移除、设置 * @param context 上下文 * @return 是否成功 */ bool updateComponentDirections(const QString& compoName,int directionMask,DirectionOperation operation,Context& context); bool updateComponentCacheInternal(const QString& compoName,int directionMask,DirectionOperation operation,Context& context); bool updateComponentModel(const QString& compoName,int directionMask,DirectionOperation operation,Context& context); // 辅助函数 QStandardItem* getNameItem(const QString& name, Context& context); int getComponentDirection(const QString& compoName, Context& context); QRectF calculateBoundingRect(const QMap& components); Direction getRouteDirection(const QString& routeName,const QMap& routes); int getComponentTotalOccupiedDirections(const QString& compoName, Context& context); //从总占用表中获取元件占用方向 int getComponentDirectionFromCache(const QString& compoName,const QString& routeId,Context& context); //从缓存获取方向占用 QString getDirectionName(int dirBit) { switch (dirBit) { case 8: return "上"; case 4: return "下"; case 2: return "左"; case 1: return "右"; default: return QString("未知(%1)").arg(dirBit); } } int getOppositeDirection(int dirBit) { switch (dirBit) { case 8: return 4; // 上 ↔ 下 case 4: return 8; // 下 ↔ 上 case 2: return 1; // 左 ↔ 右 case 1: return 2; // 右 ↔ 左 default: return 0; } } int getDirectionIndex(int dirBit) { switch (dirBit) { case 1: return 0; // 右 case 2: return 1; // 左 case 4: return 2; // 下 case 8: return 3; // 上 default: return -1; } } private: int m_compoWidth = 50; int m_compoHeight = 30; DiagramEditorModel* m_model = nullptr; };