From cd95f16221571786e155e57bbd026b14a202b5fb Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Sat, 21 Mar 2026 16:30:38 +0000 Subject: [PATCH] fix name in gcompose --- app/gcompose/CMakeLists.txt | 4 +- app/gcompose/src/MainPanel.cpp | 4 +- app/gcompose/src/MainPanel.h | 6 +- app/gcompose/src/MainWindow.h | 1 + app/gcompose/src/ViewportPane.cpp | 169 ++++++++++++++++++++++++++++++ app/gcompose/src/ViewportPane.h | 34 ++++++ app/gcompose/src/main.cpp | 4 +- 7 files changed, 213 insertions(+), 9 deletions(-) create mode 100644 app/gcompose/src/ViewportPane.cpp create mode 100644 app/gcompose/src/ViewportPane.h diff --git a/app/gcompose/CMakeLists.txt b/app/gcompose/CMakeLists.txt index af064d9..6ed246d 100644 --- a/app/gcompose/CMakeLists.txt +++ b/app/gcompose/CMakeLists.txt @@ -3,8 +3,8 @@ add_executable(gcompose src/main.cpp src/MainWindow.h src/MainWindow.cpp - src/QViewportPane.h - src/QViewportPane.cpp + src/ViewportPane.h + src/ViewportPane.cpp src/MainPanel.h src/MainPanel.cpp ) diff --git a/app/gcompose/src/MainPanel.cpp b/app/gcompose/src/MainPanel.cpp index dcc2fb9..b5399e7 100644 --- a/app/gcompose/src/MainPanel.cpp +++ b/app/gcompose/src/MainPanel.cpp @@ -1,5 +1,5 @@ #include "MainPanel.h" -#include "QViewportPane.h" +#include "ViewportPane.h" #include #include #include @@ -40,7 +40,7 @@ MainPanel::MainPanel(QWidget* parent) : QWidget(parent) { // 2. Central Splitter Area m_rootSplitter = new QSplitter(Qt::Horizontal, this); - m_firstPane = new QViewportPane(m_rootSplitter); + m_firstPane = new ViewportPane(m_rootSplitter); m_rootSplitter->addWidget(m_firstPane); mainLayout->addWidget(m_rootSplitter, 1); diff --git a/app/gcompose/src/MainPanel.h b/app/gcompose/src/MainPanel.h index ec46b56..4c1af4c 100644 --- a/app/gcompose/src/MainPanel.h +++ b/app/gcompose/src/MainPanel.h @@ -4,7 +4,7 @@ #include class QSplitter; -class QViewportPane; +class ViewportPane; class MainPanel : public QWidget { Q_OBJECT @@ -12,11 +12,11 @@ public: explicit MainPanel(QWidget* parent = nullptr); virtual ~MainPanel(); - QViewportPane* getFirstPane() const { return m_firstPane; } + ViewportPane* getFirstPane() const { return m_firstPane; } private: QSplitter* m_rootSplitter; - QViewportPane* m_firstPane; + ViewportPane* m_firstPane; }; #endif // MAINPANEL_H diff --git a/app/gcompose/src/MainWindow.h b/app/gcompose/src/MainWindow.h index 0668f69..d5b54ee 100644 --- a/app/gcompose/src/MainWindow.h +++ b/app/gcompose/src/MainWindow.h @@ -5,6 +5,7 @@ #include class MainPanel; +class ViewportPane; namespace uLib { namespace Vtk { diff --git a/app/gcompose/src/ViewportPane.cpp b/app/gcompose/src/ViewportPane.cpp new file mode 100644 index 0000000..0c2e594 --- /dev/null +++ b/app/gcompose/src/ViewportPane.cpp @@ -0,0 +1,169 @@ +#include "ViewportPane.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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->setFixedHeight(22); + m_titleBar->setStyleSheet("background-color: #333; color: white;"); + + auto* titleLayout = new QHBoxLayout(m_titleBar); + titleLayout->setContentsMargins(5, 0, 5, 0); + + m_titleLabel = new QLabel("Viewport", m_titleBar); + + auto* closeBtn = new QToolButton(m_titleBar); + closeBtn->setText("X"); + closeBtn->setFixedSize(18, 18); + closeBtn->setStyleSheet("QToolButton { border: none; font-weight: bold; background: transparent; color: #ccc; } " + "QToolButton:hover { color: white; background: red; }"); + + titleLayout->addWidget(m_titleLabel); + titleLayout->addStretch(); + titleLayout->addWidget(closeBtn); + + m_layout->addWidget(m_titleBar); + + m_titleBar->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_titleBar, &QWidget::customContextMenuRequested, this, &ViewportPane::showContextMenu); + connect(closeBtn, &QToolButton::clicked, this, &ViewportPane::onCloseRequested); + + addVtkViewport(); // Initialize with a default VTK viewport +} + +ViewportPane::~ViewportPane() {} + +void ViewportPane::setViewport(QWidget* viewport, const QString& title) { + if (m_viewport) { + m_layout->removeWidget(m_viewport); + delete m_viewport; + } + m_viewport = viewport; + m_titleLabel->setText(title); + + m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout->addWidget(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(parentWidget()); + if (parentSplitter && parentSplitter->count() > 1) { + deleteLater(); + } else { + // Can't close the last viewport in the splitter safely. Re-initialize to default VTK canvas. + 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(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) { + if (isVtk) { + addRootCanvas(); + } else { + addVtkViewport(); + } + } +} + +void ViewportPane::AttemptSplit(Qt::Orientation orientation) { + QWidget* p = parentWidget(); + if (!p) return; + + QSplitter* parentSplitter = qobject_cast(p); + if (!parentSplitter) return; + + ViewportPane* newPane = new ViewportPane(); + + // 1. Synchronize viewport content and camera (VTK Viewport only for now) + auto* currentVtk = qobject_cast(m_viewport); + if (currentVtk) { + auto* newVtk = qobject_cast(newPane->currentViewport()); + if (newVtk) { + // Copy puppets + for (auto* puppet : currentVtk->getPuppets()) { + newVtk->AddPuppet(*puppet); + } + // Copy camera + if (currentVtk->GetRenderer() && newVtk->GetRenderer()) { + vtkCamera* currentCam = currentVtk->GetRenderer()->GetActiveCamera(); + vtkCamera* newCam = newVtk->GetRenderer()->GetActiveCamera(); + if (currentCam && newCam) { + newCam->DeepCopy(currentCam); + } + } + // Sync grid visible and axis + newVtk->SetGridVisible(currentVtk->GetGridVisible()); + newVtk->SetGridAxis(currentVtk->GetGridAxis()); + } + } + + // 2. Adjust for ROOT Canvas if that was the active view + bool isRoot = (qobject_cast(m_viewport) != nullptr); + if (isRoot) { + newPane->addRootCanvas(); + } + + if (parentSplitter->orientation() == orientation) { + int index = parentSplitter->indexOf(this); + QList 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 parentSizes = parentSplitter->sizes(); + + QSplitter* newSplitter = new QSplitter(orientation); + newSplitter->addWidget(this); + newSplitter->addWidget(newPane); + + QList subSizes; + subSizes << 500 << 500; + newSplitter->setSizes(subSizes); + + parentSplitter->insertWidget(index, newSplitter); + parentSplitter->setSizes(parentSizes); + } +} diff --git a/app/gcompose/src/ViewportPane.h b/app/gcompose/src/ViewportPane.h new file mode 100644 index 0000000..9207dad --- /dev/null +++ b/app/gcompose/src/ViewportPane.h @@ -0,0 +1,34 @@ +#ifndef VIEWPORTPANE_H +#define VIEWPORTPANE_H + +#include + +class QVBoxLayout; +class QLabel; + +class ViewportPane : public QWidget { + Q_OBJECT +public: + explicit ViewportPane(QWidget* parent = nullptr); + virtual ~ViewportPane(); + + void addVtkViewport(); + void addRootCanvas(); + + QWidget* currentViewport() const { return m_viewport; } + +private slots: + void onCloseRequested(); + void showContextMenu(const QPoint& pos); + +private: + void AttemptSplit(Qt::Orientation orientation); + void setViewport(QWidget* viewport, const QString& title); + + QVBoxLayout* m_layout; + QWidget* m_titleBar; + QLabel* m_titleLabel; + QWidget* m_viewport; +}; + +#endif // VIEWPORTPANE_H diff --git a/app/gcompose/src/main.cpp b/app/gcompose/src/main.cpp index 392cdce..8755d19 100644 --- a/app/gcompose/src/main.cpp +++ b/app/gcompose/src/main.cpp @@ -1,7 +1,7 @@ #include #include "MainWindow.h" #include "MainPanel.h" -#include "QViewportPane.h" +#include "ViewportPane.h" #include "Math/ContainerBox.h" #include @@ -38,7 +38,7 @@ int main(int argc, char** argv) { // 2. Initialize MainWindow (contains embedded VTK QViewport) MainWindow window; MainPanel* panel = window.getPanel(); - QViewportPane* pane = panel->getFirstPane(); + ViewportPane* pane = panel->getFirstPane(); Vtk::QViewport* viewport = qobject_cast(pane->currentViewport()); Vtk::vtkContainerBox vtk_box(&world_box);