Compare commits
3 Commits
1c7780eb14
...
30fa211a22
| Author | SHA1 | Date | |
|---|---|---|---|
| 30fa211a22 | |||
| 7473a45f41 | |||
| 6d8c2f0419 |
@ -905,7 +905,7 @@ void HPPA::removeLayerByTreeIndex()
|
|||||||
LayerTreeNode* node = static_cast<LayerTreeNode*>(currentIndexTmp.internalPointer());
|
LayerTreeNode* node = static_cast<LayerTreeNode*>(currentIndexTmp.internalPointer());
|
||||||
if (!node || node->type() != LayerTreeNode::Type::Layer) return;
|
if (!node || node->type() != LayerTreeNode::Type::Layer) return;
|
||||||
|
|
||||||
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
|
auto* layerNode = static_cast<LayerTreeLayer*>(node);
|
||||||
MapLayer* mapLayer = layerNode->mapLayer();
|
MapLayer* mapLayer = layerNode->mapLayer();
|
||||||
QWidget* layerWidget = nullptr;
|
QWidget* layerWidget = nullptr;
|
||||||
|
|
||||||
@ -957,7 +957,7 @@ void HPPA::removeAllLayersInRasterGroup()
|
|||||||
|
|
||||||
if (node->type() != LayerTreeNode::Type::Layer) continue;
|
if (node->type() != LayerTreeNode::Type::Layer) continue;
|
||||||
|
|
||||||
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
|
auto* layerNode = static_cast<LayerTreeLayer*>(node);
|
||||||
MapLayer* mapLayer = layerNode->mapLayer();
|
MapLayer* mapLayer = layerNode->mapLayer();
|
||||||
QWidget* layerWidget = nullptr;
|
QWidget* layerWidget = nullptr;
|
||||||
|
|
||||||
@ -1334,6 +1334,41 @@ void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab,会调
|
|||||||
{
|
{
|
||||||
canvas->setMapTool(activeTool);
|
canvas->setMapTool(activeTool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync layer tree view selection with the current tab
|
||||||
|
if (m_MapLayerStore && m_layerTreeView && m_LayerTreeModel && m_RasterGroup)
|
||||||
|
{
|
||||||
|
MapLayer* layer = m_MapLayerStore->layerForWidget(currentWidget);
|
||||||
|
if (layer)
|
||||||
|
{
|
||||||
|
// Find the LayerTreeLayer node in m_RasterGroup that matches this layer
|
||||||
|
for (int i = 0; i < m_RasterGroup->childCount(); ++i)
|
||||||
|
{
|
||||||
|
LayerTreeNode* child = m_RasterGroup->childAt(i);
|
||||||
|
if (child && child->type() == LayerTreeNode::Type::Layer)
|
||||||
|
{
|
||||||
|
auto* layerNode = static_cast<LayerTreeLayer*>(child);
|
||||||
|
if (layerNode->mapLayer() == layer)
|
||||||
|
{
|
||||||
|
QModelIndex nodeIndex = m_LayerTreeModel->index(i, 0,
|
||||||
|
m_LayerTreeModel->index(m_RasterGroup->rowInParent(), 0));
|
||||||
|
// Block signals to avoid infinite loop with onLayerTreeSelectionChanged
|
||||||
|
m_layerTreeView->selectionModel()->blockSignals(true);
|
||||||
|
m_layerTreeView->setCurrentIndex(nodeIndex);
|
||||||
|
m_layerTreeView->selectionModel()->blockSignals(false);
|
||||||
|
|
||||||
|
// Manually update ImageControl since we blocked the signal
|
||||||
|
RasterLayer* rl = qobject_cast<RasterLayer*>(layer);
|
||||||
|
if (rl)
|
||||||
|
{
|
||||||
|
m_ic->setActiveLayer(rl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HPPA::onActionOpenDirectory()
|
void HPPA::onActionOpenDirectory()
|
||||||
@ -1570,16 +1605,7 @@ void HPPA::onOpenImg()
|
|||||||
QFileInfo fi(uri);
|
QFileInfo fi(uri);
|
||||||
QString baseName = fi.completeBaseName();
|
QString baseName = fi.completeBaseName();
|
||||||
|
|
||||||
RasterLayer* rl = new RasterLayer(baseName, uri);
|
addLayer(baseName, uri, true);
|
||||||
|
|
||||||
auto* layerNode = new LayerTreeLayerNode(rl);
|
|
||||||
m_LayerTreeModel->addLayer(m_RasterGroup, layerNode);
|
|
||||||
|
|
||||||
QWidget* mapcavasContainer = onCreateTab(baseName);
|
|
||||||
if (m_MapLayerStore) m_MapLayerStore->addLayer(rl, mapcavasContainer);
|
|
||||||
QList<Mapcavas*> mapcavas = mapcavasContainer->findChildren<Mapcavas*>();
|
|
||||||
mapcavas[0]->setLayers(rl);
|
|
||||||
mapcavas[0]->freshmap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HPPA::onconnect()
|
void HPPA::onconnect()
|
||||||
@ -1722,26 +1748,6 @@ void HPPA::testImagerStatus()
|
|||||||
m_TestImagerStausThread->start();
|
m_TestImagerStausThread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HPPA::onImageFileSaved(QString path, int fileIndex)
|
|
||||||
{
|
|
||||||
// 该槽在 UI 线程中执行(Qt 会使用 queued connection),可以安全操作 model
|
|
||||||
QFileInfo fi(path);
|
|
||||||
QString base = fi.completeBaseName(); // 去掉路径与扩展名(例如 tmp_image_0)
|
|
||||||
|
|
||||||
// 将新的 layer 添加到 Raster 分组
|
|
||||||
if (!m_LayerTreeModel || !m_RasterGroup) return;
|
|
||||||
|
|
||||||
// layer 名称可根据需要调整,这里用文件名作为图层名
|
|
||||||
{
|
|
||||||
auto* ln = new LayerTreeLayerNode(nullptr);
|
|
||||||
ln->setName(base);
|
|
||||||
m_LayerTreeModel->addLayer(m_RasterGroup, ln);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 可选:展开 TOC 或者做其他 UI 更新(目前不做动画,仅打印日志)
|
|
||||||
qDebug() << "ImageFileSaved -> add layer:" << base << " index:" << fileIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HPPA::onAutoExposure()
|
void HPPA::onAutoExposure()
|
||||||
{
|
{
|
||||||
double ReturnedExposureTime = m_Imager->auto_exposure();
|
double ReturnedExposureTime = m_Imager->auto_exposure();
|
||||||
@ -2045,23 +2051,26 @@ void WorkerThread3::run()
|
|||||||
void HPPA::onLayerCreatedFromFile(const QString& baseName, const QString& filePath, int fileIndex)
|
void HPPA::onLayerCreatedFromFile(const QString& baseName, const QString& filePath, int fileIndex)
|
||||||
{
|
{
|
||||||
if (!m_LayerTreeModel || !m_RasterGroup) return;
|
if (!m_LayerTreeModel || !m_RasterGroup) return;
|
||||||
|
addLayer(baseName, filePath, false);
|
||||||
|
}
|
||||||
|
|
||||||
QWidget* mapcavasContainer = onCreateTab(baseName);
|
void HPPA::addLayer(const QString& baseName, const QString& filePath,bool refresh)
|
||||||
|
{
|
||||||
// Create MapLayer first and attach it to a LayerTreeLayerNode
|
// Create MapLayer first and attach it to a LayerTreeLayerNode
|
||||||
RasterLayer* ml = new RasterLayer(baseName, filePath);
|
RasterLayer* ml = new RasterLayer(baseName, filePath);
|
||||||
|
|
||||||
|
auto* layerNode = new LayerTreeLayer(ml);
|
||||||
|
LayerTreeNode* node = m_LayerTreeModel->addLayer(m_RasterGroup, layerNode);
|
||||||
|
|
||||||
|
QWidget* mapcavasContainer = onCreateTab(baseName);
|
||||||
if (m_MapLayerStore) m_MapLayerStore->addLayer(ml, mapcavasContainer);
|
if (m_MapLayerStore) m_MapLayerStore->addLayer(ml, mapcavasContainer);
|
||||||
QList<Mapcavas*> mapcavas = mapcavasContainer->findChildren<Mapcavas*>();
|
QList<Mapcavas*> mapcavas = mapcavasContainer->findChildren<Mapcavas*>();
|
||||||
mapcavas[0]->setLayers(ml);
|
mapcavas[0]->setLayers(ml);
|
||||||
|
|
||||||
auto* layerNode = new LayerTreeLayerNode(ml);
|
if (refresh)
|
||||||
LayerTreeNode* node = m_LayerTreeModel->addLayer(m_RasterGroup, layerNode);
|
{
|
||||||
LayerTreeLayerNode* lnode = dynamic_cast<LayerTreeLayerNode*>(node);
|
mapcavas[0]->freshmap();
|
||||||
if (!lnode) return;
|
}
|
||||||
|
|
||||||
// layerNode already holds the MapLayer pointer from constructor
|
|
||||||
|
|
||||||
qDebug() << "LayerFileCreated -> created layer:" << baseName << "path:" << filePath << "index:" << fileIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HPPA::onLayerTreeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
|
void HPPA::onLayerTreeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
|
||||||
@ -2085,7 +2094,7 @@ void HPPA::onLayerTreeSelectionChanged(const QItemSelection& selected, const QIt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
|
auto* layerNode = static_cast<LayerTreeLayer*>(node);
|
||||||
MapLayer* mapLayer = layerNode->mapLayer();
|
MapLayer* mapLayer = layerNode->mapLayer();
|
||||||
if (!mapLayer || mapLayer->layerType() != MapLayer::LayerType::Raster) {
|
if (!mapLayer || mapLayer->layerType() != MapLayer::LayerType::Raster) {
|
||||||
m_ic->setActiveLayer(nullptr);
|
m_ic->setActiveLayer(nullptr);
|
||||||
|
|||||||
@ -341,8 +341,7 @@ public Q_SLOTS:
|
|||||||
void onCreated3DModelPlantPhenotype();
|
void onCreated3DModelPlantPhenotype();
|
||||||
void onCreated3DModelOneMotor();
|
void onCreated3DModelOneMotor();
|
||||||
|
|
||||||
void onImageFileSaved(QString path, int fileIndex);
|
void addLayer(const QString& baseName, const QString& filePath, bool refresh);
|
||||||
|
|
||||||
void onLayerCreatedFromFile(const QString& baseName, const QString& filePath, int fileIndex);
|
void onLayerCreatedFromFile(const QString& baseName, const QString& filePath, int fileIndex);
|
||||||
void removeLayerByTreeIndex();
|
void removeLayerByTreeIndex();
|
||||||
void removeAllLayersInRasterGroup();
|
void removeAllLayersInRasterGroup();
|
||||||
|
|||||||
@ -103,6 +103,50 @@ bool Mapcavas::HasImage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mapcavas::updateCrosshair(double sceneX, double sceneY)
|
||||||
|
{
|
||||||
|
QPen pen(Qt::red, 2.0);
|
||||||
|
pen.setCosmetic(true); // constant screen-width regardless of zoom
|
||||||
|
|
||||||
|
if (!m_hLine)
|
||||||
|
{
|
||||||
|
m_hLine = m_qtGraphicsScene->addLine(0, 0, 0, 0, pen);
|
||||||
|
m_hLine->setZValue(1e9);
|
||||||
|
}
|
||||||
|
if (!m_vLine)
|
||||||
|
{
|
||||||
|
m_vLine = m_qtGraphicsScene->addLine(0, 0, 0, 0, pen);
|
||||||
|
m_vLine->setZValue(1e9);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hLine->setPen(pen);
|
||||||
|
m_vLine->setPen(pen);
|
||||||
|
|
||||||
|
m_hLine->setLine(sceneX - m_CrosshairHalfLen, sceneY,
|
||||||
|
sceneX + m_CrosshairHalfLen, sceneY);
|
||||||
|
m_vLine->setLine(sceneX, sceneY - m_CrosshairHalfLen,
|
||||||
|
sceneX, sceneY + m_CrosshairHalfLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapcavas::removeCrosshair()
|
||||||
|
{
|
||||||
|
if (m_hLine)
|
||||||
|
{
|
||||||
|
if (m_hLine->scene())
|
||||||
|
m_hLine->scene()->removeItem(m_hLine);
|
||||||
|
delete m_hLine;
|
||||||
|
m_hLine = nullptr;
|
||||||
|
}
|
||||||
|
if (m_vLine)
|
||||||
|
{
|
||||||
|
if (m_vLine->scene())
|
||||||
|
m_vLine->scene()->removeItem(m_vLine);
|
||||||
|
delete m_vLine;
|
||||||
|
m_vLine = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapcavas::wheelEvent(QWheelEvent *event)
|
void Mapcavas::wheelEvent(QWheelEvent *event)
|
||||||
{
|
{
|
||||||
// Always let the tool have a chance first
|
// Always let the tool have a chance first
|
||||||
|
|||||||
@ -29,6 +29,9 @@ public:
|
|||||||
bool HasImage();
|
bool HasImage();
|
||||||
void ensureSceneVisible();
|
void ensureSceneVisible();
|
||||||
|
|
||||||
|
void updateCrosshair(double sceneX, double sceneY);
|
||||||
|
void removeCrosshair();
|
||||||
|
|
||||||
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
|
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
|
||||||
void scaling(qreal scaleFactor);
|
void scaling(qreal scaleFactor);
|
||||||
|
|
||||||
@ -71,6 +74,10 @@ private:
|
|||||||
QPoint m_lastMousePos; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>λ<EFBFBD><CEBB>
|
QPoint m_lastMousePos; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>λ<EFBFBD><CEBB>
|
||||||
qreal m_scale; // <20><><EFBFBD><EFBFBD>ֵ
|
qreal m_scale; // <20><><EFBFBD><EFBFBD>ֵ
|
||||||
|
|
||||||
|
double m_CrosshairHalfLen = 10.0;
|
||||||
|
QGraphicsLineItem* m_hLine = nullptr; // horizontal line
|
||||||
|
QGraphicsLineItem* m_vLine = nullptr; // vertical line
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void leftMouseButtonPressed(int, int, QVector<double>, QVector<double>);
|
void leftMouseButtonPressed(int, int, QVector<double>, QVector<double>);
|
||||||
|
|||||||
@ -1,39 +1,13 @@
|
|||||||
#include "LayerTree.h"
|
#include "LayerTree.h"
|
||||||
#include "LayerTreeGroupNode.h"
|
|
||||||
|
|
||||||
LayerTree::LayerTree(QObject* parent)
|
LayerTree::LayerTree(QObject* parent)
|
||||||
: QObject(parent)
|
: LayerTreeGroup("__root__", parent)
|
||||||
{
|
{
|
||||||
// root <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> view <20><><EFBFBD><EFBFBD>ʾ
|
setVisible(Qt::Checked);
|
||||||
m_root = new LayerTreeGroupNode("__root__", this);
|
|
||||||
m_root->setVisible(Qt::Checked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTree::~LayerTree()
|
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)
|
void LayerTree::setChildrenVisible(LayerTreeNode* n, Qt::CheckState state)
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include "LayerTreeGroupNode.h"
|
||||||
#include "LayerTreeNode.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LayerTree<65><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* LayerTree<65><65>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
* - <20><><EFBFBD><EFBFBD> root
|
* - <20>̳<EFBFBD><EFBFBD><EFBFBD> LayerTreeGroup<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
* - <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>
|
* - <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>
|
* ע<>⣺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>
|
* LayerTree ֻ<><D6BB><EFBFBD><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9>ȷ<EFBFBD>ԡ<EFBFBD>
|
||||||
*/
|
*/
|
||||||
class LayerTree : public QObject
|
class LayerTree : public LayerTreeGroup
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -22,28 +20,7 @@ public:
|
|||||||
LayerTree(const LayerTree&) = delete;
|
LayerTree(const LayerTree&) = delete;
|
||||||
LayerTree& operator=(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>
|
// <20>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD> Model <20><><EFBFBD>ã<EFBFBD>
|
||||||
static void setChildrenVisible(LayerTreeNode* n, Qt::CheckState state);
|
static void setChildrenVisible(LayerTreeNode* n, Qt::CheckState state);
|
||||||
static void updateParentVisibleFromChildren(LayerTreeNode* parent);
|
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
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,103 @@
|
|||||||
#include "LayerTreeGroupNode.h"
|
#include "LayerTreeGroupNode.h"
|
||||||
|
#include "LayerTreeLayerNode.h"
|
||||||
|
|
||||||
LayerTreeGroupNode::LayerTreeGroupNode(const QString& name, QObject* parent)
|
LayerTreeGroup::LayerTreeGroup(const QString& name, QObject* parent)
|
||||||
: LayerTreeNode(name, parent)
|
: LayerTreeNode(name, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerTreeGroup* LayerTreeGroup::insertGroup(int index, const QString& name)
|
||||||
|
{
|
||||||
|
auto* group = new LayerTreeGroup(name);
|
||||||
|
insertChildNode(index, group);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeGroup* LayerTreeGroup::addGroup(const QString& name)
|
||||||
|
{
|
||||||
|
return insertGroup(childCount(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeLayer* LayerTreeGroup::insertLayer(int index, LayerTreeLayer* layer)
|
||||||
|
{
|
||||||
|
if (!layer) return nullptr;
|
||||||
|
insertChildNode(index, layer);
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeLayer* LayerTreeGroup::addLayer(LayerTreeLayer* layer)
|
||||||
|
{
|
||||||
|
return insertLayer(childCount(), layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeGroup::insertChildNode(int index, LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
insertChild(index, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTreeGroup::addChildNode(LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
appendChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeNode* LayerTreeGroup::removeChildNode(LayerTreeNode* node)
|
||||||
|
{
|
||||||
|
if (!node) return nullptr;
|
||||||
|
int row = -1;
|
||||||
|
for (int i = 0; i < childCount(); ++i)
|
||||||
|
{
|
||||||
|
if (childAt(i) == node)
|
||||||
|
{
|
||||||
|
row = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row < 0) return nullptr;
|
||||||
|
removeChild(row, 1, false);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerTreeLayer* LayerTreeGroup::findLayer(const QString& name) const
|
||||||
|
{
|
||||||
|
const auto layers = findLayers();
|
||||||
|
for (auto* l : layers)
|
||||||
|
{
|
||||||
|
if (l->name() == name)
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<LayerTreeLayer*> LayerTreeGroup::findLayers() const
|
||||||
|
{
|
||||||
|
QList<LayerTreeLayer*> result;
|
||||||
|
for (int i = 0; i < childCount(); ++i)
|
||||||
|
{
|
||||||
|
LayerTreeNode* child = childAt(i);
|
||||||
|
if (LayerTreeNode::isLayer(child))
|
||||||
|
{
|
||||||
|
result.append(static_cast<LayerTreeLayer*>(child));
|
||||||
|
}
|
||||||
|
else if (LayerTreeNode::isGroup(child))
|
||||||
|
{
|
||||||
|
result.append(static_cast<LayerTreeGroup*>(child)->findLayers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<LayerTreeGroup*> LayerTreeGroup::findGroups() const
|
||||||
|
{
|
||||||
|
QList<LayerTreeGroup*> result;
|
||||||
|
for (int i = 0; i < childCount(); ++i)
|
||||||
|
{
|
||||||
|
LayerTreeNode* child = childAt(i);
|
||||||
|
if (LayerTreeNode::isGroup(child))
|
||||||
|
{
|
||||||
|
auto* g = static_cast<LayerTreeGroup*>(child);
|
||||||
|
result.append(g);
|
||||||
|
result.append(g->findGroups());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,15 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "LayerTreeNode.h"
|
#include "LayerTreeNode.h"
|
||||||
|
|
||||||
/** Group <20>ڵ<EFBFBD> */
|
class LayerTreeLayer;
|
||||||
class LayerTreeGroupNode : public LayerTreeNode
|
|
||||||
|
/**
|
||||||
|
* LayerTreeGroup<75><70>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
|
* - <20><><EFBFBD><EFBFBD>Ϊ LayerTreeNode
|
||||||
|
* - <20>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ڵ㣨LayerTreeLayer<65><72><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>飨LayerTreeGroup<75><70><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
*/
|
||||||
|
class LayerTreeGroup : public LayerTreeNode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LayerTreeGroupNode(const QString& name,
|
explicit LayerTreeGroup(const QString& name = QString(),
|
||||||
QObject* parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
Type type() const override { return Type::Group; }
|
Type type() const override { return Type::Group; }
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
LayerTreeGroup* insertGroup(int index, const QString& name);
|
||||||
|
LayerTreeGroup* addGroup(const QString& name);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ڵ<EFBFBD>
|
||||||
|
LayerTreeLayer* insertLayer(int index, LayerTreeLayer* layer);
|
||||||
|
LayerTreeLayer* addLayer(LayerTreeLayer* layer);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
|
void insertChildNode(int index, LayerTreeNode* node);
|
||||||
|
void addChildNode(LayerTreeNode* node);
|
||||||
|
|
||||||
|
// <20>Ƴ<EFBFBD><C6B3>ӽڵ㣨<DAB5><E3A3A8> delete<74><65><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1>Ƴ<EFBFBD><C6B3>ڵ㣩
|
||||||
|
LayerTreeNode* removeChildNode(LayerTreeNode* node);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>
|
||||||
|
LayerTreeLayer* findLayer(const QString& name) const;
|
||||||
|
QList<LayerTreeLayer*> findLayers() const;
|
||||||
|
QList<LayerTreeGroup*> findGroups() const;
|
||||||
|
|
||||||
// <20>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>collapsed / groupOpacity <20><>
|
// <20>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>collapsed / groupOpacity <20><>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
using LayerTreeGroupNode = LayerTreeGroup;
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
#include "LayerTreeLayerNode.h"
|
#include "LayerTreeLayerNode.h"
|
||||||
|
|
||||||
LayerTreeLayerNode::LayerTreeLayerNode(MapLayer* layer, QObject* parent)
|
LayerTreeLayer::LayerTreeLayer(MapLayer* layer, QObject* parent)
|
||||||
: LayerTreeNode(layer ? layer->name() : QString(), parent), m_layer(layer)
|
: LayerTreeNode(layer ? layer->name() : QString(), parent), m_layer(layer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTreeNode::Type LayerTreeLayerNode::type() const
|
LayerTreeNode::Type LayerTreeLayer::type() const
|
||||||
{
|
{
|
||||||
return Type::Layer;
|
return Type::Layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> MapLayer ָ<>루<EFBFBD><EBA3A8>ӵ<EFBFBD>У<EFBFBD>
|
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> MapLayer ָ<>루<EFBFBD><EBA3A8>ӵ<EFBFBD>У<EFBFBD>
|
||||||
void LayerTreeLayerNode::setMapLayer(MapLayer* layer)
|
void LayerTreeLayer::setMapLayer(MapLayer* layer)
|
||||||
{
|
{
|
||||||
m_layer = layer;
|
m_layer = layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapLayer* LayerTreeLayerNode::mapLayer() const
|
MapLayer* LayerTreeLayer::mapLayer() const
|
||||||
{
|
{
|
||||||
return m_layer;
|
return m_layer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,16 +2,19 @@
|
|||||||
#include "LayerTreeNode.h"
|
#include "LayerTreeNode.h"
|
||||||
#include "MapLayer.h"
|
#include "MapLayer.h"
|
||||||
|
|
||||||
/** Layer <20>ڵ<EFBFBD> */
|
/**
|
||||||
class LayerTreeLayerNode : public LayerTreeNode
|
* LayerTreeLayer<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
|
* - <20><><EFBFBD><EFBFBD>Ϊ LayerTreeNode
|
||||||
|
* - <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> MapLayer ָ<>루<EFBFBD><EBA3A8>ӵ<EFBFBD>У<EFBFBD>
|
||||||
|
*/
|
||||||
|
class LayerTreeLayer : public LayerTreeNode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LayerTreeLayerNode(MapLayer* layer, QObject* parent = nullptr);
|
explicit LayerTreeLayer(MapLayer* layer, QObject* parent = nullptr);
|
||||||
|
|
||||||
Type type() const override;
|
Type type() const override;
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> MapLayer ָ<>루<EFBFBD><EBA3A8>ӵ<EFBFBD>У<EFBFBD>
|
|
||||||
void setMapLayer(MapLayer* layer);
|
void setMapLayer(MapLayer* layer);
|
||||||
MapLayer* mapLayer() const;
|
MapLayer* mapLayer() const;
|
||||||
|
|
||||||
@ -20,3 +23,6 @@ private:
|
|||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>layerId / pointer / legendItems <20><>
|
// <20><><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>layerId / pointer / legendItems <20><>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
using LayerTreeLayerNode = LayerTreeLayer;
|
||||||
|
|||||||
@ -28,10 +28,10 @@ QModelIndex LayerTreeModel::index(int row, int column, const QModelIndex& parent
|
|||||||
QModelIndex LayerTreeModel::parent(const QModelIndex& child) const
|
QModelIndex LayerTreeModel::parent(const QModelIndex& child) const
|
||||||
{
|
{
|
||||||
LayerTreeNode* node = nodeFromIndex(child);
|
LayerTreeNode* node = nodeFromIndex(child);
|
||||||
if (!node || node == m_tree->root()) return {};
|
if (!node || node == m_tree) return {};
|
||||||
|
|
||||||
LayerTreeNode* p = node->parentNode();
|
LayerTreeNode* p = node->parentNode();
|
||||||
if (!p || p == m_tree->root()) return {};
|
if (!p || p == m_tree) return {};
|
||||||
|
|
||||||
return createIndex(p->rowInParent(), 0, p);
|
return createIndex(p->rowInParent(), 0, p);
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ int LayerTreeModel::columnCount(const QModelIndex&) const
|
|||||||
QVariant LayerTreeModel::data(const QModelIndex& index, int role) const
|
QVariant LayerTreeModel::data(const QModelIndex& index, int role) const
|
||||||
{
|
{
|
||||||
LayerTreeNode* n = nodeFromIndex(index);
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
if (!n || n == m_tree->root()) return {};
|
if (!n || n == m_tree) return {};
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
@ -59,9 +59,9 @@ QVariant LayerTreeModel::data(const QModelIndex& index, int role) const
|
|||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
{
|
{
|
||||||
auto* tmp = nodeFromIndex(index);
|
auto* tmp = nodeFromIndex(index);
|
||||||
if (LayerTree::isGroup(tmp))
|
if (LayerTreeNode::isGroup(tmp))
|
||||||
return QIcon();
|
return QIcon();
|
||||||
else if (LayerTree::isLayer(tmp))
|
else if (LayerTreeNode::isLayer(tmp))
|
||||||
{
|
{
|
||||||
QString basePath = QCoreApplication::applicationDirPath();
|
QString basePath = QCoreApplication::applicationDirPath();
|
||||||
return QIcon(basePath + "/icons/mIconRaster.svg");
|
return QIcon(basePath + "/icons/mIconRaster.svg");
|
||||||
@ -82,7 +82,7 @@ QVariant LayerTreeModel::data(const QModelIndex& index, int role) const
|
|||||||
bool LayerTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
bool LayerTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
{
|
{
|
||||||
LayerTreeNode* n = nodeFromIndex(index);
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
if (!n || n == m_tree->root()) return false;
|
if (!n || n == m_tree) return false;
|
||||||
|
|
||||||
if (role == Qt::CheckStateRole) {
|
if (role == Qt::CheckStateRole) {
|
||||||
auto newState = static_cast<Qt::CheckState>(value.toInt());
|
auto newState = static_cast<Qt::CheckState>(value.toInt());
|
||||||
@ -111,39 +111,39 @@ Qt::ItemFlags LayerTreeModel::flags(const QModelIndex& index) const
|
|||||||
if (!index.isValid()) return Qt::NoItemFlags;
|
if (!index.isValid()) return Qt::NoItemFlags;
|
||||||
|
|
||||||
LayerTreeNode* n = nodeFromIndex(index);
|
LayerTreeNode* n = nodeFromIndex(index);
|
||||||
if (!n || n == m_tree->root()) return Qt::NoItemFlags;
|
if (!n || n == m_tree) return Qt::NoItemFlags;
|
||||||
|
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTreeNode* LayerTreeModel::root() const
|
LayerTreeNode* LayerTreeModel::root() const
|
||||||
{
|
{
|
||||||
return m_tree->root();
|
return m_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTreeNode* LayerTreeModel::addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon)
|
LayerTreeNode* LayerTreeModel::addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon)
|
||||||
{
|
{
|
||||||
if (!parent) parent = m_tree->root();
|
if (!parent) parent = m_tree;
|
||||||
|
|
||||||
const int row = parent->childCount();
|
const int row = parent->childCount();
|
||||||
beginInsertRows(indexFromNode(parent), row, row);
|
beginInsertRows(indexFromNode(parent), row, row);
|
||||||
LayerTreeNode* g = m_tree->insertNode(parent, row, new LayerTreeGroupNode(name));
|
LayerTreeNode* g = m_tree->addGroup(name);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTreeNode* LayerTreeModel::addLayer(LayerTreeNode* parent, LayerTreeLayerNode* layerNode, const QIcon& icon)
|
LayerTreeNode* LayerTreeModel::addLayer(LayerTreeNode* parent, LayerTreeLayer* layerNode, const QIcon& icon)
|
||||||
{
|
{
|
||||||
if (!parent) parent = m_tree->root();
|
if (!parent) parent = m_tree;
|
||||||
if (!layerNode) return nullptr;
|
if (!layerNode) return nullptr;
|
||||||
|
|
||||||
const int row = parent->childCount();
|
const int row = parent->childCount();
|
||||||
beginInsertRows(indexFromNode(parent), row, row);
|
beginInsertRows(indexFromNode(parent), row, row);
|
||||||
LayerTreeNode* l = m_tree->insertNode(parent, row, layerNode);
|
parent->insertChild(row, layerNode);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
return l;
|
return layerNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerTreeModel::setCascadeCheckEnabled(bool enabled)
|
void LayerTreeModel::setCascadeCheckEnabled(bool enabled)
|
||||||
@ -159,11 +159,12 @@ bool LayerTreeModel::cascadeCheckEnabled() const
|
|||||||
// <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3>Ƴ<EFBFBD><C6B3>ӽڵ㲢<DAB5><E3B2A2> model <20>Ϸ<EFBFBD><CFB7><EFBFBD> begin/endRemoveRows
|
// <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3>Ƴ<EFBFBD><C6B3>ӽڵ㲢<DAB5><E3B2A2> model <20>Ϸ<EFBFBD><CFB7><EFBFBD> begin/endRemoveRows
|
||||||
LayerTreeNode* LayerTreeModel::removeNode(LayerTreeNode* parent, int row)
|
LayerTreeNode* LayerTreeModel::removeNode(LayerTreeNode* parent, int row)
|
||||||
{
|
{
|
||||||
if (!parent) parent = m_tree->root();
|
if (!parent) parent = m_tree;
|
||||||
if (row < 0 || row >= parent->childCount()) return nullptr;
|
if (row < 0 || row >= parent->childCount()) return nullptr;
|
||||||
|
|
||||||
|
LayerTreeNode* removed = parent->childAt(row);
|
||||||
beginRemoveRows(indexFromNode(parent), row, row);
|
beginRemoveRows(indexFromNode(parent), row, row);
|
||||||
LayerTreeNode* removed = m_tree->removeNode(parent, row);
|
parent->removeChild(row, 1, false);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
@ -171,12 +172,12 @@ LayerTreeNode* LayerTreeModel::removeNode(LayerTreeNode* parent, int row)
|
|||||||
|
|
||||||
LayerTreeNode* LayerTreeModel::nodeFromIndex(const QModelIndex& index) const
|
LayerTreeNode* LayerTreeModel::nodeFromIndex(const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid()) return m_tree->root();
|
if (!index.isValid()) return m_tree;
|
||||||
return static_cast<LayerTreeNode*>(index.internalPointer());
|
return static_cast<LayerTreeNode*>(index.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex LayerTreeModel::indexFromNode(LayerTreeNode* n) const
|
QModelIndex LayerTreeModel::indexFromNode(LayerTreeNode* n) const
|
||||||
{
|
{
|
||||||
if (!n || n == m_tree->root()) return {};
|
if (!n || n == m_tree) return {};
|
||||||
return createIndex(n->rowInParent(), 0, n);
|
return createIndex(n->rowInParent(), 0, n);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include "LayerTree.h"
|
#include "LayerTree.h"
|
||||||
|
|
||||||
class LayerTreeLayerNode; // forward declare
|
class LayerTreeLayer; // forward declare
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LayerTreeModel<65><6C>Qt <20><><EFBFBD><EFBFBD><EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD>ٹ<EFBFBD><D9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* LayerTreeModel<65><6C>Qt <20><><EFBFBD><EFBFBD><EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD>ٹ<EFBFBD><D9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
LayerTreeNode* root() const;
|
LayerTreeNode* root() const;
|
||||||
|
|
||||||
LayerTreeNode* addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon = QIcon());
|
LayerTreeNode* addGroup(LayerTreeNode* parent, const QString& name, const QIcon& icon = QIcon());
|
||||||
LayerTreeNode* addLayer(LayerTreeNode* parent, LayerTreeLayerNode* layerNode, const QIcon& icon = QIcon());
|
LayerTreeNode* addLayer(LayerTreeNode* parent, LayerTreeLayer* layerNode, const QIcon& icon = QIcon());
|
||||||
|
|
||||||
void setCascadeCheckEnabled(bool enabled);
|
void setCascadeCheckEnabled(bool enabled);
|
||||||
bool cascadeCheckEnabled() const;
|
bool cascadeCheckEnabled() const;
|
||||||
|
|||||||
@ -19,8 +19,12 @@ QString LayerTreeNode::name() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LayerTreeNode::setName(const QString& name)
|
void LayerTreeNode::setName(const QString& name)
|
||||||
|
{
|
||||||
|
if (m_name != name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
|
emit nameChanged(this, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon LayerTreeNode::icon() const
|
QIcon LayerTreeNode::icon() const
|
||||||
@ -97,14 +101,35 @@ void LayerTreeNode::insertChild(int row, LayerTreeNode* child)
|
|||||||
if (row < 0 || row > m_children.size())
|
if (row < 0 || row > m_children.size())
|
||||||
row = m_children.size();
|
row = m_children.size();
|
||||||
|
|
||||||
|
emit willAddChildren(this, row, row);
|
||||||
child->setParentNode(this);
|
child->setParentNode(this);
|
||||||
m_children.insert(row, child);
|
m_children.insert(row, child);
|
||||||
|
emit addedChildren(this, row, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerTreeNode* LayerTreeNode::takeChild(int row)
|
void LayerTreeNode::removeChild(int from, int count, bool destroy)
|
||||||
{
|
{
|
||||||
if (row < 0 || row >= m_children.size()) return nullptr;
|
if (from < 0 || count <= 0 || from + count > m_children.size()) return;
|
||||||
LayerTreeNode* taken = m_children.takeAt(row);
|
|
||||||
if (taken) taken->setParentNode(nullptr);
|
emit willRemoveChildren(this, from, from + count - 1);
|
||||||
return taken;
|
|
||||||
|
QVector<LayerTreeNode*> removed;
|
||||||
|
removed.reserve(count);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
removed.append(m_children.at(from));
|
||||||
|
m_children.removeAt(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LayerTreeNode* node : removed)
|
||||||
|
{
|
||||||
|
node->setParentNode(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit removedChildren(this, from, from + count - 1);
|
||||||
|
|
||||||
|
if (destroy)
|
||||||
|
{
|
||||||
|
qDeleteAll(removed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,10 @@
|
|||||||
* LayerTreeNode<64><65><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ࣨ<EFBFBD><E0A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* 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>ϵ
|
* - <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>
|
* - Group / Layer <20>ڵ<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD>̳<EFBFBD>ʵ<EFBFBD><CAB5>
|
||||||
|
* - <20>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>/ɾ<><C9BE><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ź<EFBFBD>֪ͨ
|
||||||
*
|
*
|
||||||
* ˵<><CBB5><EFBFBD><EFBFBD>
|
* ˵<><CBB5><EFBFBD><EFBFBD>
|
||||||
* - <20><><EFBFBD><EFBFBD>ͬʱά<CAB1><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>롱<EFBFBD><EFBFBD>m_parentNode<EFBFBD><EFBFBD><EFBFBD><EFBFBD> QObject parent<6E><74><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
* - <20><><EFBFBD><EFBFBD>ͬʱά<CAB1><CEAC>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>m_parentNode<EFBFBD><EFBFBD><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>
|
* - 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
|
class LayerTreeNode : public QObject
|
||||||
@ -50,7 +51,32 @@ public:
|
|||||||
// ---- structure mutation (used by LayerTree / Model) ----
|
// ---- structure mutation (used by LayerTree / Model) ----
|
||||||
void appendChild(LayerTreeNode* child);
|
void appendChild(LayerTreeNode* child);
|
||||||
void insertChild(int row, LayerTreeNode* child);
|
void insertChild(int row, LayerTreeNode* child);
|
||||||
LayerTreeNode* takeChild(int row); // remove but not delete
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> QgsLayerTreeNode::removeChildrenPrivate <20>Ľ<EFBFBD>
|
||||||
|
// from: <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>, count: <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>, destroy: true <20><> delete <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ڵ<EFBFBD>
|
||||||
|
void removeChild(int from, int count, bool destroy = true);
|
||||||
|
|
||||||
|
// ---- static type helpers ----
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>ӽڵ<D3BD>֮ǰ/֮<><EFBFBD>
|
||||||
|
void willAddChildren(LayerTreeNode* node, int indexFrom, int indexTo);
|
||||||
|
void addedChildren(LayerTreeNode* node, int indexFrom, int indexTo);
|
||||||
|
|
||||||
|
// <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ӽڵ<D3BD>֮ǰ/֮<><EFBFBD>
|
||||||
|
void willRemoveChildren(LayerTreeNode* node, int indexFrom, int indexTo);
|
||||||
|
void removedChildren(LayerTreeNode* node, int indexFrom, int indexTo);
|
||||||
|
|
||||||
|
void nameChanged(LayerTreeNode* node, const QString& name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setParentNode(LayerTreeNode* p);
|
void setParentNode(LayerTreeNode* p);
|
||||||
|
|||||||
@ -81,3 +81,12 @@ QWidget* MapLayerStore::widgetForLayer(const QString& absolutePath) const
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapLayer* MapLayerStore::layerForWidget(QWidget* widget) const
|
||||||
|
{
|
||||||
|
if (!widget) return nullptr;
|
||||||
|
for (const auto& kv : m_layerWidgets) {
|
||||||
|
if (kv.second == widget) return kv.first;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -35,6 +35,9 @@ public slots:
|
|||||||
// Get associated widget by layer absolute data path
|
// Get associated widget by layer absolute data path
|
||||||
QWidget* widgetForLayer(const QString& absolutePath) const;
|
QWidget* widgetForLayer(const QString& absolutePath) const;
|
||||||
|
|
||||||
|
// Reverse lookup: find the MapLayer associated with a given widget (or nullptr)
|
||||||
|
MapLayer* layerForWidget(QWidget* widget) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void layerAdded(MapLayer* layer);
|
void layerAdded(MapLayer* layer);
|
||||||
// Emitted just before the layer is destroyed/removed from store
|
// Emitted just before the layer is destroyed/removed from store
|
||||||
|
|||||||
@ -34,7 +34,7 @@ void MapTool::setMapcavas(Mapcavas* canvas)
|
|||||||
|
|
||||||
if (m_isActive && m_canvas)
|
if (m_isActive && m_canvas)
|
||||||
{
|
{
|
||||||
deactivate();
|
//deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_canvas = canvas;
|
m_canvas = canvas;
|
||||||
|
|||||||
@ -8,8 +8,6 @@
|
|||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
const double MapToolSpectral::CrosshairHalfLen = 10.0;
|
|
||||||
|
|
||||||
MapToolSpectral::MapToolSpectral(QObject* parent)
|
MapToolSpectral::MapToolSpectral(QObject* parent)
|
||||||
: MapTool(parent)
|
: MapTool(parent)
|
||||||
{
|
{
|
||||||
@ -18,7 +16,6 @@ MapToolSpectral::MapToolSpectral(QObject* parent)
|
|||||||
|
|
||||||
MapToolSpectral::~MapToolSpectral()
|
MapToolSpectral::~MapToolSpectral()
|
||||||
{
|
{
|
||||||
//removeCrosshair();//不需要在析构函数中调用removeCrosshair(),因为当MapToolSpectral被销毁时,它的canvas()也会被销毁,crosshair的scene也会被销毁,所以crosshair会自动被删除,不会造成内存泄漏。
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapToolSpectral::activate()
|
void MapToolSpectral::activate()
|
||||||
@ -28,7 +25,7 @@ void MapToolSpectral::activate()
|
|||||||
|
|
||||||
void MapToolSpectral::deactivate()
|
void MapToolSpectral::deactivate()
|
||||||
{
|
{
|
||||||
removeCrosshair();
|
canvas()->removeCrosshair();
|
||||||
MapTool::deactivate();
|
MapTool::deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +45,7 @@ void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e)
|
|||||||
if (rl && rl->isValidPixel(x, y))
|
if (rl && rl->isValidPixel(x, y))
|
||||||
{
|
{
|
||||||
// Place crosshair at pixel center
|
// Place crosshair at pixel center
|
||||||
updateCrosshair(x + 0.5, y + 0.5);
|
canvas()->updateCrosshair(x + 0.5, y + 0.5);
|
||||||
|
|
||||||
QVector<double> wavelengths;
|
QVector<double> wavelengths;
|
||||||
QVector<double> spectrum;
|
QVector<double> spectrum;
|
||||||
@ -58,51 +55,3 @@ void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapToolSpectral::updateCrosshair(double sceneX, double sceneY)
|
|
||||||
{
|
|
||||||
if (!canvas() || !canvas()->scene())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QGraphicsScene* scene = canvas()->scene();
|
|
||||||
|
|
||||||
QPen pen(Qt::red, 2.0);
|
|
||||||
pen.setCosmetic(true); // constant screen-width regardless of zoom
|
|
||||||
|
|
||||||
if (!m_hLine)
|
|
||||||
{
|
|
||||||
m_hLine = scene->addLine(0, 0, 0, 0, pen);
|
|
||||||
m_hLine->setZValue(1e9);
|
|
||||||
}
|
|
||||||
if (!m_vLine)
|
|
||||||
{
|
|
||||||
m_vLine = scene->addLine(0, 0, 0, 0, pen);
|
|
||||||
m_vLine->setZValue(1e9);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hLine->setPen(pen);
|
|
||||||
m_vLine->setPen(pen);
|
|
||||||
|
|
||||||
m_hLine->setLine(sceneX - CrosshairHalfLen, sceneY,
|
|
||||||
sceneX + CrosshairHalfLen, sceneY);
|
|
||||||
m_vLine->setLine(sceneX, sceneY - CrosshairHalfLen,
|
|
||||||
sceneX, sceneY + CrosshairHalfLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapToolSpectral::removeCrosshair()
|
|
||||||
{
|
|
||||||
if (m_hLine)
|
|
||||||
{
|
|
||||||
if (m_hLine->scene())
|
|
||||||
m_hLine->scene()->removeItem(m_hLine);
|
|
||||||
delete m_hLine;
|
|
||||||
m_hLine = nullptr;
|
|
||||||
}
|
|
||||||
if (m_vLine)
|
|
||||||
{
|
|
||||||
if (m_vLine->scene())
|
|
||||||
m_vLine->scene()->removeItem(m_vLine);
|
|
||||||
delete m_vLine;
|
|
||||||
m_vLine = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -23,13 +23,6 @@ signals:
|
|||||||
void spectralClicked(int x, int y, QVector<double> wavelengths, QVector<double> spectrum);
|
void spectralClicked(int x, int y, QVector<double> wavelengths, QVector<double> spectrum);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateCrosshair(double sceneX, double sceneY);
|
|
||||||
void removeCrosshair();
|
|
||||||
|
|
||||||
QGraphicsLineItem* m_hLine = nullptr; // horizontal line
|
|
||||||
QGraphicsLineItem* m_vLine = nullptr; // vertical line
|
|
||||||
|
|
||||||
static const double CrosshairHalfLen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAPTOOLSPECTRAL_H
|
#endif // MAPTOOLSPECTRAL_H
|
||||||
|
|||||||
Reference in New Issue
Block a user