GridFrame/diagramCavas/include/diagramEditor/editorDiagramLayoutEngine.h

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