GridFrame/diagramCavas/source/diagramEditor/layoutBuilder.cpp

159 lines
5.0 KiB
C++
Raw Normal View History

2026-05-06 19:48:33 +08:00
// LayoutBuilder.cpp
#include "diagramEditor/layoutBuilder.h"
#include "diagramEditor/editItemFactory.h"
#include "diagramEditor/hierarchyItemBuilder.h"
#include "common/core_model/constants.h"
#include "diagramEditor/editPanel.h"
#include <QDebug>
LayoutBuilder::LayoutBuilder(EditPanel* panel)
: m_panel(panel) {}
LayoutBuilder::BuildResult LayoutBuilder::buildContainer(const BlockMap& blockMap) {
BuildResult result;
// 1. 创建容器
result.container = new EditContainerItem();
result.container->setMinimumWidth(Constants::EDITOR_ITEM_WIDTH + 40);
result.container->setId(QUuid::createUuid().toString());
// 2. 连接容器信号
connectContainerSignals(result.container);
// 3. 创建垂直布局
auto verticalLayout = createVerticalLayout();
result.container->setLayout(verticalLayout);
// 4. 处理每一层
for (int layerIndex = 0; layerIndex < TOTAL_LAYERS; ++layerIndex) {
auto blocks = blockMap.value(layerIndex);
auto layerLayout = createHorizontalLayout();
verticalLayout->addItem(layerLayout);
if (blocks.isEmpty()) {
// 空层添加占位符
layerLayout->addItem(createSpacerItem());
} else {
// 处理有Blocks的层
processLayer(blocks, layerLayout, result.bayItems, result.deviceItems);
}
}
// 5. 添加拉伸
addStretchToVerticalLayout(verticalLayout);
return result;
}
EditBaseItem* LayoutBuilder::processBlock(BlockDataPtr block,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems) {
if (!block) return nullptr;
// 1. 通过工厂创建Item
auto factory = EditItemFactory::getFactory(block->getType());
if (!factory) {
qWarning() << "No factory found for block type:" << block->getType();
return nullptr;
}
auto editItem = factory->createItem(block);
if (!editItem) {
qWarning() << "Failed to create item for block type:" << block->getType();
return nullptr;
}
// 2. 设置Item属性
editItem->setName(block->getName());
// 注意:这里使用原始指针,不涉及所有权转移
editItem->setBlockData(block);
// 3. 连接信号
connectSignals(editItem);
// 4. 构建层级项
int blockType = block->getType();
switch (blockType) {
case 1: // 母线
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 1));
break;
case 2: // 间隔
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
break;
case 3: // 变压器
// 变压器不创建bayItem但会创建deviceItem
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 16));
break;
}
return editItem;
}
void LayoutBuilder::processLayer(const QList<BlockDataPtr>& blocks,
QGraphicsLinearLayout* layerLayout,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems) {
if (!layerLayout) return;
for (auto block : blocks) {
auto editItem = processBlock(block, bayItems, deviceItems);
if (editItem) {
layerLayout->addItem(editItem);
}
}
}
void LayoutBuilder::connectSignals(EditBaseItem* item) {
if (!m_panel || !item) return;
QObject::connect(item, &EditBaseItem::itemDbClicked,
m_panel, &EditPanel::onItemDbClicked);
}
void LayoutBuilder::connectContainerSignals(EditContainerItem* container) {
if (!m_panel || !container) return;
QObject::connect(container, &EditContainerItem::containerSizeChange,
m_panel, &EditPanel::onContainerSizeChanged);
}
QGraphicsLinearLayout* LayoutBuilder::createRowLayout() {
auto layout = new QGraphicsLinearLayout(Qt::Horizontal);
layout->setSpacing(20);
layout->setMaximumHeight(300);
return layout;
}
QGraphicsLinearLayout* LayoutBuilder::createVerticalLayout() {
auto layout = new QGraphicsLinearLayout(Qt::Vertical);
layout->setSpacing(10);
layout->setMinimumHeight(260);
return layout;
}
QGraphicsLinearLayout* LayoutBuilder::createHorizontalLayout() {
return new QGraphicsLinearLayout(Qt::Horizontal);
}
EditBaseItem* LayoutBuilder::createSpacerItem() {
auto spacer = new EditBaseItem();
spacer->setType(EditorItemType::None);
spacer->setBoundingRect(QRectF(0, 0,
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
return spacer;
}
void LayoutBuilder::addStretchToVerticalLayout(QGraphicsLinearLayout* layout) {
if (!layout) return;
int count = layout->count();
if (count == 4) {
layout->insertStretch(3);
layout->insertStretch(1);
} else if (count == 2) {
layout->insertStretch(1);
}
}