139 lines
5.8 KiB
C++
139 lines
5.8 KiB
C++
#include "common/core_model/diagram.h"
|
|
#include "diagramEditor/editorLayoutConfig.h"
|
|
#include <QStandardItem>
|
|
// layout_engine.h
|
|
/********editor布局生成核心类**********/
|
|
|
|
class DiagramEditorModel;
|
|
|
|
class DiagramLayoutEngine {
|
|
public:
|
|
struct Context {
|
|
int sourceId = 0;
|
|
QString currentRouteId; // 当前正在处理的线路ID
|
|
bool isRemovingRoute = false; // 是否为删除操作
|
|
bool saveToModel = false;
|
|
QMap<QString, QStandardItem*> itemCache;
|
|
QMap<QString, DiagramEditorComponentInfo> componentsCache;
|
|
QMap<QString, QSet<Direction>> branchUsedDirections; //key: 组件名 value: 已被支线占用的方向集合
|
|
QMap<QString, QMap<int,DirectionOccupancyRecord>> directionOccupancyMap;
|
|
QMap<QString, DirectionOccupancyRouteInfo> routeDirectionMap;
|
|
|
|
void initComponentsCache(const QMap<QString, DiagramEditorComponentInfo>& compos) {
|
|
componentsCache = compos;
|
|
}
|
|
|
|
void initDirectionOccupancyCache(const QMap<QString, QMap<int,DirectionOccupancyRecord>>& occus){
|
|
directionOccupancyMap = occus;
|
|
}
|
|
|
|
void initRouteDirectionMapCache(const QMap<QString, DirectionOccupancyRouteInfo>& routes){
|
|
routeDirectionMap = routes;
|
|
}
|
|
};
|
|
|
|
enum class DirectionOperation {
|
|
ADD, // 添加方向
|
|
REMOVE, // 移除方向
|
|
SET // 设置方向(替换)
|
|
};
|
|
|
|
explicit DiagramLayoutEngine(DiagramEditorModel* model)
|
|
: m_model(model) {}
|
|
|
|
QRectF executeLayout(
|
|
QMap<QString, DiagramEditorRouteInfo>& routes,
|
|
QMap<QString, DiagramEditorComponentInfo>& components,
|
|
QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,
|
|
QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,
|
|
const LayoutConfig& config,
|
|
Context& context
|
|
);
|
|
bool clearRouteDirectionOccupancy(const QString& routeId,Context& context);
|
|
private:
|
|
// 主线相关
|
|
QString findMainRoute(const QMap<QString, DiagramEditorRouteInfo>& 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<DiagramEditorComponentInfo>& 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<QString, DiagramEditorComponentInfo>& components);
|
|
Direction getRouteDirection(const QString& routeName,const QMap<QString, DiagramEditorRouteInfo>& 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;
|
|
};
|