159 lines
5.0 KiB
C++
159 lines
5.0 KiB
C++
// 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);
|
||
}
|
||
}
|