Compare commits
2 Commits
d74a02e0c4
...
5204e3be10
| Author | SHA1 | Date | |
|---|---|---|---|
| 5204e3be10 | |||
| c1337ffe49 |
@ -4,6 +4,7 @@
|
|||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
|
||||||
#include "ui/Menu/SystemManagerMenu.h"
|
#include "ui/Menu/SystemManagerMenu.h"
|
||||||
|
#include "ui/Menu/WindowManagerMenu.h"
|
||||||
#include "common/SpdLogger.h"
|
#include "common/SpdLogger.h"
|
||||||
#include "ui/MainFrame.h"
|
#include "ui/MainFrame.h"
|
||||||
|
|
||||||
@ -24,6 +25,10 @@ DockWidget::DockWidget(const QString& title, QWidget* parent)
|
|||||||
if (nullptr != windowManagerMenu) {
|
if (nullptr != windowManagerMenu) {
|
||||||
windowManagerMenu->AddDockWidget(this);
|
windowManagerMenu->AddDockWidget(this);
|
||||||
}
|
}
|
||||||
|
// 同步到可视的 WindowManagerMenu 列表(如果存在)
|
||||||
|
if (auto* listMenu = MainFrame::Get().GetMenuManager<WindowManagerMenu>("window_manager")) {
|
||||||
|
listMenu->AddDockWidget(this);
|
||||||
|
}
|
||||||
|
|
||||||
m_bMax = false;
|
m_bMax = false;
|
||||||
//setStyleSheet(QString("border: 1px solid #A2C2DB;"));
|
//setStyleSheet(QString("border: 1px solid #A2C2DB;"));
|
||||||
@ -35,6 +40,10 @@ DockWidget::DockWidget(QWidget* parent)
|
|||||||
SystemManagerMenu* windowManagerMenu = MainFrame::Get().GetMenuManager<SystemManagerMenu>("system_manager");
|
SystemManagerMenu* windowManagerMenu = MainFrame::Get().GetMenuManager<SystemManagerMenu>("system_manager");
|
||||||
if (nullptr != windowManagerMenu) {
|
if (nullptr != windowManagerMenu) {
|
||||||
windowManagerMenu->AddDockWidget(this);
|
windowManagerMenu->AddDockWidget(this);
|
||||||
|
}
|
||||||
|
// 同步到可视的 WindowManagerMenu 列表(如果存在)
|
||||||
|
if (auto* listMenu = MainFrame::Get().GetMenuManager<WindowManagerMenu>("window_manager")) {
|
||||||
|
listMenu->AddDockWidget(this);
|
||||||
}
|
}
|
||||||
m_bMax = false;
|
m_bMax = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,7 @@ void MainWindow::InitUI() {
|
|||||||
|
|
||||||
connect(modelBrowser_, &ModelBrowser::WorkSpaceChange, propertyBrowser_, &PropertyBrowser::OnWorkSpaceChange);
|
connect(modelBrowser_, &ModelBrowser::WorkSpaceChange, propertyBrowser_, &PropertyBrowser::OnWorkSpaceChange);
|
||||||
connect(modelBrowser_, &ModelBrowser::EntityChange, propertyBrowser_, &PropertyBrowser::OnEntityChange);
|
connect(modelBrowser_, &ModelBrowser::EntityChange, propertyBrowser_, &PropertyBrowser::OnEntityChange);
|
||||||
|
connect(modelBrowser_, &ModelBrowser::FileEntryChange, propertyBrowser_, &PropertyBrowser::OnFileEntryChange);
|
||||||
|
|
||||||
qtOsgViewWidget_ = new OsgWidget;
|
qtOsgViewWidget_ = new OsgWidget;
|
||||||
qtOsgViewWidget_->Initialize();
|
qtOsgViewWidget_->Initialize();
|
||||||
|
|||||||
@ -31,11 +31,18 @@ void SystemManagerMenu::AddDockWidget(class DockWidget* dockWidget) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setChecked(!dockWidget->isVisible());
|
// 勾选状态应与可见状态一致
|
||||||
|
action->setChecked(dockWidget->isVisible());
|
||||||
|
// 绑定 dock 到 action,便于打开菜单时同步状态
|
||||||
|
action->setData(QVariant::fromValue(dockWidget));
|
||||||
connect(action, &QAction::triggered, [dockWidget, action]() {
|
connect(action, &QAction::triggered, [dockWidget, action]() {
|
||||||
dockWidget->setVisible(action->isChecked());
|
dockWidget->setVisible(action->isChecked());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// 同步可见性变化到勾选状态
|
||||||
|
connect(dockWidget, &DockWidget::visibilityChanged, [action](bool visible) {
|
||||||
|
action->setChecked(visible);
|
||||||
|
});
|
||||||
connect(dockWidget, &DockWidget::signalClose, [action]() {
|
connect(dockWidget, &DockWidget::signalClose, [action]() {
|
||||||
action->setChecked(false);
|
action->setChecked(false);
|
||||||
});
|
});
|
||||||
@ -64,7 +71,17 @@ void SystemManagerMenu::OnExit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SystemManagerMenu::OnWindowManagerMenu() {
|
void SystemManagerMenu::OnWindowManagerMenu() {
|
||||||
// 添加窗口管理菜单
|
// <EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><EFBFBD>ڹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>
|
||||||
LOG_INFO("add window manager menu");
|
LOG_INFO("add window manager menu");
|
||||||
|
// 打开菜单前,同步所有条目的勾选状态与当前 dock 可见性
|
||||||
|
for (QAction* act : windowManagerMenu_->actions()) {
|
||||||
|
QVariant v = act->data();
|
||||||
|
if (v.isValid()) {
|
||||||
|
DockWidget* dock = v.value<DockWidget*>();
|
||||||
|
if (dock) {
|
||||||
|
act->setChecked(dock->isVisible());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
windowManagerMenu_->exec(QCursor::pos());
|
windowManagerMenu_->exec(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,14 +33,18 @@ void WindowManagerMenu::AddDockWidget(DockWidget* dockWidget) {
|
|||||||
item->setText(title);
|
item->setText(title);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// 初始勾选状态与 dock 的可见性同步
|
||||||
item->setCheckState(Qt::Checked);
|
item->setCheckState(dockWidget->isVisible() ? Qt::Checked : Qt::Unchecked);
|
||||||
connect(ui->listWidget, &QListWidget::itemClicked, [](QListWidgetItem* item) {
|
connect(ui->listWidget, &QListWidget::itemClicked, [](QListWidgetItem* item) {
|
||||||
bool checked = !(item->checkState() == Qt::Checked);
|
bool checked = !(item->checkState() == Qt::Checked);
|
||||||
item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
|
item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
|
||||||
item->data(DockWidgetRole).value<DockWidget*>()->setVisible(checked);
|
item->data(DockWidgetRole).value<DockWidget*>()->setVisible(checked);
|
||||||
});
|
});
|
||||||
item->setData(DockWidgetRole, QVariant::fromValue(dockWidget));
|
item->setData(DockWidgetRole, QVariant::fromValue(dockWidget));
|
||||||
|
// 同步 dock 可见性变化到勾选状态
|
||||||
|
connect(dockWidget, &DockWidget::visibilityChanged, [item](bool visible) {
|
||||||
|
item->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
|
||||||
|
});
|
||||||
connect(dockWidget, &DockWidget::signalClose, [this, item]() {
|
connect(dockWidget, &DockWidget::signalClose, [this, item]() {
|
||||||
item->setCheckState(Qt::Unchecked);
|
item->setCheckState(Qt::Unchecked);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -46,4 +46,5 @@ void ModelBrowser::InitUI() {
|
|||||||
//ModelTreeWidget* treeWidget = modelBrowserPannal_->GetModelTreeWidget();
|
//ModelTreeWidget* treeWidget = modelBrowserPannal_->GetModelTreeWidget();
|
||||||
connect(treeWidget_, &ModelTreeWidget::WorkSpaceChange, this, &ModelBrowser::WorkSpaceChange);
|
connect(treeWidget_, &ModelTreeWidget::WorkSpaceChange, this, &ModelBrowser::WorkSpaceChange);
|
||||||
connect(treeWidget_, &ModelTreeWidget::EntityChange, this, &ModelBrowser::EntityChange);
|
connect(treeWidget_, &ModelTreeWidget::EntityChange, this, &ModelBrowser::EntityChange);
|
||||||
|
connect(treeWidget_, &ModelTreeWidget::FileEntryChange, this, &ModelBrowser::FileEntryChange);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void WorkSpaceChange(const QVariant& workSpace);
|
void WorkSpaceChange(const QVariant& workSpace);
|
||||||
void EntityChange(const QVariant& workSpace);
|
void EntityChange(const QVariant& workSpace);
|
||||||
|
void FileEntryChange(const QVariant& fileEntry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitUI();
|
void InitUI();
|
||||||
|
|||||||
@ -5,5 +5,6 @@
|
|||||||
enum ItemRol {
|
enum ItemRol {
|
||||||
E_Workspace = Qt::ItemDataRole::UserRole + 1,
|
E_Workspace = Qt::ItemDataRole::UserRole + 1,
|
||||||
E_Entity,
|
E_Entity,
|
||||||
E_UUid
|
E_UUid,
|
||||||
|
E_FileEntry
|
||||||
};
|
};
|
||||||
|
|||||||
@ -42,6 +42,7 @@ void ModelTreeWidget::OnWorkspaceChange(WorkSpace* workSpace) {
|
|||||||
|
|
||||||
connect(workSpace, &WorkSpace::EntityAdded, this, &ModelTreeWidget::OnEntityAdded);
|
connect(workSpace, &WorkSpace::EntityAdded, this, &ModelTreeWidget::OnEntityAdded);
|
||||||
connect(workSpace, &WorkSpace::EntityRemoved, this, &ModelTreeWidget::OnEntityRemoved);
|
connect(workSpace, &WorkSpace::EntityRemoved, this, &ModelTreeWidget::OnEntityRemoved);
|
||||||
|
connect(workSpace, &WorkSpace::FilesChanged, this, &ModelTreeWidget::OnWorkspaceFilesChanged);
|
||||||
|
|
||||||
const QString& name = currentWorkSpace_->GetName();
|
const QString& name = currentWorkSpace_->GetName();
|
||||||
root_ = new QTreeWidgetItem(this);
|
root_ = new QTreeWidgetItem(this);
|
||||||
@ -56,6 +57,12 @@ void ModelTreeWidget::OnWorkspaceChange(WorkSpace* workSpace) {
|
|||||||
for (const auto& entity : entities) {
|
for (const auto& entity : entities) {
|
||||||
AddEntity(root_, entity);
|
AddEntity(root_, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create and populate curve entries branch
|
||||||
|
curvesRoot_ = new QTreeWidgetItem(root_);
|
||||||
|
curvesRoot_->setText(0, tr("Curves"));
|
||||||
|
curvesRoot_->setData(0, E_UUid, QString("CurvesRoot"));
|
||||||
|
PopulateCurveEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelTreeWidget::OnEntityAdded(Entity* entity) {
|
void ModelTreeWidget::OnEntityAdded(Entity* entity) {
|
||||||
@ -163,22 +170,17 @@ void ModelTreeWidget::OnWorkItemChanged(WorkSpaceItem* item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModelTreeWidget::OnWorkItemCliecked(QTreeWidgetItem* item, int column) {
|
void ModelTreeWidget::OnWorkItemCliecked(QTreeWidgetItem* item, int column) {
|
||||||
|
// Prefer entity, then file entry, then workspace
|
||||||
QVariant value = item->data(column, E_Entity);
|
QVariant value = item->data(column, E_Entity);
|
||||||
bool isEntity = true;
|
if (value.isValid()) { emit EntityChange(value); return; }
|
||||||
if (!value.isValid()) {
|
|
||||||
value = item->data(column, E_Workspace);
|
|
||||||
isEntity = false;
|
|
||||||
}
|
|
||||||
if (!value.isValid()) {
|
|
||||||
LOG_WARN("unknown data rol");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEntity) {
|
value = item->data(column, E_FileEntry);
|
||||||
emit EntityChange(value);
|
if (value.isValid()) { emit FileEntryChange(value); return; }
|
||||||
} else {
|
|
||||||
emit WorkSpaceChange(value);
|
value = item->data(column, E_Workspace);
|
||||||
}
|
if (value.isValid()) { emit WorkSpaceChange(value); return; }
|
||||||
|
|
||||||
|
LOG_WARN("unknown data rol");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelTreeWidget::OnItemDoubleClicked(QTreeWidgetItem* item, int column) {
|
void ModelTreeWidget::OnItemDoubleClicked(QTreeWidgetItem* item, int column) {
|
||||||
@ -393,3 +395,32 @@ void ModelTreeWidget::AddEntity(class QTreeWidgetItem* parent, Entity* entity) {
|
|||||||
AddEntity(item, child);
|
AddEntity(item, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelTreeWidget::PopulateCurveEntries() {
|
||||||
|
if (!currentWorkSpace_ || !curvesRoot_) return;
|
||||||
|
|
||||||
|
// Clear existing curve children
|
||||||
|
while (curvesRoot_->childCount() > 0) {
|
||||||
|
QTreeWidgetItem* child = curvesRoot_->child(0);
|
||||||
|
curvesRoot_->removeChild(child);
|
||||||
|
delete child;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto entries = currentWorkSpace_->GetFileEntries(FileEntryType::Curve);
|
||||||
|
for (const auto& entry : entries) {
|
||||||
|
if (!entry) continue;
|
||||||
|
QTreeWidgetItem* item = new QTreeWidgetItem;
|
||||||
|
item->setText(0, entry->GetName());
|
||||||
|
QVariant v;
|
||||||
|
v.setValue(entry.get());
|
||||||
|
item->setData(0, E_FileEntry, v);
|
||||||
|
item->setData(0, E_UUid, QString("Curve:%1").arg(entry->GetFileName()));
|
||||||
|
curvesRoot_->addChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelTreeWidget::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> /*fileEntry*/) {
|
||||||
|
if (type == FileEntryType::Curve) {
|
||||||
|
PopulateCurveEntries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "entities/Entity.h"
|
#include "entities/Entity.h"
|
||||||
#include "workspace/WorkSpace.h"
|
#include "workspace/WorkSpace.h"
|
||||||
#include "workspace/WorkSpaceItem.h"
|
#include "workspace/WorkSpaceItem.h"
|
||||||
|
#include "workspace/FileEntry.h"
|
||||||
|
|
||||||
class ModelTreeWidget : public QTreeWidget {
|
class ModelTreeWidget : public QTreeWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -22,6 +23,7 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void WorkSpaceChange(const QVariant& workSpace);
|
void WorkSpaceChange(const QVariant& workSpace);
|
||||||
void EntityChange(const QVariant& entity);
|
void EntityChange(const QVariant& entity);
|
||||||
|
void FileEntryChange(const QVariant& fileEntry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void contextMenuEvent(QContextMenuEvent* event) override;
|
void contextMenuEvent(QContextMenuEvent* event) override;
|
||||||
@ -30,6 +32,8 @@ protected:
|
|||||||
void OnWorkItemCliecked(QTreeWidgetItem* item, int column);
|
void OnWorkItemCliecked(QTreeWidgetItem* item, int column);
|
||||||
void OnItemDoubleClicked(QTreeWidgetItem* item, int column);
|
void OnItemDoubleClicked(QTreeWidgetItem* item, int column);
|
||||||
|
|
||||||
|
void OnWorkspaceFilesChanged(enum class FileEntryType type, std::shared_ptr<FileEntry> fileEntry);
|
||||||
|
|
||||||
void OnAddMeshEntity(const QString& mesh, const QString& name);
|
void OnAddMeshEntity(const QString& mesh, const QString& name);
|
||||||
class SceneComponent* OnAddComponent(const QString& typeName, class Entity* entity);
|
class SceneComponent* OnAddComponent(const QString& typeName, class Entity* entity);
|
||||||
|
|
||||||
@ -47,8 +51,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
//void initUI();
|
//void initUI();
|
||||||
void AddEntity(class QTreeWidgetItem* parent, Entity* entity);
|
void AddEntity(class QTreeWidgetItem* parent, Entity* entity);
|
||||||
|
void PopulateCurveEntries();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WorkSpace* currentWorkSpace_{ nullptr };
|
WorkSpace* currentWorkSpace_{ nullptr };
|
||||||
QTreeWidgetItem* root_{ nullptr };
|
QTreeWidgetItem* root_{ nullptr };
|
||||||
|
QTreeWidgetItem* curvesRoot_{ nullptr };
|
||||||
};
|
};
|
||||||
@ -70,7 +70,8 @@ void DataPanelManager::SetWorkspace(WorkSpace* workspace)
|
|||||||
LOG_INFO("DataPanelManager::SetWorkspace - Reapplying UI layout after panels created");
|
LOG_INFO("DataPanelManager::SetWorkspace - Reapplying UI layout after panels created");
|
||||||
UiLayoutManager::Restore(mainWindow_, 1);
|
UiLayoutManager::Restore(mainWindow_, 1);
|
||||||
} else {
|
} else {
|
||||||
ClearAllPanels();
|
// 需求变更:如果当前工作空间不存在,继续显示现有面板,不清空
|
||||||
|
LOG_INFO("DataPanelManager::SetWorkspace - No workspace; keeping existing panels displayed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,7 @@ void PropertyBrowser::AttachDock(DockWidget* dockWidget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
|
void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
|
||||||
|
inFileEntryView_ = false;
|
||||||
WorkSpace* workspace = value.value<WorkSpace*>();
|
WorkSpace* workspace = value.value<WorkSpace*>();
|
||||||
if (nullptr == workspace) {
|
if (nullptr == workspace) {
|
||||||
LOG_WARN("workspace is nullptr");
|
LOG_WARN("workspace is nullptr");
|
||||||
@ -70,25 +71,11 @@ void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
|
|||||||
QObject::connect(currentWorkspace_, &WorkSpace::FilesChanged,
|
QObject::connect(currentWorkspace_, &WorkSpace::FilesChanged,
|
||||||
this, &PropertyBrowser::OnWorkspaceFilesChanged);
|
this, &PropertyBrowser::OnWorkspaceFilesChanged);
|
||||||
|
|
||||||
// Mount all curve entries, each as its own top-level group
|
// No longer mount file entries under workspace; file entries are handled separately
|
||||||
auto curves = currentWorkspace_->GetFileEntries(FileEntryType::Curve);
|
|
||||||
for (const auto& entry : curves) {
|
|
||||||
if (!entry) continue;
|
|
||||||
auto curve = entry->AsCurve();
|
|
||||||
if (!curve) continue;
|
|
||||||
|
|
||||||
// Use filename as stable unique id, and include display name in group title
|
|
||||||
const QString id = QString("CurveEntry:%1").arg(entry->GetFileName());
|
|
||||||
const QString title = QString("CurveEntry - %1").arg(entry->GetName());
|
|
||||||
|
|
||||||
QtProperty* cprop = curveEntryManager_->addProperty(title);
|
|
||||||
QCurveEntryAttribute attr(curve);
|
|
||||||
curveEntryManager_->setValue(cprop, attr);
|
|
||||||
addProperty(cprop, id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyBrowser::OnEntityChange(const QVariant& value) {
|
void PropertyBrowser::OnEntityChange(const QVariant& value) {
|
||||||
|
inFileEntryView_ = false;
|
||||||
Entity* entity = value.value<Entity*>();
|
Entity* entity = value.value<Entity*>();
|
||||||
if (nullptr == entity) {
|
if (nullptr == entity) {
|
||||||
LOG_WARN("engity is nullptr");
|
LOG_WARN("engity is nullptr");
|
||||||
@ -136,6 +123,43 @@ void PropertyBrowser::OnEntityChange(const QVariant& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropertyBrowser::OnFileEntryChange(const QVariant& value) {
|
||||||
|
FileEntry* entry = value.value<FileEntry*>();
|
||||||
|
if (!entry) {
|
||||||
|
LOG_WARN("file entry is nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enter single FileEntry view mode and clear existing panels
|
||||||
|
inFileEntryView_ = true;
|
||||||
|
browser_->clear();
|
||||||
|
propertyToId_.clear();
|
||||||
|
idToProperty_.clear();
|
||||||
|
idToExpanded_.clear();
|
||||||
|
|
||||||
|
// Compute our id and ensure the property exists (create if missing)
|
||||||
|
const QString id = QString("CurveEntry:%1").arg(entry->GetFileName());
|
||||||
|
auto curve = entry->AsCurve();
|
||||||
|
if (!curve) {
|
||||||
|
LOG_WARN("file entry not a curve: %s", entry->GetFileName().toStdString().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QString title = QString("CurveEntry - %1").arg(entry->GetName());
|
||||||
|
QtProperty* prop = curveEntryManager_->addProperty(title);
|
||||||
|
QCurveEntryAttribute attr(curve);
|
||||||
|
curveEntryManager_->setValue(prop, attr);
|
||||||
|
addProperty(prop, id);
|
||||||
|
|
||||||
|
// Focus the corresponding group: expand and select it
|
||||||
|
if (prop) {
|
||||||
|
QtBrowserItem* item = browser_->topLevelItem(prop);
|
||||||
|
if (item) {
|
||||||
|
browser_->setExpanded(item, true);
|
||||||
|
browser_->setCurrentItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PropertyBrowser::InitUI() {
|
void PropertyBrowser::InitUI() {
|
||||||
QBoxLayout* layout = new QVBoxLayout(this);
|
QBoxLayout* layout = new QVBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
@ -208,6 +232,8 @@ void PropertyBrowser::InitPropertyManager() {
|
|||||||
|
|
||||||
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> fileEntry) {
|
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> fileEntry) {
|
||||||
if (!currentWorkspace_) return;
|
if (!currentWorkspace_) return;
|
||||||
|
// In single FileEntry view, skip workspace-driven group refresh to keep panel clean
|
||||||
|
if (inFileEntryView_) return;
|
||||||
// Refresh workspace group
|
// Refresh workspace group
|
||||||
{
|
{
|
||||||
auto it = idToProperty_.find(tr("WorkSpace"));
|
auto it = idToProperty_.find(tr("WorkSpace"));
|
||||||
@ -217,52 +243,6 @@ void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_pt
|
|||||||
workSpaceManager_->setValue(property, worksapceAttribute);
|
workSpaceManager_->setValue(property, worksapceAttribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh curve entry groups when curve files mutate
|
|
||||||
if (type == FileEntryType::Curve) {
|
|
||||||
const auto curves = currentWorkspace_->GetFileEntries(FileEntryType::Curve);
|
|
||||||
|
|
||||||
// Desired ids for current curves
|
|
||||||
QSet<QString> desiredIds;
|
|
||||||
for (const auto& entry : curves) {
|
|
||||||
if (!entry) continue;
|
|
||||||
desiredIds.insert(QString("CurveEntry:%1").arg(entry->GetFileName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add or update properties for all current curves
|
|
||||||
for (const auto& entry : curves) {
|
|
||||||
if (!entry) continue;
|
|
||||||
auto curve = entry->AsCurve();
|
|
||||||
if (!curve) continue;
|
|
||||||
|
|
||||||
const QString id = QString("CurveEntry:%1").arg(entry->GetFileName());
|
|
||||||
const QString title = QString("CurveEntry - %1").arg(entry->GetName());
|
|
||||||
QCurveEntryAttribute attr(curve);
|
|
||||||
|
|
||||||
auto it = idToProperty_.find(id);
|
|
||||||
if (it != idToProperty_.end()) {
|
|
||||||
// Update existing group
|
|
||||||
curveEntryManager_->setValue(it.value(), attr);
|
|
||||||
} else {
|
|
||||||
// Create new group for this curve
|
|
||||||
QtProperty* prop = curveEntryManager_->addProperty(title);
|
|
||||||
curveEntryManager_->setValue(prop, attr);
|
|
||||||
addProperty(prop, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove groups for curves that no longer exist
|
|
||||||
QList<QString> existingIds = idToProperty_.keys();
|
|
||||||
for (const auto& id : existingIds) {
|
|
||||||
if (id.startsWith("CurveEntry:") && !desiredIds.contains(id)) {
|
|
||||||
QtProperty* prop = idToProperty_[id];
|
|
||||||
browser_->removeProperty(prop);
|
|
||||||
propertyToId_.remove(prop);
|
|
||||||
idToExpanded_.remove(id);
|
|
||||||
idToProperty_.remove(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyBrowser::InitComponentPropertyManager() {
|
void PropertyBrowser::InitComponentPropertyManager() {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ public:
|
|||||||
|
|
||||||
void OnWorkSpaceChange(const QVariant& value);
|
void OnWorkSpaceChange(const QVariant& value);
|
||||||
void OnEntityChange(const QVariant& value);
|
void OnEntityChange(const QVariant& value);
|
||||||
|
void OnFileEntryChange(const QVariant& value);
|
||||||
void OnWorkspaceFilesChanged(enum class FileEntryType type, std::shared_ptr<FileEntry> fileEntry);
|
void OnWorkspaceFilesChanged(enum class FileEntryType type, std::shared_ptr<FileEntry> fileEntry);
|
||||||
|
|
||||||
void Test();
|
void Test();
|
||||||
@ -55,5 +56,8 @@ private:
|
|||||||
|
|
||||||
// Track current workspace for real-time refresh
|
// Track current workspace for real-time refresh
|
||||||
class WorkSpace* currentWorkspace_{ nullptr };
|
class WorkSpace* currentWorkspace_{ nullptr };
|
||||||
|
|
||||||
|
// When true, we are showing a single FileEntry view (not workspace-wide groups)
|
||||||
|
bool inFileEntryView_{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "entities/EntitiesManager.h"
|
#include "entities/EntitiesManager.h"
|
||||||
#include "utils/Transform.h"
|
#include "utils/Transform.h"
|
||||||
#include "utils/OsgUtils.h"
|
#include "utils/OsgUtils.h"
|
||||||
|
#include "workspace/WorkSpaceManager.h"
|
||||||
|
|
||||||
|
|
||||||
QWorkspaceAttribute::QWorkspaceAttribute(class WorkSpace* workspace)
|
QWorkspaceAttribute::QWorkspaceAttribute(class WorkSpace* workspace)
|
||||||
@ -138,9 +139,8 @@ void QWorkspaceAttribute::SetFileEntryPath(FileEntryType type, int index, const
|
|||||||
|
|
||||||
// Update the path of the specific entry
|
// Update the path of the specific entry
|
||||||
entries[index]->SetPath(path);
|
entries[index]->SetPath(path);
|
||||||
|
// Trigger files changed signal properly
|
||||||
// Trigger files changed signal
|
workspace_->NotifyFileEntryUpdated(type);
|
||||||
workspace_->SetFileEntryCount(type, static_cast<int>(entries.size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QWorkspaceAttribute::GetFileEntryAbsPath(FileEntryType type, int index) const {
|
QString QWorkspaceAttribute::GetFileEntryAbsPath(FileEntryType type, int index) const {
|
||||||
@ -659,6 +659,7 @@ QCurveEntryAttribute& QCurveEntryAttribute::operator=(const QCurveEntryAttribute
|
|||||||
void QCurveEntryAttribute::SetName(const QString& name) {
|
void QCurveEntryAttribute::SetName(const QString& name) {
|
||||||
if (!entry_) return;
|
if (!entry_) return;
|
||||||
entry_->SetName(name);
|
entry_->SetName(name);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QCurveEntryAttribute::GetName() const {
|
QString QCurveEntryAttribute::GetName() const {
|
||||||
@ -669,6 +670,7 @@ QString QCurveEntryAttribute::GetName() const {
|
|||||||
void QCurveEntryAttribute::SetChartType(ChartType type) {
|
void QCurveEntryAttribute::SetChartType(ChartType type) {
|
||||||
if (!entry_) return;
|
if (!entry_) return;
|
||||||
entry_->SetChartType(type);
|
entry_->SetChartType(type);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
ChartType QCurveEntryAttribute::GetChartType() const {
|
ChartType QCurveEntryAttribute::GetChartType() const {
|
||||||
@ -703,6 +705,7 @@ void QCurveEntryAttribute::SetCurveCount(int count) {
|
|||||||
entry_->RemoveCurveProperty(i);
|
entry_->RemoveCurveProperty(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QCurveEntryAttribute::GetCurveName(int index) const {
|
QString QCurveEntryAttribute::GetCurveName(int index) const {
|
||||||
@ -721,6 +724,7 @@ void QCurveEntryAttribute::SetCurveName(int index, const QString& name) {
|
|||||||
// overwrite by remove/add pattern
|
// overwrite by remove/add pattern
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor QCurveEntryAttribute::GetCurveColor(int index) const {
|
QColor QCurveEntryAttribute::GetCurveColor(int index) const {
|
||||||
@ -738,6 +742,7 @@ void QCurveEntryAttribute::SetCurveColor(int index, const QColor& color) {
|
|||||||
cp.color = color;
|
cp.color = color;
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
int QCurveEntryAttribute::GetWaveStart(int index) const {
|
int QCurveEntryAttribute::GetWaveStart(int index) const {
|
||||||
@ -755,6 +760,7 @@ void QCurveEntryAttribute::SetWaveStart(int index, int start) {
|
|||||||
cp.data.wave.start = start;
|
cp.data.wave.start = start;
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
int QCurveEntryAttribute::GetWaveStop(int index) const {
|
int QCurveEntryAttribute::GetWaveStop(int index) const {
|
||||||
@ -772,6 +778,7 @@ void QCurveEntryAttribute::SetWaveStop(int index, int stop) {
|
|||||||
cp.data.wave.stop = stop;
|
cp.data.wave.stop = stop;
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
double QCurveEntryAttribute::GetReportX(int index) const {
|
double QCurveEntryAttribute::GetReportX(int index) const {
|
||||||
@ -789,6 +796,7 @@ void QCurveEntryAttribute::SetReportX(int index, double x) {
|
|||||||
cp.data.report.x = x;
|
cp.data.report.x = x;
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|
||||||
double QCurveEntryAttribute::GetReportY(int index) const {
|
double QCurveEntryAttribute::GetReportY(int index) const {
|
||||||
@ -806,4 +814,5 @@ void QCurveEntryAttribute::SetReportY(int index, double y) {
|
|||||||
cp.data.report.y = y;
|
cp.data.report.y = y;
|
||||||
entry_->RemoveCurveProperty(index);
|
entry_->RemoveCurveProperty(index);
|
||||||
entry_->AddCurveProperty(cp);
|
entry_->AddCurveProperty(cp);
|
||||||
|
if (auto ws = WorkSpaceManager::Get().GetCurrent()) { ws->NotifyFileEntryUpdated(FileEntryType::Curve); }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
@ -396,5 +396,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ChartProperties chartProperties_;
|
ChartProperties chartProperties_;
|
||||||
ImageProperties imageProperties_;
|
ImageProperties imageProperties_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enable QVariant support for FileEntry pointers
|
||||||
|
#include <QMetaType>
|
||||||
|
Q_DECLARE_METATYPE(FileEntry*)
|
||||||
@ -379,3 +379,9 @@ void WorkSpace::ExecuteCommands(CommandWhen when) {
|
|||||||
}
|
}
|
||||||
cmdMgr_->Execute(this, when);
|
cmdMgr_->Execute(this, when);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一属性更新通知:不改变数量,仅提升序号并广播 FilesChanged
|
||||||
|
void WorkSpace::NotifyFileEntryUpdated(FileEntryType type, std::shared_ptr<FileEntry> fileEntry) {
|
||||||
|
++filesSeq_;
|
||||||
|
emit FilesChanged(type, fileEntry);
|
||||||
|
}
|
||||||
|
|||||||
@ -127,6 +127,9 @@ public:
|
|||||||
|
|
||||||
void OnLoaded();
|
void OnLoaded();
|
||||||
|
|
||||||
|
// 通知:某类型的文件条目属性已更新(不改变数量,仅触发刷新)
|
||||||
|
void NotifyFileEntryUpdated(FileEntryType type, std::shared_ptr<FileEntry> fileEntry = nullptr);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void EntityAdded(class Entity* entity);
|
void EntityAdded(class Entity* entity);
|
||||||
void EntityRemoved(class Entity* entity);
|
void EntityRemoved(class Entity* entity);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user