280 lines
9.7 KiB
C++
280 lines
9.7 KiB
C++
#include "MainPanel.h"
|
|
#include "ViewportPane.h"
|
|
#include "ContextPanel.h"
|
|
#include "PropertiesPanel.h"
|
|
#include "Core/ObjectFactory.h"
|
|
#include "Core/ObjectsContext.h"
|
|
#include "Vtk/vtkObjectsContext.h"
|
|
#include "Vtk/vtkQViewport.h"
|
|
#include "Vtk/vtkViewportProperties.h"
|
|
#include <Vtk/uLibVtkInterface.h>
|
|
#include <QVBoxLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QSplitter>
|
|
#include <QLabel>
|
|
#include <QPushButton>
|
|
#include <QMenu>
|
|
#include <QAction>
|
|
#include <QShortcut>
|
|
#include <QApplication>
|
|
#include <QFileDialog>
|
|
#include <QFileInfo>
|
|
#include "StyleManager.h"
|
|
#include "Math/VoxImage.h"
|
|
#include "PreferencesDialog.h"
|
|
#include "Settings.h"
|
|
|
|
MainPanel::MainPanel(QWidget* parent) : QWidget(parent), m_context(nullptr), m_mainVtkContext(nullptr), m_viewportProps(nullptr) {
|
|
this->setObjectName("MainPanel");
|
|
this->setAttribute(Qt::WA_StyledBackground);
|
|
auto* mainLayout = new QVBoxLayout(this);
|
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
mainLayout->setSpacing(0);
|
|
|
|
// 1. Top Menu Panel
|
|
auto* menuPanel = new QWidget(this);
|
|
menuPanel->setObjectName("MenuPanel");
|
|
menuPanel->setFixedHeight(36);
|
|
|
|
auto* menuLayout = new QHBoxLayout(menuPanel);
|
|
menuLayout->setContentsMargins(10, 0, 10, 0);
|
|
menuLayout->setSpacing(15);
|
|
|
|
auto* logo = new QLabel("G-COMPOSE", menuPanel);
|
|
logo->setObjectName("LogoLabel");
|
|
|
|
// File Menu Button
|
|
auto* btnFile = new QPushButton("File", menuPanel);
|
|
btnFile->setObjectName("MenuButton");
|
|
auto* fileMenu = new QMenu(btnFile);
|
|
fileMenu->addAction("Open", this, &MainPanel::onOpen);
|
|
fileMenu->addAction("Save", this, &MainPanel::onSave);
|
|
fileMenu->addAction("Save As", this, &MainPanel::onSaveAs);
|
|
fileMenu->addSeparator();
|
|
fileMenu->addAction("Preferences", this, &MainPanel::onPreferences);
|
|
fileMenu->addSeparator();
|
|
fileMenu->addAction("Exit", this, &MainPanel::onExit);
|
|
btnFile->setMenu(fileMenu);
|
|
|
|
// New Menu Button
|
|
auto* btnNew = new QPushButton("Add", menuPanel);
|
|
btnNew->setObjectName("MenuButton");
|
|
auto* newMenu = new QMenu(btnNew);
|
|
|
|
auto classes = uLib::ObjectFactory::Instance().GetRegisteredClasses();
|
|
for (const auto& className : classes) {
|
|
auto* action = newMenu->addAction(QString::fromStdString(className));
|
|
connect(action, &QAction::triggered, [this, className]() {
|
|
this->onCreateObject(className);
|
|
});
|
|
}
|
|
btnNew->setMenu(newMenu);
|
|
|
|
menuLayout->addWidget(logo);
|
|
menuLayout->addWidget(btnFile);
|
|
menuLayout->addWidget(btnNew);
|
|
menuLayout->addStretch();
|
|
|
|
mainLayout->addWidget(menuPanel);
|
|
|
|
// 2. Central Splitter Area
|
|
m_rootSplitter = new QSplitter(Qt::Horizontal, this);
|
|
m_contextPanel = new ContextPanel(m_rootSplitter);
|
|
m_rootSplitter->addWidget(m_contextPanel);
|
|
m_rootSplitter->setStretchFactor(0, 0);
|
|
|
|
m_firstPane = new ViewportPane(m_rootSplitter);
|
|
m_rootSplitter->addWidget(m_firstPane);
|
|
m_rootSplitter->setStretchFactor(1, 1);
|
|
|
|
connect(m_contextPanel, &ContextPanel::objectSelected, [this](uLib::Object* obj) {
|
|
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
|
uLib::Vtk::Prop3D* prop3d = nullptr;
|
|
if (m_mainVtkContext) {
|
|
prop3d = m_mainVtkContext->GetProp3D(obj);
|
|
}
|
|
viewport->SelectProp3D(prop3d);
|
|
// Update the display properties in the viewport pane itself - use the prop3d proxy if possible
|
|
m_firstPane->setObject(prop3d ? (uLib::Object*)prop3d : obj);
|
|
} else {
|
|
m_firstPane->setObject(obj);
|
|
}
|
|
});
|
|
|
|
connect(m_contextPanel, &ContextPanel::propertyUpdated, [this](){
|
|
auto viewports = this->findChildren<uLib::Vtk::QViewport*>();
|
|
for (auto* vp : viewports) {
|
|
vp->Render();
|
|
}
|
|
});
|
|
|
|
// Set initial sizes: Context(250), Viewport(600), Properties(250)
|
|
QList<int> sizes;
|
|
sizes << 250 << 600 << 250;
|
|
m_rootSplitter->setSizes(sizes);
|
|
|
|
mainLayout->addWidget(m_rootSplitter, 1);
|
|
|
|
// Shortcuts
|
|
auto* groupShortcut = new QShortcut(QKeySequence("Ctrl+G"), this);
|
|
connect(groupShortcut, &QShortcut::activated, [this]() {
|
|
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
|
viewport->GroupSelection(m_context);
|
|
}
|
|
});
|
|
}
|
|
|
|
void MainPanel::setContext(uLib::ObjectsContext* context) {
|
|
m_context = context;
|
|
m_contextPanel->setContext(context);
|
|
|
|
// Propagate context to all panels for reference property dropdowns
|
|
m_contextPanel->setPropertyContext(context);
|
|
m_firstPane->setContext(context);
|
|
if (m_mainVtkContext) {
|
|
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
|
viewport->RemoveProp3D(*m_mainVtkContext);
|
|
}
|
|
delete m_mainVtkContext;
|
|
m_mainVtkContext = nullptr;
|
|
}
|
|
|
|
if (context) {
|
|
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
|
m_mainVtkContext = new uLib::Vtk::ObjectsContext(context);
|
|
// viewport->AddProp3D(*m_mainVtkContext); // redundant
|
|
|
|
auto syncSelection = [this](uLib::Vtk::Prop3D* p) {
|
|
if (!p) {
|
|
m_contextPanel->clearSelection();
|
|
m_firstPane->setObject(nullptr);
|
|
} else {
|
|
m_contextPanel->selectObject(p->GetContent());
|
|
m_firstPane->setObject(p);
|
|
}
|
|
};
|
|
connect(viewport, &uLib::Vtk::QViewport::prop3dSelected, syncSelection);
|
|
|
|
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::Prop3DAdded, [this](uLib::Vtk::Prop3D* p) {
|
|
if (p) {
|
|
auto panes = this->findChildren<ViewportPane*>();
|
|
for (auto* pane : panes) {
|
|
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
|
vp->AddProp3D(*p);
|
|
vp->ZoomAuto();
|
|
vp->Render();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::Prop3DRemoved, [this](uLib::Vtk::Prop3D* p) {
|
|
if (p) {
|
|
auto panes = this->findChildren<ViewportPane*>();
|
|
for (auto* pane : panes) {
|
|
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
|
vp->RemoveProp3D(*p);
|
|
vp->Render();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Add any prop3ds that were created during m_mainVtkContext's construction to all panes
|
|
auto panes = this->findChildren<ViewportPane*>();
|
|
for (auto* obj : context->GetObjects()) {
|
|
if (auto* p = m_mainVtkContext->GetProp3D(obj)) {
|
|
for (auto* pane : panes) {
|
|
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
|
vp->AddProp3D(*p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uLib::Object::connect(context, &uLib::Object::Updated, [viewport]() {
|
|
viewport->Render();
|
|
});
|
|
viewport->ZoomAuto();
|
|
viewport->Render();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainPanel::onCreateObject(const std::string& className) {
|
|
if (!m_context) return;
|
|
auto* obj = uLib::ObjectFactory::Instance().Create(className);
|
|
if (obj) {
|
|
m_context->AddObject(obj);
|
|
}
|
|
}
|
|
|
|
void MainPanel::onOpen() {
|
|
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "",
|
|
"VTK/VTI Images (*.vtk *.vti);;All Files (*.*)");
|
|
|
|
if (fileName.isEmpty()) return;
|
|
|
|
QFileInfo info(fileName);
|
|
QString ext = info.suffix().toLower();
|
|
|
|
if (ext == "vti" || ext == "vtk") {
|
|
auto* obj = uLib::ObjectFactory::Instance().Create("VoxImage");
|
|
auto* vox = dynamic_cast<uLib::Abstract::VoxImage*>(obj);
|
|
if (vox) {
|
|
bool success = false;
|
|
if (ext == "vti") {
|
|
success = vox->ImportFromVti(fileName.toStdString().c_str());
|
|
} else {
|
|
success = vox->ImportFromVtk(fileName.toStdString().c_str());
|
|
}
|
|
|
|
if (success) {
|
|
obj->SetInstanceName(info.fileName().toStdString());
|
|
m_context->AddObject(obj);
|
|
} else {
|
|
delete obj;
|
|
}
|
|
} else {
|
|
delete obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainPanel::onSave() {
|
|
// Placeholder for save logic
|
|
}
|
|
|
|
void MainPanel::onSaveAs() {
|
|
// Placeholder for save as logic
|
|
}
|
|
|
|
void MainPanel::onExit() {
|
|
qApp->quit();
|
|
}
|
|
|
|
void MainPanel::onPreferences() {
|
|
uLib::Qt::PreferencesDialog dlg(this);
|
|
if (dlg.exec() == QDialog::Accepted) {
|
|
// Apply theme and GUI font
|
|
auto theme = uLib::Qt::Settings::Instance().GetTheme();
|
|
auto guiFont = uLib::Qt::Settings::Instance().GetGuiFont();
|
|
StyleManager::applyStyle(qApp, theme == uLib::Qt::Settings::Dark ? "dark" : "bright", guiFont);
|
|
|
|
// Apply rendering and font preferences to all viewports
|
|
bool throttled = uLib::Qt::Settings::Instance().GetThrottledRendering();
|
|
auto font = uLib::Qt::Settings::Instance().GetFont();
|
|
auto fontColor = uLib::Qt::Settings::Instance().GetFontColor();
|
|
|
|
auto viewports = this->findChildren<uLib::Vtk::QViewport*>();
|
|
for (auto* vp : viewports) {
|
|
vp->SetThrottledRendering(throttled);
|
|
vp->SetFont(font);
|
|
vp->SetFontColor(fontColor);
|
|
vp->Render();
|
|
}
|
|
}
|
|
}
|
|
|
|
MainPanel::~MainPanel() {}
|