GridFrame/diagramCavas/source/diagramEditor/layoutBuilder.cpp

159 lines
5.0 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.

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