Files
uLib/app/gcompose/src/ViewportPane.cpp
AndreaRigoni f13342ff30 vtkProperties
2026-03-23 17:46:42 +00:00

181 lines
6.3 KiB
C++

#include "ViewportPane.h"
#include <Vtk/vtkQViewport.h>
#include <Root/QCanvas.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QMenu>
#include <QAction>
#include <QSplitter>
#include <vtkCamera.h>
#include "PropertyWidgets.h"
#include <QSignalBlocker>
ViewportPane::ViewportPane(QWidget* parent) : QWidget(parent), m_viewport(nullptr) {
m_layout = new QVBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
// Title bar setup
m_titleBar = new QWidget(this);
m_titleBar->setObjectName("PaneTitleBar");
m_titleBar->setFixedHeight(22);
auto* titleLayout = new QHBoxLayout(m_titleBar);
titleLayout->setContentsMargins(5, 0, 0, 0);
m_titleLabel = new QLabel("Viewport", m_titleBar);
m_titleLabel->setObjectName("TitleLabel");
m_toggleBtn = new QPushButton("Display", m_titleBar);
m_toggleBtn->setCheckable(true);
m_toggleBtn->setFixedSize(60, 18);
m_toggleBtn->setObjectName("DisplayToggleBtn");
auto* closeBtn = new QToolButton(m_titleBar);
closeBtn->setObjectName("PaneCloseButton");
closeBtn->setText("X");
closeBtn->setFixedSize(18, 18);
titleLayout->addWidget(m_titleLabel);
titleLayout->addStretch();
titleLayout->addWidget(m_toggleBtn);
titleLayout->addSpacing(5);
titleLayout->addWidget(closeBtn);
m_layout->addWidget(m_titleBar);
// Main horizontal container for viewport and display panel
QWidget* mainArea = new QWidget(this);
QHBoxLayout* hLayout = new QHBoxLayout(mainArea);
hLayout->setContentsMargins(0, 0, 0, 0);
hLayout->setSpacing(0);
m_layout->addWidget(mainArea);
// Viewport will be added here via setViewport
m_viewport = new uLib::Vtk::QViewport(mainArea);
hLayout->addWidget(m_viewport);
// Display Panel (Overlay/Slide-out)
m_displayPanel = new QFrame(mainArea);
m_displayPanel->setObjectName("DisplayPropertiesPanel");
m_displayPanel->setFixedWidth(250);
m_displayPanel->hide();
QVBoxLayout* panelLayout = new QVBoxLayout(m_displayPanel);
panelLayout->setContentsMargins(5, 5, 5, 5);
QLabel* panelHeader = new QLabel("Display Properties", m_displayPanel);
panelHeader->setStyleSheet("font-weight: bold; padding: 5px;");
panelLayout->addWidget(panelHeader);
m_displayEditor = new uLib::Qt::PropertyEditor(m_displayPanel);
panelLayout->addWidget(m_displayEditor);
hLayout->addWidget(m_displayPanel);
connect(m_toggleBtn, &QPushButton::toggled, this, &ViewportPane::toggleDisplayPanel);
connect(m_titleBar, &QWidget::customContextMenuRequested, this, &ViewportPane::showContextMenu);
connect(closeBtn, &QToolButton::clicked, this, &ViewportPane::onCloseRequested);
m_titleBar->setContextMenuPolicy(Qt::CustomContextMenu);
}
ViewportPane::~ViewportPane() {}
void ViewportPane::toggleDisplayPanel() {
m_displayPanel->setVisible(m_toggleBtn->isChecked());
}
void ViewportPane::setObject(uLib::Object* obj) {
m_displayEditor->setObject(obj, true);
// Check if the object is a Puppet (meaning it has display properties)
bool isPuppet = (dynamic_cast<::uLib::Vtk::Puppet*>(obj) != nullptr);
// Only show the "Display" toggle button if it's a puppet
m_toggleBtn->setVisible(isPuppet);
// If it's a puppet, we might want to keep the panel state if it was already open,
// or if it's NOT a puppet, definitely hide the toggle and panel.
if (!isPuppet) {
m_toggleBtn->setChecked(false);
m_displayPanel->hide();
}
}
void ViewportPane::setViewport(QWidget* viewport, const QString& title) {
if (m_viewport) {
m_viewport->parentWidget()->layout()->removeWidget(m_viewport);
delete m_viewport;
}
m_viewport = viewport;
m_titleLabel->setText(title);
m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
auto* mainAreaLayout = static_cast<QHBoxLayout*>(m_displayPanel->parentWidget()->layout());
mainAreaLayout->insertWidget(0, m_viewport);
}
void ViewportPane::addVtkViewport() {
auto* viewport = new uLib::Vtk::QViewport(this);
setViewport(viewport, "VTK Viewport");
}
void ViewportPane::addRootCanvas() {
auto* canvas = new uLib::Root::QCanvas(this);
setViewport(canvas, "ROOT Canvas");
}
void ViewportPane::onCloseRequested() {
QSplitter* parentSplitter = qobject_cast<QSplitter*>(parentWidget());
if (parentSplitter && parentSplitter->count() > 1) {
deleteLater();
} else {
addVtkViewport();
}
}
void ViewportPane::showContextMenu(const QPoint& pos) {
QMenu menu(this);
QAction* hSplit = menu.addAction("H split");
QAction* vSplit = menu.addAction("V split");
menu.addSeparator();
bool isVtk = (qobject_cast<uLib::Vtk::QViewport*>(m_viewport) != nullptr);
QAction* changeType = menu.addAction(isVtk ? "Change to ROOT Canvas" : "Change to VTK Viewport");
QAction* selected = menu.exec(m_titleBar->mapToGlobal(pos));
if (selected == hSplit) AttemptSplit(Qt::Horizontal);
else if (selected == vSplit) AttemptSplit(Qt::Vertical);
else if (selected == changeType) isVtk ? addRootCanvas() : addVtkViewport();
}
void ViewportPane::AttemptSplit(Qt::Orientation orientation) {
QWidget* p = parentWidget();
if (!p) return;
QSplitter* parentSplitter = qobject_cast<QSplitter*>(p);
if (!parentSplitter) return;
ViewportPane* newPane = new ViewportPane();
if (parentSplitter->orientation() == orientation) {
int index = parentSplitter->indexOf(this);
QList<int> sizes = parentSplitter->sizes();
int currentSize = sizes.value(index, 0);
int half = currentSize / 2;
sizes[index] = half;
sizes.insert(index + 1, currentSize - half);
parentSplitter->insertWidget(index + 1, newPane);
parentSplitter->setSizes(sizes);
} else {
int index = parentSplitter->indexOf(this);
QList<int> parentSizes = parentSplitter->sizes();
QSplitter* newSplitter = new QSplitter(orientation);
newSplitter->addWidget(this);
newSplitter->addWidget(newPane);
QList<int> subSizes;
subSizes << 500 << 500;
newSplitter->setSizes(subSizes);
parentSplitter->insertWidget(index, newSplitter);
parentSplitter->setSizes(parentSizes);
}
}