GridFrame/diagramCavas/source/diagramEditor/layoutCalculator.cpp

273 lines
9.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// LayoutCalculator.cpp
#include "diagramEditor/layoutCalculator.h"
#include "diagramEditor/diagramEditorWizard.h"
#include "diagramEditor/diagramEditorStructContainer.h"
#include "diagramEditor/diagramEditorBaseBlock.h"
#include <QDebug>
FixedLayoutCalculator::FixedLayoutCalculator(DiagramEditorWizard* wizard)
: m_wizard(wizard) {}
QMap<DiagramEditorBaseBlock*, QPointF> FixedLayoutCalculator::calculateLayout() {
m_blockPositions.clear();
if (!m_wizard) {
qWarning() << "FixedLayoutCalculator: Wizard为空";
return m_blockPositions;
}
auto mapTotal = m_wizard->getContainerStruct();
double deltaY = 0;
double lastMaxDownH = 0;
// 按层级顺序处理
for (auto iter = mapTotal.begin(); iter != mapTotal.end(); ++iter) {
int level = iter.key();
if (level == Constants::TRANSFORMER_LEVEL) {
continue; // 变压器特殊处理
}
// 创建层级布局
LevelLayout levelLayout;
levelLayout.level = level;
levelLayout.containers = iter.value();
if (levelLayout.containers.isEmpty()) {
continue;
}
// 第一阶段:计算尺寸
calculateContainerSizes(levelLayout);
// 第二阶段:计算位置
calculatePositions(levelLayout, deltaY, lastMaxDownH);
// 处理变压器在层级0之后
if (level == 0 && mapTotal.contains(Constants::TRANSFORMER_LEVEL)) {
auto transformers = mapTotal.value(Constants::TRANSFORMER_LEVEL);
if (!transformers.isEmpty()) {
calculateTransformerPositions(transformers, deltaY, lastMaxDownH);
}
}
}
return m_blockPositions;
}
void FixedLayoutCalculator::calculateContainerSizes(LevelLayout& levelLayout) {
levelLayout.maxUpHeight = 0;
levelLayout.maxDownHeight = 0;
for (auto& container : levelLayout.containers) {
if (!container) continue;
auto mapBlocks = container->getBlockMap();
// 计算上间隔尺寸
auto topBays = mapBlocks.value(0);
double maxUp = 0;
double widthUp = 0;
for (auto block : topBays) {
if (!block) continue;
QRectF rec = block->getRecSize();
maxUp = qMax(maxUp, rec.height());
widthUp += 100 + rec.width();
}
maxUp += Constants::EDITOR_ITEM_HEIGHT;
levelLayout.maxUpHeight = qMax(levelLayout.maxUpHeight, maxUp);
// 计算下间隔尺寸
auto bottomBays = mapBlocks.value(3);
double maxDown = 0;
double widthDown = 0;
for (auto block : bottomBays) {
if (!block) continue;
QRectF rec = block->getRecSize();
maxDown = qMax(maxDown, rec.height());
widthDown += 100 + rec.width();
}
maxDown += Constants::EDITOR_ITEM_HEIGHT;
levelLayout.maxDownHeight = qMax(levelLayout.maxDownHeight, maxDown);
// 计算母线宽度
double busWidth = 0;
auto bus1 = mapBlocks.value(1);
auto bus2 = mapBlocks.value(2);
if (!bus1.isEmpty()) {
busWidth = qMax(busWidth, bus1.first()->getRecSize().width());
}
if (!bus2.isEmpty()) {
busWidth = qMax(busWidth, bus2.first()->getRecSize().width());
}
// 计算容器宽度
double containerWidth = qMax(widthUp, widthDown);
if (containerWidth < busWidth) {
containerWidth = busWidth;
}
// 设置容器尺寸
container->setWidth(containerWidth);
}
// 处理空的情况
if (levelLayout.maxUpHeight == 0) {
levelLayout.maxUpHeight = Constants::EDITOR_ITEM_HEIGHT;
}
if (levelLayout.maxDownHeight == 0) {
levelLayout.maxDownHeight = Constants::EDITOR_ITEM_HEIGHT;
}
}
void FixedLayoutCalculator::calculatePositions(LevelLayout& levelLayout,
double& deltaY, double& lastMaxDownH) {
double startX = CONTAINER_START_X;
bool isFirstContainer = true;
for (auto& container : levelLayout.containers) {
if (!container) continue;
// 设置容器高度
container->setMaxUpH(levelLayout.maxUpHeight);
container->setMaxDownH(levelLayout.maxDownHeight);
// 计算垂直位置(每行第一个容器计算一次)
if (isFirstContainer) {
if (levelLayout.level == 0) { // 首行
deltaY = container->getMaxUpH();
} else { // 其他行
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getMaxUpH();
}
lastMaxDownH = container->getMaxDownH();
isFirstContainer = false;
}
// 设置容器的关键Y坐标
container->setMidUpY(deltaY);
container->setMidDownY(deltaY + BUS_V_SPACING);
container->setStartX(startX);
// 计算容器内间隔位置
calculateBlockPositionsInContainer(container, startX, deltaY, deltaY + BUS_V_SPACING);
// 更新水平位置
startX += container->getWidth() + CONTAINER_H_SPACING;
}
}
void FixedLayoutCalculator::calculateBlockPositionsInContainer(DiagramEditorStructContainer* container,
double startX,
double midUpY,
double midDownY) {
if (!container) return;
auto mapBlocks = container->getBlockMap();
double currentX = startX;
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
int layer = it.key();
auto blocks = it.value();
for (auto block : blocks) {
if (!block) continue;
QRectF rec = block->getRecSize();
QPointF centerOffset = block->getCenterOffset(); //参考中心与boundingrect中心的偏移量
QPointF center;
int blockType = block->getType();
if (blockType == 1) { // 母线
if (layer == 1) { // 母线1
center = QPointF(startX-20, midUpY + rec.height() * 0.5);
} else if (layer == 2) { // 母线2
center = QPointF(startX-20, midDownY - rec.height() * 0.5);
}
} else if (blockType == 2) { // 间隔
/*int nLayout = 0; //默认垂直
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(block);
if(pBay){
nLayout = pBay->getBayInfo().nLayout;
}*/
if (layer == 0) { // 上间隔
center = QPointF(currentX + rec.width() * 0.5,
midUpY - rec.height() * 0.5 + centerOffset.y() - Constants::EDITOR_ITEM_HEIGHT * 0.5);
} else if (layer == 3) { // 下间隔
center = QPointF(currentX + rec.width() * 0.5,
midDownY + rec.height() * 0.5 + centerOffset.y() + Constants::EDITOR_ITEM_HEIGHT * 0.5);
}
currentX += rec.width();
}
// 变压器不在这里处理
if (!center.isNull()) {
m_blockPositions[block] = center;
block->setSeceneDelta(center);
}
}
}
}
void FixedLayoutCalculator::calculateTransformerPositions(const QList<DiagramEditorStructContainer*>& transformers,
double& deltaY, double& lastMaxDownH) {
if (transformers.isEmpty()) return;
// 计算变压器尺寸
for (auto container : transformers) {
if (!container) continue;
auto mapBlocks = container->getBlockMap();
auto transBlocks = mapBlocks.value(1); // 变压器在layer 1
for (auto block : transBlocks) {
if (!block) continue;
QRectF rec = block->getRecSize();
container->setWidth(rec.width());
container->setHeight(rec.height());
break; // 只取第一个变压器
}
}
// 计算变压器位置
double startX = TRANSFORMER_START_X;
bool isFirstTransformer = true;
for (auto container : transformers) {
if (!container) continue;
// 计算垂直位置
if (isFirstTransformer) {
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getHeight();
isFirstTransformer = false;
}
double centerY = deltaY - container->getHeight() * 0.5;
container->setStartY(centerY);
container->setStartX(startX);
// 计算变压器内部设备位置
auto mapBlocks = container->getBlockMap();
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
for (auto block : it.value()) {
if (!block) continue;
QRectF rec = block->getRecSize();
QPointF center(startX + rec.width() * 0.5,
centerY + rec.height() * 0.5);
m_blockPositions[block] = center;
block->setSeceneDelta(center);
}
}
// 更新水平位置
startX += container->getWidth() + TRANSFORMER_SPACING;
}
}