GUI Milestone 8c
This commit is contained in:
parent
befe57530a
commit
fa67dd3708
9 changed files with 458 additions and 22 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "GraphEditorWidget.h"
|
||||
#include "PresetManager.h"
|
||||
#include "WarpGraphModel.h"
|
||||
|
||||
#include <QtNodes/BasicGraphicsScene>
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
|
|
@ -21,10 +23,16 @@
|
|||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QMenu>
|
||||
#include <QListWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QSplitter>
|
||||
#include <QStandardPaths>
|
||||
#include <QStatusBar>
|
||||
#include <QTabWidget>
|
||||
#include <QTimer>
|
||||
#include <QUndoCommand>
|
||||
#include <QVBoxLayout>
|
||||
|
|
@ -142,9 +150,58 @@ GraphEditorWidget::GraphEditorWidget(warppipe::Client *client,
|
|||
m_view->viewport()->setFocusPolicy(Qt::StrongFocus);
|
||||
m_view->viewport()->installEventFilter(this);
|
||||
|
||||
m_presetDir =
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) +
|
||||
QStringLiteral("/presets");
|
||||
|
||||
m_sidebar = new QTabWidget();
|
||||
m_sidebar->setTabPosition(QTabWidget::North);
|
||||
m_sidebar->setDocumentMode(true);
|
||||
m_sidebar->setStyleSheet(QStringLiteral(
|
||||
"QTabWidget::pane { border: none; background: #1a1a1e; }"
|
||||
"QTabBar::tab { background: #24242a; color: #a0a8b6; padding: 8px 16px;"
|
||||
" border: none; border-bottom: 2px solid transparent; }"
|
||||
"QTabBar::tab:selected { color: #ecf0f6;"
|
||||
" border-bottom: 2px solid #ffa500; }"
|
||||
"QTabBar::tab:hover { background: #2e2e36; }"));
|
||||
|
||||
auto *presetsTab = new QWidget();
|
||||
auto *presetsLayout = new QVBoxLayout(presetsTab);
|
||||
presetsLayout->setContentsMargins(8, 8, 8, 8);
|
||||
presetsLayout->setSpacing(6);
|
||||
|
||||
auto *savePresetBtn = new QPushButton(QStringLiteral("Save Preset..."));
|
||||
savePresetBtn->setStyleSheet(QStringLiteral(
|
||||
"QPushButton { background: #2e2e36; color: #ecf0f6; border: 1px solid #3a3a44;"
|
||||
" border-radius: 4px; padding: 6px 12px; }"
|
||||
"QPushButton:hover { background: #3a3a44; }"
|
||||
"QPushButton:pressed { background: #44444e; }"));
|
||||
connect(savePresetBtn, &QPushButton::clicked, this,
|
||||
&GraphEditorWidget::savePreset);
|
||||
|
||||
auto *loadPresetBtn = new QPushButton(QStringLiteral("Load Preset..."));
|
||||
loadPresetBtn->setStyleSheet(savePresetBtn->styleSheet());
|
||||
connect(loadPresetBtn, &QPushButton::clicked, this,
|
||||
&GraphEditorWidget::loadPreset);
|
||||
|
||||
presetsLayout->addWidget(savePresetBtn);
|
||||
presetsLayout->addWidget(loadPresetBtn);
|
||||
presetsLayout->addStretch();
|
||||
|
||||
m_sidebar->addTab(presetsTab, QStringLiteral("PRESETS"));
|
||||
|
||||
m_splitter = new QSplitter(Qt::Horizontal);
|
||||
m_splitter->addWidget(m_view);
|
||||
m_splitter->addWidget(m_sidebar);
|
||||
m_splitter->setStretchFactor(0, 1);
|
||||
m_splitter->setStretchFactor(1, 0);
|
||||
m_splitter->setSizes({1200, 320});
|
||||
m_splitter->setStyleSheet(QStringLiteral(
|
||||
"QSplitter::handle { background: #2a2a32; width: 2px; }"));
|
||||
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_view);
|
||||
layout->addWidget(m_splitter);
|
||||
|
||||
m_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_view, &QWidget::customContextMenuRequested, this,
|
||||
|
|
@ -266,6 +323,9 @@ GraphEditorWidget::GraphEditorWidget(warppipe::Client *client,
|
|||
Q_EMIT graphReady();
|
||||
}
|
||||
|
||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this,
|
||||
&GraphEditorWidget::saveLayoutWithViewState);
|
||||
|
||||
m_refreshTimer = new QTimer(this);
|
||||
connect(m_refreshTimer, &QTimer::timeout, this,
|
||||
&GraphEditorWidget::onRefreshTimer);
|
||||
|
|
@ -430,6 +490,9 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos,
|
|||
menu.addSeparator();
|
||||
QAction *saveLayoutAs = menu.addAction(QStringLiteral("Save Layout As..."));
|
||||
QAction *resetLayout = menu.addAction(QStringLiteral("Reset Layout"));
|
||||
menu.addSeparator();
|
||||
QAction *savePresetAction = menu.addAction(QStringLiteral("Save Preset..."));
|
||||
QAction *loadPresetAction = menu.addAction(QStringLiteral("Load Preset..."));
|
||||
|
||||
QAction *chosen = menu.exec(screenPos);
|
||||
if (chosen == createSink) {
|
||||
|
|
@ -466,6 +529,10 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos,
|
|||
m_model->autoArrange();
|
||||
m_view->zoomFitAll();
|
||||
saveLayoutWithViewState();
|
||||
} else if (chosen == savePresetAction) {
|
||||
savePreset();
|
||||
} else if (chosen == loadPresetAction) {
|
||||
loadPreset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -868,6 +935,9 @@ void GraphEditorWidget::saveLayoutWithViewState() {
|
|||
QPointF center = m_view->mapToScene(m_view->viewport()->rect().center());
|
||||
vs.centerX = center.x();
|
||||
vs.centerY = center.y();
|
||||
QList<int> sizes = m_splitter->sizes();
|
||||
vs.splitterGraph = sizes.value(0, 1200);
|
||||
vs.splitterSidebar = sizes.value(1, 320);
|
||||
vs.valid = true;
|
||||
m_model->saveLayout(m_layoutPath, vs);
|
||||
}
|
||||
|
|
@ -877,7 +947,50 @@ void GraphEditorWidget::restoreViewState() {
|
|||
if (vs.valid) {
|
||||
m_view->setupScale(vs.scale);
|
||||
m_view->centerOn(QPointF(vs.centerX, vs.centerY));
|
||||
if (vs.splitterGraph > 0 || vs.splitterSidebar > 0) {
|
||||
m_splitter->setSizes({vs.splitterGraph, vs.splitterSidebar});
|
||||
}
|
||||
} else {
|
||||
m_view->zoomFitAll();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditorWidget::savePreset() {
|
||||
QDir dir(m_presetDir);
|
||||
if (!dir.exists())
|
||||
dir.mkpath(".");
|
||||
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
this, QStringLiteral("Save Preset"), m_presetDir,
|
||||
QStringLiteral("JSON files (*.json)"));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
if (!path.endsWith(QStringLiteral(".json"), Qt::CaseInsensitive))
|
||||
path += QStringLiteral(".json");
|
||||
|
||||
if (PresetManager::savePreset(path, m_client, m_model)) {
|
||||
if (auto *mw = qobject_cast<QMainWindow *>(window()))
|
||||
mw->statusBar()->showMessage(
|
||||
QStringLiteral("Preset saved: ") + QFileInfo(path).fileName(), 4000);
|
||||
} else {
|
||||
QMessageBox::warning(this, QStringLiteral("Error"),
|
||||
QStringLiteral("Failed to save preset."));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditorWidget::loadPreset() {
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, QStringLiteral("Load Preset"), m_presetDir,
|
||||
QStringLiteral("JSON files (*.json)"));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
if (PresetManager::loadPreset(path, m_client, m_model)) {
|
||||
if (auto *mw = qobject_cast<QMainWindow *>(window()))
|
||||
mw->statusBar()->showMessage(
|
||||
QStringLiteral("Preset loaded: ") + QFileInfo(path).fileName(), 4000);
|
||||
} else {
|
||||
QMessageBox::warning(this, QStringLiteral("Error"),
|
||||
QStringLiteral("Failed to load preset."));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue