add context panel
This commit is contained in:
@@ -7,6 +7,12 @@ add_executable(gcompose
|
|||||||
src/ViewportPane.cpp
|
src/ViewportPane.cpp
|
||||||
src/MainPanel.h
|
src/MainPanel.h
|
||||||
src/MainPanel.cpp
|
src/MainPanel.cpp
|
||||||
|
src/ContextPanel.h
|
||||||
|
src/ContextPanel.cpp
|
||||||
|
src/ContextModel.h
|
||||||
|
src/ContextModel.cpp
|
||||||
|
src/StyleManager.h
|
||||||
|
src/StyleManager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(gcompose PROPERTIES
|
set_target_properties(gcompose PROPERTIES
|
||||||
|
|||||||
132
app/gcompose/src/ContextModel.cpp
Normal file
132
app/gcompose/src/ContextModel.cpp
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#include "ContextModel.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
ContextModel::ContextModel(QObject* parent)
|
||||||
|
: QAbstractItemModel(parent), m_rootContext(nullptr) {}
|
||||||
|
|
||||||
|
ContextModel::~ContextModel() {}
|
||||||
|
|
||||||
|
void ContextModel::setContext(uLib::ObjectsContext* context) {
|
||||||
|
beginResetModel();
|
||||||
|
m_rootContext = context;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex ContextModel::index(int row, int column, const QModelIndex& parent) const {
|
||||||
|
if (!hasIndex(row, column, parent) || !m_rootContext) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parent.isValid()) {
|
||||||
|
if (row < m_rootContext->GetCount()) {
|
||||||
|
return createIndex(row, column, m_rootContext->GetObject(row));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uLib::Object* parentObj = static_cast<uLib::Object*>(parent.internalPointer());
|
||||||
|
uLib::ObjectsContext* parentCtx = dynamic_cast<uLib::ObjectsContext*>(parentObj);
|
||||||
|
if (parentCtx && row < parentCtx->GetCount()) {
|
||||||
|
return createIndex(row, column, parentCtx->GetObject(row));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex ContextModel::parent(const QModelIndex& child) const {
|
||||||
|
if (!child.isValid() || !m_rootContext) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
uLib::Object* childObj = static_cast<uLib::Object*>(child.internalPointer());
|
||||||
|
|
||||||
|
// Finding the parent of childObj is O(N) since there is no parent pointer.
|
||||||
|
// We just do a recursive search starting from root context.
|
||||||
|
std::function<uLib::ObjectsContext*(uLib::ObjectsContext*, uLib::Object*)> findParent =
|
||||||
|
[&findParent](uLib::ObjectsContext* ctx, uLib::Object* target) -> uLib::ObjectsContext* {
|
||||||
|
for (const auto& obj : ctx->GetObjects()) {
|
||||||
|
if (obj == target) return ctx;
|
||||||
|
if (auto subCtx = dynamic_cast<uLib::ObjectsContext*>(obj)) {
|
||||||
|
if (auto p = findParent(subCtx, target)) return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
uLib::ObjectsContext* parentCtx = findParent(m_rootContext, childObj);
|
||||||
|
if (!parentCtx || parentCtx == m_rootContext) {
|
||||||
|
return QModelIndex(); // Root items have invalid parent index
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now need to find the row of parentCtx in its own parent Context.
|
||||||
|
uLib::ObjectsContext* grandParentCtx = findParent(m_rootContext, parentCtx);
|
||||||
|
if (!grandParentCtx) grandParentCtx = m_rootContext;
|
||||||
|
|
||||||
|
int row = -1;
|
||||||
|
for (size_t i = 0; i < grandParentCtx->GetCount(); ++i) {
|
||||||
|
if (grandParentCtx->GetObject(i) == parentCtx) {
|
||||||
|
row = (int)i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row != -1) {
|
||||||
|
return createIndex(row, 0, parentCtx);
|
||||||
|
}
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContextModel::rowCount(const QModelIndex& parent) const {
|
||||||
|
if (!m_rootContext) return 0;
|
||||||
|
|
||||||
|
if (!parent.isValid()) {
|
||||||
|
return m_rootContext->GetCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
uLib::Object* parentObj = static_cast<uLib::Object*>(parent.internalPointer());
|
||||||
|
if (auto parentCtx = dynamic_cast<uLib::ObjectsContext*>(parentObj)) {
|
||||||
|
return parentCtx->GetCount();
|
||||||
|
}
|
||||||
|
return 0; // leaf node
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContextModel::columnCount(const QModelIndex& parent) const {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString getDemangledName(const std::type_info& info) {
|
||||||
|
int status = -4;
|
||||||
|
char* demangled = abi::__cxa_demangle(info.name(), nullptr, nullptr, &status);
|
||||||
|
QString res = (status == 0 && demangled) ? QString::fromUtf8(demangled) : QString::fromUtf8(info.name());
|
||||||
|
if (demangled) free(demangled);
|
||||||
|
|
||||||
|
// Remove namespaces
|
||||||
|
int lastColon = res.lastIndexOf("::");
|
||||||
|
if (lastColon != -1) {
|
||||||
|
res = res.mid(lastColon + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove "class " prefix if any
|
||||||
|
if (res.startsWith("class ")) res = res.mid(6);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ContextModel::data(const QModelIndex& index, int role) const {
|
||||||
|
if (!index.isValid()) return QVariant();
|
||||||
|
|
||||||
|
uLib::Object* obj = static_cast<uLib::Object*>(index.internalPointer());
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return getDemangledName(typeid(*obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ContextModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) {
|
||||||
|
return "Object Type";
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
26
app/gcompose/src/ContextModel.h
Normal file
26
app/gcompose/src/ContextModel.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef CONTEXT_MODEL_H
|
||||||
|
#define CONTEXT_MODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include "Core/ObjectsContext.h"
|
||||||
|
|
||||||
|
class ContextModel : public QAbstractItemModel {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ContextModel(QObject* parent = nullptr);
|
||||||
|
virtual ~ContextModel();
|
||||||
|
|
||||||
|
void setContext(uLib::ObjectsContext* context);
|
||||||
|
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QModelIndex parent(const QModelIndex& child) const override;
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uLib::ObjectsContext* m_rootContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTEXT_MODEL_H
|
||||||
43
app/gcompose/src/ContextPanel.cpp
Normal file
43
app/gcompose/src/ContextPanel.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include "ContextPanel.h"
|
||||||
|
#include "ContextModel.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
ContextPanel::ContextPanel(QWidget* parent) : QWidget(parent) {
|
||||||
|
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, 5, 0);
|
||||||
|
|
||||||
|
m_titleLabel = new QLabel("Context Panel", m_titleBar);
|
||||||
|
m_titleLabel->setObjectName("TitleLabel");
|
||||||
|
titleLayout->addWidget(m_titleLabel);
|
||||||
|
titleLayout->addStretch();
|
||||||
|
|
||||||
|
m_layout->addWidget(m_titleBar);
|
||||||
|
|
||||||
|
m_treeView = new QTreeView(this);
|
||||||
|
m_treeView->setObjectName("ContextTree");
|
||||||
|
m_treeView->setHeaderHidden(false);
|
||||||
|
|
||||||
|
m_model = new ContextModel(this);
|
||||||
|
m_treeView->setModel(m_model);
|
||||||
|
|
||||||
|
m_layout->addWidget(m_treeView);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextPanel::~ContextPanel() {}
|
||||||
|
|
||||||
|
void ContextPanel::setContext(uLib::ObjectsContext* context) {
|
||||||
|
m_model->setContext(context);
|
||||||
|
m_treeView->expandAll();
|
||||||
|
}
|
||||||
31
app/gcompose/src/ContextPanel.h
Normal file
31
app/gcompose/src/ContextPanel.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef CONTEXT_PANEL_H
|
||||||
|
#define CONTEXT_PANEL_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QTreeView;
|
||||||
|
class QVBoxLayout;
|
||||||
|
class QLabel;
|
||||||
|
class ContextModel;
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
class ObjectsContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContextPanel : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ContextPanel(QWidget* parent = nullptr);
|
||||||
|
virtual ~ContextPanel();
|
||||||
|
|
||||||
|
void setContext(uLib::ObjectsContext* context);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVBoxLayout* m_layout;
|
||||||
|
QWidget* m_titleBar;
|
||||||
|
QLabel* m_titleLabel;
|
||||||
|
QTreeView* m_treeView;
|
||||||
|
ContextModel* m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTEXT_PANEL_H
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
#include "MainPanel.h"
|
#include "MainPanel.h"
|
||||||
#include "ViewportPane.h"
|
#include "ViewportPane.h"
|
||||||
|
#include "ContextPanel.h"
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "StyleManager.h"
|
||||||
|
|
||||||
MainPanel::MainPanel(QWidget* parent) : QWidget(parent) {
|
MainPanel::MainPanel(QWidget* parent) : QWidget(parent) {
|
||||||
auto* mainLayout = new QVBoxLayout(this);
|
auto* mainLayout = new QVBoxLayout(this);
|
||||||
@@ -13,37 +18,72 @@ MainPanel::MainPanel(QWidget* parent) : QWidget(parent) {
|
|||||||
|
|
||||||
// 1. Top Menu Panel
|
// 1. Top Menu Panel
|
||||||
auto* menuPanel = new QWidget(this);
|
auto* menuPanel = new QWidget(this);
|
||||||
|
menuPanel->setObjectName("MenuPanel");
|
||||||
menuPanel->setFixedHeight(36);
|
menuPanel->setFixedHeight(36);
|
||||||
menuPanel->setStyleSheet("background-color: #2b2b2b; border-bottom: 1px solid #111;");
|
|
||||||
|
|
||||||
auto* menuLayout = new QHBoxLayout(menuPanel);
|
auto* menuLayout = new QHBoxLayout(menuPanel);
|
||||||
menuLayout->setContentsMargins(10, 0, 10, 0);
|
menuLayout->setContentsMargins(10, 0, 10, 0);
|
||||||
menuLayout->setSpacing(15);
|
menuLayout->setSpacing(15);
|
||||||
|
|
||||||
auto* logo = new QLabel("G-COMPOSE", menuPanel);
|
auto* logo = new QLabel("G-COMPOSE", menuPanel);
|
||||||
logo->setStyleSheet("font-weight: bold; color: #0078d7; font-size: 14px; letter-spacing: 1px;");
|
logo->setObjectName("LogoLabel");
|
||||||
|
|
||||||
auto* btnOpen = new QPushButton("Open", menuPanel);
|
// File Menu Button
|
||||||
auto* btnSave = new QPushButton("Save", menuPanel);
|
auto* btnFile = new QPushButton("File", menuPanel);
|
||||||
|
btnFile->setObjectName("MenuButton");
|
||||||
QString btnStyle = "QPushButton { background: transparent; color: #ccc; border: none; padding: 5px 10px; }"
|
auto* fileMenu = new QMenu(btnFile);
|
||||||
"QPushButton:hover { background: #3c3c3c; color: white; border-radius: 4px; }";
|
fileMenu->addAction("Open", this, &MainPanel::onOpen);
|
||||||
btnOpen->setStyleSheet(btnStyle);
|
fileMenu->addAction("Save", this, &MainPanel::onSave);
|
||||||
btnSave->setStyleSheet(btnStyle);
|
btnFile->setMenu(fileMenu);
|
||||||
|
|
||||||
|
// Theme Menu Button
|
||||||
|
auto* btnTheme = new QPushButton("Theme", menuPanel);
|
||||||
|
btnTheme->setObjectName("MenuButton");
|
||||||
|
auto* themeMenu = new QMenu(btnTheme);
|
||||||
|
themeMenu->addAction("Dark", this, &MainPanel::onDarkTheme);
|
||||||
|
themeMenu->addAction("Bright", this, &MainPanel::onBrightTheme);
|
||||||
|
btnTheme->setMenu(themeMenu);
|
||||||
|
|
||||||
menuLayout->addWidget(logo);
|
menuLayout->addWidget(logo);
|
||||||
menuLayout->addWidget(btnOpen);
|
menuLayout->addWidget(btnFile);
|
||||||
menuLayout->addWidget(btnSave);
|
menuLayout->addWidget(btnTheme);
|
||||||
menuLayout->addStretch();
|
menuLayout->addStretch();
|
||||||
|
|
||||||
mainLayout->addWidget(menuPanel);
|
mainLayout->addWidget(menuPanel);
|
||||||
|
|
||||||
// 2. Central Splitter Area
|
// 2. Central Splitter Area
|
||||||
m_rootSplitter = new QSplitter(Qt::Horizontal, this);
|
m_rootSplitter = new QSplitter(Qt::Horizontal, this);
|
||||||
|
m_contextPanel = new ContextPanel(m_rootSplitter);
|
||||||
|
m_rootSplitter->addWidget(m_contextPanel);
|
||||||
m_firstPane = new ViewportPane(m_rootSplitter);
|
m_firstPane = new ViewportPane(m_rootSplitter);
|
||||||
m_rootSplitter->addWidget(m_firstPane);
|
m_rootSplitter->addWidget(m_firstPane);
|
||||||
|
|
||||||
|
// Set initial sizes
|
||||||
|
QList<int> sizes;
|
||||||
|
sizes << 200 << 1000;
|
||||||
|
m_rootSplitter->setSizes(sizes);
|
||||||
|
|
||||||
mainLayout->addWidget(m_rootSplitter, 1);
|
mainLayout->addWidget(m_rootSplitter, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainPanel::setContext(uLib::ObjectsContext* context) {
|
||||||
|
m_contextPanel->setContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainPanel::onOpen() {
|
||||||
|
// Placeholder for open logic
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainPanel::onSave() {
|
||||||
|
// Placeholder for save logic
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainPanel::onDarkTheme() {
|
||||||
|
StyleManager::applyStyle(qApp, "dark");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainPanel::onBrightTheme() {
|
||||||
|
StyleManager::applyStyle(qApp, "bright");
|
||||||
|
}
|
||||||
|
|
||||||
MainPanel::~MainPanel() {}
|
MainPanel::~MainPanel() {}
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
class QSplitter;
|
class QSplitter;
|
||||||
class ViewportPane;
|
class ViewportPane;
|
||||||
|
class ContextPanel;
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
class ObjectsContext;
|
||||||
|
}
|
||||||
|
|
||||||
class MainPanel : public QWidget {
|
class MainPanel : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -12,11 +17,19 @@ public:
|
|||||||
explicit MainPanel(QWidget* parent = nullptr);
|
explicit MainPanel(QWidget* parent = nullptr);
|
||||||
virtual ~MainPanel();
|
virtual ~MainPanel();
|
||||||
|
|
||||||
|
void setContext(uLib::ObjectsContext* context);
|
||||||
ViewportPane* getFirstPane() const { return m_firstPane; }
|
ViewportPane* getFirstPane() const { return m_firstPane; }
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onOpen();
|
||||||
|
void onSave();
|
||||||
|
void onDarkTheme();
|
||||||
|
void onBrightTheme();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSplitter* m_rootSplitter;
|
QSplitter* m_rootSplitter;
|
||||||
ViewportPane* m_firstPane;
|
ViewportPane* m_firstPane;
|
||||||
|
ContextPanel* m_contextPanel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINPANEL_H
|
#endif // MAINPANEL_H
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include "MainPanel.h"
|
#include "MainPanel.h"
|
||||||
|
#include "Core/ObjectsContext.h"
|
||||||
|
|
||||||
using namespace uLib;
|
using namespace uLib;
|
||||||
|
|
||||||
@@ -14,3 +15,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
|
|||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::setContext(uLib::ObjectsContext* context) {
|
||||||
|
m_panel->setContext(context);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class ViewportPane;
|
|||||||
namespace uLib {
|
namespace uLib {
|
||||||
namespace Vtk {
|
namespace Vtk {
|
||||||
}
|
}
|
||||||
|
class ObjectsContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainWindow : public QMainWindow {
|
class MainWindow : public QMainWindow {
|
||||||
@@ -18,6 +19,7 @@ public:
|
|||||||
MainWindow(QWidget* parent = nullptr);
|
MainWindow(QWidget* parent = nullptr);
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
void setContext(uLib::ObjectsContext* context);
|
||||||
MainPanel* getPanel() { return m_panel; }
|
MainPanel* getPanel() { return m_panel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -17,19 +17,19 @@ QViewportPane::QViewportPane(QWidget* parent) : QWidget(parent), m_viewport(null
|
|||||||
|
|
||||||
// Title bar setup
|
// Title bar setup
|
||||||
m_titleBar = new QWidget(this);
|
m_titleBar = new QWidget(this);
|
||||||
|
m_titleBar->setObjectName("PaneTitleBar");
|
||||||
m_titleBar->setFixedHeight(22);
|
m_titleBar->setFixedHeight(22);
|
||||||
m_titleBar->setStyleSheet("background-color: #333; color: white;");
|
|
||||||
|
|
||||||
auto* titleLayout = new QHBoxLayout(m_titleBar);
|
auto* titleLayout = new QHBoxLayout(m_titleBar);
|
||||||
titleLayout->setContentsMargins(5, 0, 5, 0);
|
titleLayout->setContentsMargins(5, 0, 5, 0);
|
||||||
|
|
||||||
m_titleLabel = new QLabel("Viewport", m_titleBar);
|
m_titleLabel = new QLabel("Viewport", m_titleBar);
|
||||||
|
m_titleLabel->setObjectName("TitleLabel");
|
||||||
|
|
||||||
auto* closeBtn = new QToolButton(m_titleBar);
|
auto* closeBtn = new QToolButton(m_titleBar);
|
||||||
|
closeBtn->setObjectName("PaneCloseButton");
|
||||||
closeBtn->setText("X");
|
closeBtn->setText("X");
|
||||||
closeBtn->setFixedSize(18, 18);
|
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->addWidget(m_titleLabel);
|
||||||
titleLayout->addStretch();
|
titleLayout->addStretch();
|
||||||
|
|||||||
44
app/gcompose/src/StyleManager.cpp
Normal file
44
app/gcompose/src/StyleManager.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "StyleManager.h"
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
static const QString DARK_THEME = R"(
|
||||||
|
QWidget#MenuPanel { background-color: #2b2b2b; border-bottom: 1px solid #111; }
|
||||||
|
QLabel#LogoLabel { font-weight: bold; color: #0078d7; font-size: 14px; letter-spacing: 1px; }
|
||||||
|
QPushButton#MenuButton { background: transparent; color: #ccc; border: none; padding: 5px 10px; }
|
||||||
|
QPushButton#MenuButton:hover { background: #3c3c3c; color: white; border-radius: 4px; }
|
||||||
|
QWidget#PaneTitleBar { background-color: #333; color: white; }
|
||||||
|
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #ccc; }
|
||||||
|
QToolButton#PaneCloseButton:hover { color: white; background: red; }
|
||||||
|
QMenu { background-color: #2b2b2b; color: white; border: 1px solid #111; }
|
||||||
|
QMenu::item:selected { background-color: #3c3c3c; }
|
||||||
|
QTreeView#ContextTree { background-color: #1e1e1e; color: #ccc; border: none; }
|
||||||
|
QTreeView#ContextTree::item:hover { background-color: #2a2d2e; }
|
||||||
|
QTreeView#ContextTree::item:selected { background-color: #094771; color: white; }
|
||||||
|
QHeaderView::section { background-color: #252526; color: #ccc; border: 1px solid #323233; padding: 4px; }
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const QString BRIGHT_THEME = R"(
|
||||||
|
QWidget#MenuPanel { background-color: #f0f0f0; border-bottom: 1px solid #ccc; }
|
||||||
|
QLabel#LogoLabel { font-weight: bold; color: #005a9e; font-size: 14px; letter-spacing: 1px; }
|
||||||
|
QPushButton#MenuButton { background: transparent; color: #333; border: none; padding: 5px 10px; }
|
||||||
|
QPushButton#MenuButton:hover { background: #d0d0d0; color: black; border-radius: 4px; }
|
||||||
|
QWidget#PaneTitleBar { background-color: #e0e0e0; color: black; }
|
||||||
|
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #666; }
|
||||||
|
QToolButton#PaneCloseButton:hover { color: white; background: #e81123; }
|
||||||
|
QMenu { background-color: #f0f0f0; color: black; border: 1px solid #ccc; }
|
||||||
|
QMenu::item:selected { background-color: #d0d0d0; }
|
||||||
|
QTreeView#ContextTree { background-color: #ffffff; color: #333; border: none; }
|
||||||
|
QTreeView#ContextTree::item:hover { background-color: #f2f2f2; }
|
||||||
|
QTreeView#ContextTree::item:selected { background-color: #0078d7; color: white; }
|
||||||
|
QHeaderView::section { background-color: #f3f3f3; color: #333; border: 1px solid #ccc; padding: 4px; }
|
||||||
|
)";
|
||||||
|
|
||||||
|
void StyleManager::applyStyle(QApplication* app, const QString& themeName) {
|
||||||
|
if (!app) return;
|
||||||
|
|
||||||
|
if (themeName == "bright") {
|
||||||
|
app->setStyleSheet(BRIGHT_THEME);
|
||||||
|
} else {
|
||||||
|
app->setStyleSheet(DARK_THEME); // default
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/gcompose/src/StyleManager.h
Normal file
13
app/gcompose/src/StyleManager.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef STYLEMANAGER_H
|
||||||
|
#define STYLEMANAGER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class QApplication;
|
||||||
|
|
||||||
|
class StyleManager {
|
||||||
|
public:
|
||||||
|
static void applyStyle(QApplication* app, const QString& themeName);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STYLEMANAGER_H
|
||||||
@@ -17,19 +17,19 @@ ViewportPane::ViewportPane(QWidget* parent) : QWidget(parent), m_viewport(nullpt
|
|||||||
|
|
||||||
// Title bar setup
|
// Title bar setup
|
||||||
m_titleBar = new QWidget(this);
|
m_titleBar = new QWidget(this);
|
||||||
|
m_titleBar->setObjectName("PaneTitleBar");
|
||||||
m_titleBar->setFixedHeight(22);
|
m_titleBar->setFixedHeight(22);
|
||||||
m_titleBar->setStyleSheet("background-color: #333; color: white;");
|
|
||||||
|
|
||||||
auto* titleLayout = new QHBoxLayout(m_titleBar);
|
auto* titleLayout = new QHBoxLayout(m_titleBar);
|
||||||
titleLayout->setContentsMargins(5, 0, 5, 0);
|
titleLayout->setContentsMargins(5, 0, 5, 0);
|
||||||
|
|
||||||
m_titleLabel = new QLabel("Viewport", m_titleBar);
|
m_titleLabel = new QLabel("Viewport", m_titleBar);
|
||||||
|
m_titleLabel->setObjectName("TitleLabel");
|
||||||
|
|
||||||
auto* closeBtn = new QToolButton(m_titleBar);
|
auto* closeBtn = new QToolButton(m_titleBar);
|
||||||
|
closeBtn->setObjectName("PaneCloseButton");
|
||||||
closeBtn->setText("X");
|
closeBtn->setText("X");
|
||||||
closeBtn->setFixedSize(18, 18);
|
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->addWidget(m_titleLabel);
|
||||||
titleLayout->addStretch();
|
titleLayout->addStretch();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "MainPanel.h"
|
#include "MainPanel.h"
|
||||||
#include "ViewportPane.h"
|
#include "ViewportPane.h"
|
||||||
|
#include "StyleManager.h"
|
||||||
|
|
||||||
#include "Math/ContainerBox.h"
|
#include "Math/ContainerBox.h"
|
||||||
#include <HEP/Geant/Scene.h>
|
#include <HEP/Geant/Scene.h>
|
||||||
@@ -11,6 +12,8 @@
|
|||||||
#include <Vtk/vtkContainerBox.h>
|
#include <Vtk/vtkContainerBox.h>
|
||||||
#include <Vtk/vtkQViewport.h>
|
#include <Vtk/vtkQViewport.h>
|
||||||
|
|
||||||
|
#include "Core/ObjectsContext.h"
|
||||||
|
|
||||||
#include <vtkSmartPointer.h>
|
#include <vtkSmartPointer.h>
|
||||||
#include <vtkCubeSource.h>
|
#include <vtkCubeSource.h>
|
||||||
#include <vtkPolyDataMapper.h>
|
#include <vtkPolyDataMapper.h>
|
||||||
@@ -26,6 +29,7 @@ using namespace uLib::literals;
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
StyleManager::applyStyle(&app, "dark");
|
||||||
std::cout << "Starting gcompose Qt application..." << std::endl;
|
std::cout << "Starting gcompose Qt application..." << std::endl;
|
||||||
|
|
||||||
ContainerBox world_box(Vector3f(1, 1, 1));
|
ContainerBox world_box(Vector3f(1, 1, 1));
|
||||||
@@ -35,8 +39,13 @@ int main(int argc, char** argv) {
|
|||||||
scene.ConstructWorldBox(world_box.GetSize(), "G4_AIR");
|
scene.ConstructWorldBox(world_box.GetSize(), "G4_AIR");
|
||||||
scene.Initialize();
|
scene.Initialize();
|
||||||
|
|
||||||
|
uLib::ObjectsContext globalContext;
|
||||||
|
globalContext.AddObject(&world_box);
|
||||||
|
globalContext.AddObject(&scene);
|
||||||
|
|
||||||
// 2. Initialize MainWindow (contains embedded VTK QViewport)
|
// 2. Initialize MainWindow (contains embedded VTK QViewport)
|
||||||
MainWindow window;
|
MainWindow window;
|
||||||
|
window.setContext(&globalContext);
|
||||||
MainPanel* panel = window.getPanel();
|
MainPanel* panel = window.getPanel();
|
||||||
ViewportPane* pane = panel->getFirstPane();
|
ViewportPane* pane = panel->getFirstPane();
|
||||||
Vtk::QViewport* viewport = qobject_cast<Vtk::QViewport*>(pane->currentViewport());
|
Vtk::QViewport* viewport = qobject_cast<Vtk::QViewport*>(pane->currentViewport());
|
||||||
|
|||||||
Reference in New Issue
Block a user