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