初步实现单独的图层管理器。
注意:没有和mapcavas通讯。
This commit is contained in:
@ -131,6 +131,7 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
addDockWidget(Qt::LeftDockWidgetArea, dock_layers);
|
addDockWidget(Qt::LeftDockWidgetArea, dock_layers);
|
||||||
dock_layers->hideMaxButton();
|
dock_layers->hideMaxButton();
|
||||||
|
|
||||||
|
//1、没用
|
||||||
QWidget* dock_layersWidgetContents = new QWidget();
|
QWidget* dock_layersWidgetContents = new QWidget();
|
||||||
dock_layersWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents_2"));
|
dock_layersWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents_2"));
|
||||||
QGridLayout* gridLayout_toc = new QGridLayout(dock_layersWidgetContents);
|
QGridLayout* gridLayout_toc = new QGridLayout(dock_layersWidgetContents);
|
||||||
@ -151,6 +152,7 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
graphicsView_delete->setFrameShadow(QFrame::Raised);
|
graphicsView_delete->setFrameShadow(QFrame::Raised);
|
||||||
//gridLayout_toc->addWidget(graphicsView_delete, 0, 0, 1, 1);
|
//gridLayout_toc->addWidget(graphicsView_delete, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
//2、没用,仅仅使用QTreeWidget实现的简略ui
|
||||||
QTreeWidget* treeWidget = new QTreeWidget();
|
QTreeWidget* treeWidget = new QTreeWidget();
|
||||||
treeWidget->setColumnCount(1);
|
treeWidget->setColumnCount(1);
|
||||||
treeWidget->setIndentation(18);
|
treeWidget->setIndentation(18);
|
||||||
@ -177,9 +179,6 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
border-image: none;
|
border-image: none;
|
||||||
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_down.svg);
|
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_down.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
|
|
||||||
//QList<QTreeWidgetItem*> items;
|
//QList<QTreeWidgetItem*> items;
|
||||||
@ -201,8 +200,51 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
QTreeWidgetItem* layerB = new QTreeWidgetItem(group1);
|
QTreeWidgetItem* layerB = new QTreeWidgetItem(group1);
|
||||||
layerB->setText(0, "tmp_image_2");
|
layerB->setText(0, "tmp_image_2");
|
||||||
|
|
||||||
gridLayout_toc->addWidget(treeWidget, 0, 0, 1, 1);
|
//gridLayout_toc->addWidget(treeWidget, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
//3、正经TOC
|
||||||
|
LayerTree* tree = new LayerTree();
|
||||||
|
auto* model = new LayerTreeModel(tree, this, true);
|
||||||
|
|
||||||
|
//auto* g1 = model->addGroup(model->root(), "Group A");
|
||||||
|
//model->addLayer(g1, "Roads");
|
||||||
|
//model->addLayer(g1, "Buildings");
|
||||||
|
|
||||||
|
|
||||||
|
auto* g1 = model->addGroup(model->root(), "Raster");
|
||||||
|
model->addLayer(g1, "tmp_image_1");
|
||||||
|
model->addLayer(g1, "tmp_image_2");
|
||||||
|
|
||||||
|
auto* g2 = model->addGroup(model->root(), "Vector");
|
||||||
|
//model->addLayer(g2, "Rivers");
|
||||||
|
|
||||||
|
QTreeView* LayerTreeView = new QTreeView();
|
||||||
|
LayerTreeView->setModel(model);
|
||||||
|
LayerTreeView->setHeaderHidden(true);
|
||||||
|
LayerTreeView->setStyleSheet(R"(
|
||||||
|
QTreeView
|
||||||
|
{
|
||||||
|
color: #ACCDFF;
|
||||||
|
}
|
||||||
|
QTreeView::branch {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeView::branch:has-children:!has-siblings:closed,
|
||||||
|
QTreeView::branch:closed:has-children:has-siblings
|
||||||
|
{
|
||||||
|
border-image: none;
|
||||||
|
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_right.svg);
|
||||||
|
}
|
||||||
|
QTreeView::branch:open:has-children:!has-siblings,
|
||||||
|
QTreeView::branch:open:has-children:has-siblings
|
||||||
|
{
|
||||||
|
border-image: none;
|
||||||
|
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_down.svg);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
gridLayout_toc->addWidget(LayerTreeView, 0, 0, 1, 1);
|
||||||
|
|
||||||
dock_layers->setWidget(dock_layersWidgetContents);
|
dock_layers->setWidget(dock_layersWidgetContents);
|
||||||
dock_layersWidgetContents->setStyleSheet(qss_DockWidget_contentWidget);
|
dock_layersWidgetContents->setStyleSheet(qss_DockWidget_contentWidget);
|
||||||
|
|||||||
@ -51,6 +51,9 @@
|
|||||||
|
|
||||||
#include "View3DModelManager.h"
|
#include "View3DModelManager.h"
|
||||||
|
|
||||||
|
#include "LayerTreeModel.h"
|
||||||
|
#include "LayerTree.h"
|
||||||
|
|
||||||
#define PI 3.1415926
|
#define PI 3.1415926
|
||||||
|
|
||||||
QT_CHARTS_USE_NAMESPACE//QChartView ʹ<><CAB9> <20><>Ҫ<EFBFBD>Ӻ꣬ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
QT_CHARTS_USE_NAMESPACE//QChartView ʹ<><CAB9> <20><>Ҫ<EFBFBD>Ӻ꣬ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
||||||
|
|||||||
@ -114,6 +114,11 @@
|
|||||||
<ClCompile Include="ImagerOperationBase.cpp" />
|
<ClCompile Include="ImagerOperationBase.cpp" />
|
||||||
<ClCompile Include="imager_base.cpp" />
|
<ClCompile Include="imager_base.cpp" />
|
||||||
<ClCompile Include="irisximeaimager.cpp" />
|
<ClCompile Include="irisximeaimager.cpp" />
|
||||||
|
<ClCompile Include="LayerTree.cpp" />
|
||||||
|
<ClCompile Include="LayerTreeGroupNode.cpp" />
|
||||||
|
<ClCompile Include="LayerTreeLayerNode.cpp" />
|
||||||
|
<ClCompile Include="LayerTreeModel.cpp" />
|
||||||
|
<ClCompile Include="LayerTreeNode.cpp" />
|
||||||
<ClCompile Include="OneMotorControl.cpp" />
|
<ClCompile Include="OneMotorControl.cpp" />
|
||||||
<ClCompile Include="path_tc.cpp" />
|
<ClCompile Include="path_tc.cpp" />
|
||||||
<ClCompile Include="PowerControl.cpp" />
|
<ClCompile Include="PowerControl.cpp" />
|
||||||
@ -180,6 +185,11 @@
|
|||||||
<QtMoc Include="OneMotorControl.h" />
|
<QtMoc Include="OneMotorControl.h" />
|
||||||
<QtMoc Include="TwoMotorControl.h" />
|
<QtMoc Include="TwoMotorControl.h" />
|
||||||
<QtMoc Include="TabManager.h" />
|
<QtMoc Include="TabManager.h" />
|
||||||
|
<QtMoc Include="LayerTreeModel.h" />
|
||||||
|
<QtMoc Include="LayerTreeNode.h" />
|
||||||
|
<QtMoc Include="LayerTree.h" />
|
||||||
|
<QtMoc Include="LayerTreeGroupNode.h" />
|
||||||
|
<QtMoc Include="LayerTreeLayerNode.h" />
|
||||||
<ClInclude Include="utility_tc.h" />
|
<ClInclude Include="utility_tc.h" />
|
||||||
<QtMoc Include="aboutWindow.h" />
|
<QtMoc Include="aboutWindow.h" />
|
||||||
<ClInclude Include="hppaConfigFile.h" />
|
<ClInclude Include="hppaConfigFile.h" />
|
||||||
|
|||||||
@ -21,15 +21,6 @@
|
|||||||
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
|
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
|
||||||
<Extensions>ts</Extensions>
|
<Extensions>ts</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Header Files\motor">
|
|
||||||
<UniqueIdentifier>{eadfac5f-f4f9-49e2-9f99-0849bf074cf8}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Source Files\motor">
|
|
||||||
<UniqueIdentifier>{4672856c-86fb-46e3-94ff-0a296dcc6111}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files\focus">
|
|
||||||
<UniqueIdentifier>{f2bfb93e-9ef8-4fdd-a776-db93b81af553}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtRcc Include="HPPA.qrc">
|
<QtRcc Include="HPPA.qrc">
|
||||||
@ -148,6 +139,21 @@
|
|||||||
<ClCompile Include="View3DModelManager.cpp">
|
<ClCompile Include="View3DModelManager.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayerTreeNode.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayerTreeModel.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayerTree.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayerTreeGroupNode.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayerTreeLayerNode.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="fileOperation.h">
|
<QtMoc Include="fileOperation.h">
|
||||||
@ -222,6 +228,21 @@
|
|||||||
<QtMoc Include="View3DModelManager.h">
|
<QtMoc Include="View3DModelManager.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
<QtMoc Include="LayerTreeModel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="LayerTreeNode.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="LayerTree.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="LayerTreeGroupNode.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="LayerTreeLayerNode.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="imageProcessor.h">
|
<ClInclude Include="imageProcessor.h">
|
||||||
|
|||||||
73
HPPA/LayerTree.cpp
Normal file
73
HPPA/LayerTree.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "LayerTree.h"
|
||||||
|
#include "LayerTreeGroupNode.h"
|
||||||
|
|
||||||
|
LayerTree::LayerTree(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
// root <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> view <20><><EFBFBD><EFBFBD>ʾ
|
||||||
|
m_root = new LayerTreeGroupNode("__root__", this);
|
||||||
|
m_root->setVisible(Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTree::~LayerTree()
|
||||||
|
{
|
||||||
|
delete m_root;
|
||||||
|
m_root = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTree::root() const
|
||||||
|
{
|
||||||
|
return m_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTree::insertNode(LayerTreeNode* parent, int row, LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
if (!node) return nullptr;
|
||||||
|
if (!parent) parent = m_root;
|
||||||
|
|
||||||
|
if (row < 0) row = parent->childCount();
|
||||||
|
parent->insertChild(row, node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTree::removeNode(LayerTreeNode* parent, int row)
|
||||||
|
{
|
||||||
|
if (!parent) parent = m_root;
|
||||||
|
return parent->takeChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::setChildrenVisible(LayerTreeNode* n, Qt::CheckState state)
|
||||||
|
{
|
||||||
|
if (!n) return;
|
||||||
|
const auto& cs = n->children();
|
||||||
|
for (LayerTreeNode* c : cs) {
|
||||||
|
c->setVisible(state);
|
||||||
|
setChildrenVisible(c, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::updateParentVisibleFromChildren(LayerTreeNode* p)
|
||||||
|
{
|
||||||
|
if (!p) return;
|
||||||
|
if (p->childCount() == 0) return;
|
||||||
|
|
||||||
|
int checked = 0, unchecked = 0, partial = 0;
|
||||||
|
const auto& cs = p->children();
|
||||||
|
for (LayerTreeNode* c : cs) {
|
||||||
|
auto s = c->visible();
|
||||||
|
if (s == Qt::Checked) checked++;
|
||||||
|
else if (s == Qt::Unchecked) unchecked++;
|
||||||
|
else partial++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::CheckState newState;
|
||||||
|
if (partial > 0) newState = Qt::PartiallyChecked;
|
||||||
|
else if (checked > 0 && unchecked == 0) newState = Qt::Checked;
|
||||||
|
else if (unchecked > 0 && checked == 0) newState = Qt::Unchecked;
|
||||||
|
else newState = Qt::PartiallyChecked;
|
||||||
|
|
||||||
|
if (p->visible() != newState) {
|
||||||
|
p->setVisible(newState);
|
||||||
|
updateParentVisibleFromChildren(p->parentNode());
|
||||||
|
}
|
||||||
|
}
|
||||||
49
HPPA/LayerTree.h
Normal file
49
HPPA/LayerTree.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "LayerTreeNode.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LayerTree<65><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
* - <20><><EFBFBD><EFBFBD> root
|
||||||
|
* - <20>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>/<2F>Ƴ<EFBFBD><C6B3>ڵ<EFBFBD><DAB5><EFBFBD> API
|
||||||
|
* - <20>ṩ<EFBFBD>ɼ<EFBFBD><C9BC>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>븸<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>̬<EFBFBD><CCAC><EFBFBD>µľ<C2B5>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>
|
||||||
|
*
|
||||||
|
* ע<>⣺beginInsertRows/endInsertRows <20><> Qt Model <20><><EFBFBD><EFBFBD>֪ͨӦ<D6AA><D3A6> Model <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||||
|
* LayerTree ֻ<><D6BB><EFBFBD><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9>ȷ<EFBFBD>ԡ<EFBFBD>
|
||||||
|
*/
|
||||||
|
class LayerTree : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LayerTree(QObject* parent = nullptr);
|
||||||
|
~LayerTree() override;
|
||||||
|
|
||||||
|
LayerTree(const LayerTree&) = delete;
|
||||||
|
LayerTree& operator=(const LayerTree&) = delete;
|
||||||
|
|
||||||
|
LayerTreeNode* root() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD>룺parent Ϊ nullptr <20><>ʾ root<6F><74>row=-1 <20><>ʾ append
|
||||||
|
LayerTreeNode* insertNode(LayerTreeNode* parent, int row, LayerTreeNode* node);
|
||||||
|
|
||||||
|
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD> delete<74><65><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1>Ƴ<EFBFBD><C6B3>ڵ㣨<DAB5><E3A3A8><EFBFBD><EFBFBD><EFBFBD>߸<EFBFBD><DFB8><EFBFBD> delete <20><><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2>룩
|
||||||
|
LayerTreeNode* removeNode(LayerTreeNode* parent, int row);
|
||||||
|
|
||||||
|
// <20>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD> Model <20><><EFBFBD>ã<EFBFBD>
|
||||||
|
static void setChildrenVisible(LayerTreeNode* n, Qt::CheckState state);
|
||||||
|
static void updateParentVisibleFromChildren(LayerTreeNode* parent);
|
||||||
|
|
||||||
|
static inline bool isLayer(LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
return node && node->type() == LayerTreeNode::Type::Layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool isGroup(LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
return node && node->type() == LayerTreeNode::Type::Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayerTreeNode* m_root = nullptr; // owned
|
||||||
|
};
|
||||||
6
HPPA/LayerTreeGroupNode.cpp
Normal file
6
HPPA/LayerTreeGroupNode.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "LayerTreeGroupNode.h"
|
||||||
|
|
||||||
|
LayerTreeGroupNode::LayerTreeGroupNode(const QString& name, QObject* parent)
|
||||||
|
: LayerTreeNode(name, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
15
HPPA/LayerTreeGroupNode.h
Normal file
15
HPPA/LayerTreeGroupNode.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "LayerTreeNode.h"
|
||||||
|
|
||||||
|
/** Group <20>ڵ<EFBFBD> */
|
||||||
|
class LayerTreeGroupNode : public LayerTreeNode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LayerTreeGroupNode(const QString& name,
|
||||||
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Type type() const override { return Type::Group; }
|
||||||
|
|
||||||
|
// <20>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>collapsed / groupOpacity <20><>
|
||||||
|
};
|
||||||
6
HPPA/LayerTreeLayerNode.cpp
Normal file
6
HPPA/LayerTreeLayerNode.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "LayerTreeLayerNode.h"
|
||||||
|
|
||||||
|
LayerTreeLayerNode::LayerTreeLayerNode(const QString& name, QObject* parent)
|
||||||
|
: LayerTreeNode(name, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
15
HPPA/LayerTreeLayerNode.h
Normal file
15
HPPA/LayerTreeLayerNode.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "LayerTreeNode.h"
|
||||||
|
|
||||||
|
/** Layer <20>ڵ<EFBFBD> */
|
||||||
|
class LayerTreeLayerNode : public LayerTreeNode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LayerTreeLayerNode(const QString& name,
|
||||||
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Type type() const override { return Type::Layer; }
|
||||||
|
|
||||||
|
// <20>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>layerId / pointer / legendItems <20><>
|
||||||
|
};
|
||||||
168
HPPA/LayerTreeModel.cpp
Normal file
168
HPPA/LayerTreeModel.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#include "LayerTreeModel.h"
|
||||||
|
#include "LayerTreeGroupNode.h"
|
||||||
|
#include "LayerTreeLayerNode.h"
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
LayerTreeModel::LayerTreeModel(LayerTree* tree, QObject* parent, bool cascadeCheck)
|
||||||
|
: QAbstractItemModel(parent),
|
||||||
|
m_tree(tree),
|
||||||
|
m_cascadeCheck(cascadeCheck)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_tree && "LayerTreeModel requires a valid LayerTree*");
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex LayerTreeModel::index(int row, int column, const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (column != 0 || row < 0) return {};
|
||||||
|
|
||||||
|
LayerTreeNode* parentNode = nodeFromIndex(parent);
|
||||||
|
if (!parentNode) return {};
|
||||||
|
|
||||||
|
LayerTreeNode* child = parentNode->childAt(row);
|
||||||
|
if (!child) return {};
|
||||||
|
|
||||||
|
return createIndex(row, column, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex LayerTreeModel::parent(const QModelIndex& child) const
|
||||||
|
{
|
||||||
|
LayerTreeNode* node = nodeFromIndex(child);
|
||||||
|
if (!node || node == m_tree->root()) return {};
|
||||||
|
|
||||||
|
LayerTreeNode* p = node->parentNode();
|
||||||
|
if (!p || p == m_tree->root()) return {};
|
||||||
|
|
||||||
|
return createIndex(p->rowInParent(), 0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LayerTreeModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
LayerTreeNode* p = nodeFromIndex(parent);
|
||||||
|
return p ? p->childCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LayerTreeModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LayerTreeModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
|
if (!n || n == m_tree->root()) return {};
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return n->name();
|
||||||
|
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
{
|
||||||
|
auto* tmp = nodeFromIndex(index);
|
||||||
|
if (LayerTree::isGroup(tmp))
|
||||||
|
return QIcon();
|
||||||
|
else if (LayerTree::isLayer(tmp))
|
||||||
|
{
|
||||||
|
QString basePath = QCoreApplication::applicationDirPath();
|
||||||
|
return QIcon(basePath + "/icons/mIconRaster.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
return static_cast<int>(n->visible());
|
||||||
|
|
||||||
|
case Qt::ToolTipRole:
|
||||||
|
return (n->type() == LayerTreeNode::Type::Group) ? "Group" : "Layer";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayerTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
|
{
|
||||||
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
|
if (!n || n == m_tree->root()) return false;
|
||||||
|
|
||||||
|
if (role == Qt::CheckStateRole) {
|
||||||
|
auto newState = static_cast<Qt::CheckState>(value.toInt());
|
||||||
|
if (n->visible() == newState) return true;
|
||||||
|
|
||||||
|
n->setVisible(newState);
|
||||||
|
|
||||||
|
// 1) <20><> -> <20><> <20><><EFBFBD><EFBFBD>
|
||||||
|
if (m_cascadeCheck) {
|
||||||
|
LayerTree::setChildrenVisible(n, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) <20><> -> <20><> <20><><EFBFBD><EFBFBD> PartiallyChecked
|
||||||
|
LayerTree::updateParentVisibleFromChildren(n->parentNode());
|
||||||
|
|
||||||
|
// <20><EFBFBD><F2BBAFA3><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻Ϊ<E6BBBB><CEAA> dataChanged<65><64>
|
||||||
|
emit layoutChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags LayerTreeModel::flags(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid()) return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
|
if (!n || n == m_tree->root()) return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeModel::root() const
|
||||||
|
{
|
||||||
|
return m_tree->root();
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeModel::addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon)
|
||||||
|
{
|
||||||
|
if (!parent) parent = m_tree->root();
|
||||||
|
|
||||||
|
const int row = parent->childCount();
|
||||||
|
beginInsertRows(indexFromNode(parent), row, row);
|
||||||
|
LayerTreeNode* g = m_tree->insertNode(parent, row, new LayerTreeGroupNode(name));
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeModel::addLayer(LayerTreeNode* parent, const QString& name, const QIcon& icon)
|
||||||
|
{
|
||||||
|
if (!parent) parent = m_tree->root();
|
||||||
|
|
||||||
|
const int row = parent->childCount();
|
||||||
|
beginInsertRows(indexFromNode(parent), row, row);
|
||||||
|
LayerTreeNode* l = m_tree->insertNode(parent, row, new LayerTreeLayerNode(name));
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeModel::setCascadeCheckEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_cascadeCheck = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayerTreeModel::cascadeCheckEnabled() const
|
||||||
|
{
|
||||||
|
return m_cascadeCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeModel::nodeFromIndex(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid()) return m_tree->root();
|
||||||
|
return static_cast<LayerTreeNode*>(index.internalPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex LayerTreeModel::indexFromNode(LayerTreeNode* n) const
|
||||||
|
{
|
||||||
|
if (!n || n == m_tree->root()) return {};
|
||||||
|
return createIndex(n->rowInParent(), 0, n);
|
||||||
|
}
|
||||||
47
HPPA/LayerTreeModel.h
Normal file
47
HPPA/LayerTreeModel.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include "LayerTree.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LayerTreeModel<65><6C>Qt <20><><EFBFBD><EFBFBD><EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD>ٹ<EFBFBD><D9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
* - 1 <20>У<EFBFBD><D0A3><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>ͼ<EFBFBD>꣩+ checkbox
|
||||||
|
* - <20><>ѡ<EFBFBD>ɼ<EFBFBD><C9BC>ԣ<EFBFBD><D4A3><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
||||||
|
*/
|
||||||
|
class LayerTreeModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LayerTreeModel(LayerTree* tree,
|
||||||
|
QObject* parent = nullptr,
|
||||||
|
bool cascadeCheck = true);
|
||||||
|
~LayerTreeModel() override = default;
|
||||||
|
|
||||||
|
// QAbstractItemModel <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||||
|
QModelIndex index(int row, int column,
|
||||||
|
const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QModelIndex parent(const QModelIndex& child) const override;
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex& index, int role) const override;
|
||||||
|
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> API<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD> begin/endInsertRows<77><73>
|
||||||
|
LayerTreeNode* root() const;
|
||||||
|
|
||||||
|
LayerTreeNode* addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon = QIcon());
|
||||||
|
LayerTreeNode* addLayer(LayerTreeNode* parent, const QString& name, const QIcon& icon = QIcon());
|
||||||
|
|
||||||
|
void setCascadeCheckEnabled(bool enabled);
|
||||||
|
bool cascadeCheckEnabled() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayerTree* m_tree = nullptr; // not owned
|
||||||
|
bool m_cascadeCheck = true;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayerTreeNode* nodeFromIndex(const QModelIndex& index) const;
|
||||||
|
QModelIndex indexFromNode(LayerTreeNode* n) const;
|
||||||
|
};
|
||||||
110
HPPA/LayerTreeNode.cpp
Normal file
110
HPPA/LayerTreeNode.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include "LayerTreeNode.h"
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
LayerTreeNode::LayerTreeNode(const QString& name, QObject* parent)
|
||||||
|
: QObject(parent), m_name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode::~LayerTreeNode()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_children);
|
||||||
|
m_children.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LayerTreeNode::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::setName(const QString& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon LayerTreeNode::icon() const
|
||||||
|
{
|
||||||
|
return m_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::setIcon(const QIcon& icon)
|
||||||
|
{
|
||||||
|
m_icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::CheckState LayerTreeNode::visible() const
|
||||||
|
{
|
||||||
|
return m_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::setVisible(Qt::CheckState s)
|
||||||
|
{
|
||||||
|
m_visible = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeNode::parentNode() const
|
||||||
|
{
|
||||||
|
return m_parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::setParentNode(LayerTreeNode* p)
|
||||||
|
{
|
||||||
|
m_parentNode = p;
|
||||||
|
// <20><> QObject <20><> parent Ҳ<><D2B2><EFBFBD>棨<EFBFBD><E6A3A8><EFBFBD><EFBFBD> Qt <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ι<EFBFBD><CEB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD> delete children<65><6E>
|
||||||
|
if (p) this->setParent(p);
|
||||||
|
else this->setParent(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LayerTreeNode::rowInParent() const
|
||||||
|
{
|
||||||
|
if (!m_parentNode) return 0;
|
||||||
|
|
||||||
|
const auto& siblings = m_parentNode->m_children;
|
||||||
|
for (int i = 0; i < siblings.size(); ++i)
|
||||||
|
{
|
||||||
|
if (siblings[i] == this) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LayerTreeNode::childCount() const
|
||||||
|
{
|
||||||
|
return m_children.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeNode::childAt(int row) const
|
||||||
|
{
|
||||||
|
if (row < 0 || row >= m_children.size()) return nullptr;
|
||||||
|
return m_children[row];
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVector<LayerTreeNode*>& LayerTreeNode::children() const
|
||||||
|
{
|
||||||
|
return m_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::appendChild(LayerTreeNode* child)
|
||||||
|
{
|
||||||
|
insertChild(m_children.size(), child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeNode::insertChild(int row, LayerTreeNode* child)
|
||||||
|
{
|
||||||
|
if (!child) return;
|
||||||
|
|
||||||
|
if (row < 0 || row > m_children.size())
|
||||||
|
row = m_children.size();
|
||||||
|
|
||||||
|
child->setParentNode(this);
|
||||||
|
m_children.insert(row, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeNode::takeChild(int row)
|
||||||
|
{
|
||||||
|
if (row < 0 || row >= m_children.size()) return nullptr;
|
||||||
|
LayerTreeNode* taken = m_children.takeAt(row);
|
||||||
|
if (taken) taken->setParentNode(nullptr);
|
||||||
|
return taken;
|
||||||
|
}
|
||||||
65
HPPA/LayerTreeNode.h
Normal file
65
HPPA/LayerTreeNode.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LayerTreeNode<64><65><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ࣨ<EFBFBD><E0A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
* - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD>/ͼ<><CDBC>/<2F>ɼ<EFBFBD><C9BC><EFBFBD>/<2F><><EFBFBD>ӹ<EFBFBD>ϵ
|
||||||
|
* - Group / Layer <20>ڵ<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD>̳<EFBFBD>ʵ<EFBFBD><CAB5>
|
||||||
|
*
|
||||||
|
* ˵<><CBB5><EFBFBD><EFBFBD>
|
||||||
|
* - <20><><EFBFBD><EFBFBD>ͬʱά<CAB1><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>롱<EFBFBD><EBA1B1>m_parentNode<64><65><EFBFBD><EFBFBD> QObject parent<6E><74><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
||||||
|
* - children <20>ɽڵ<C9BD><DAB5>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷţ<CDB7><C5A3><EFBFBD><EFBFBD><EFBFBD>ʱ delete children<65><6E>
|
||||||
|
*/
|
||||||
|
class LayerTreeNode : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class Type { Group, Layer };
|
||||||
|
|
||||||
|
explicit LayerTreeNode(const QString& name,
|
||||||
|
QObject* parent = nullptr);
|
||||||
|
~LayerTreeNode() override;
|
||||||
|
|
||||||
|
LayerTreeNode(const LayerTreeNode&) = delete;
|
||||||
|
LayerTreeNode& operator=(const LayerTreeNode&) = delete;
|
||||||
|
|
||||||
|
virtual Type type() const = 0;
|
||||||
|
|
||||||
|
// ---- properties ----
|
||||||
|
QString name() const;
|
||||||
|
void setName(const QString& name);
|
||||||
|
|
||||||
|
QIcon icon() const;
|
||||||
|
void setIcon(const QIcon& icon);
|
||||||
|
|
||||||
|
Qt::CheckState visible() const;
|
||||||
|
void setVisible(Qt::CheckState s);
|
||||||
|
|
||||||
|
// ---- tree relations ----
|
||||||
|
LayerTreeNode* parentNode() const;
|
||||||
|
int rowInParent() const;
|
||||||
|
|
||||||
|
int childCount() const;
|
||||||
|
LayerTreeNode* childAt(int row) const;
|
||||||
|
const QVector<LayerTreeNode*>& children() const;
|
||||||
|
|
||||||
|
// ---- structure mutation (used by LayerTree / Model) ----
|
||||||
|
void appendChild(LayerTreeNode* child);
|
||||||
|
void insertChild(int row, LayerTreeNode* child);
|
||||||
|
LayerTreeNode* takeChild(int row); // remove but not delete
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setParentNode(LayerTreeNode* p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
QIcon m_icon;
|
||||||
|
Qt::CheckState m_visible = Qt::Checked;
|
||||||
|
|
||||||
|
LayerTreeNode* m_parentNode = nullptr;
|
||||||
|
QVector<LayerTreeNode*> m_children;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user