98 lines
3.1 KiB
C++
98 lines
3.1 KiB
C++
#include "patchboardscene.h"
|
|
using Xybrid::UI::PatchboardScene;
|
|
|
|
#include <cmath>
|
|
|
|
#include <QDebug>
|
|
#include <QScrollBar>
|
|
#include <QGraphicsItem>
|
|
#include <QMainWindow>
|
|
#include <QMenu>
|
|
#include <QTimer>
|
|
|
|
#include <QGraphicsSceneContextMenuEvent>
|
|
|
|
#include "data/graph.h"
|
|
using namespace Xybrid::Data;
|
|
#include "config/pluginregistry.h"
|
|
using namespace Xybrid::Config;
|
|
|
|
#include "ui/patchboard/nodeobject.h"
|
|
|
|
#include "config/colorscheme.h"
|
|
|
|
PatchboardScene::PatchboardScene(QGraphicsView* parent, const std::shared_ptr<Xybrid::Data::Graph>& g) : QGraphicsScene(parent) {
|
|
graph = g;
|
|
view = parent;
|
|
|
|
connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, this, &PatchboardScene::queueResize);
|
|
connect(view->verticalScrollBar(), &QScrollBar::valueChanged, this, &PatchboardScene::queueResize);
|
|
connect(view->horizontalScrollBar(), &QScrollBar::rangeChanged, this, &PatchboardScene::queueResize);
|
|
connect(view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &PatchboardScene::queueResize);
|
|
connect(this, &QGraphicsScene::changed, this, &PatchboardScene::queueResize);
|
|
|
|
refresh();
|
|
}
|
|
|
|
void PatchboardScene::drawBackground(QPainter* painter, const QRectF& rect) {
|
|
painter->setBrush(QBrush(Config::colorScheme.patternBg));
|
|
painter->setPen(QPen(Qt::PenStyle::NoPen));
|
|
painter->drawRect(rect);
|
|
|
|
const constexpr int step = 32; // grid size
|
|
painter->setPen(QPen(QColor(127, 127, 127, 63), 1));
|
|
for (auto y = std::floor(rect.top() / step) * step + .5; y < rect.bottom(); y += step)
|
|
painter->drawLine(QPointF(rect.left(), y), QPointF(rect.right(), y));
|
|
for (auto x = std::floor(rect.left() / step) * step + .5; x < rect.right(); x += step)
|
|
painter->drawLine(QPointF(x, rect.top()), QPointF(x, rect.bottom()));
|
|
}
|
|
|
|
void PatchboardScene::contextMenuEvent(QGraphicsSceneContextMenuEvent* e) {
|
|
// only override if nothing inside picks it up
|
|
QGraphicsScene::contextMenuEvent(e);
|
|
if (e->isAccepted()) return;
|
|
|
|
auto p = e->scenePos();
|
|
auto* m = new QMenu();
|
|
PluginRegistry::populatePluginMenu(m->addMenu("Add..."), [this, p](std::shared_ptr<Node> n) {
|
|
n->x = static_cast<int>(p.x());
|
|
n->y = static_cast<int>(p.y());
|
|
n->parentTo(graph);
|
|
|
|
addItem(new NodeObject(n));
|
|
}, graph.get());
|
|
|
|
m->setAttribute(Qt::WA_DeleteOnClose);
|
|
m->popup(e->screenPos());
|
|
}
|
|
|
|
void PatchboardScene::queueResize() {
|
|
if (!resizeQueued) {
|
|
resizeQueued = true;
|
|
QTimer::singleShot(1, this, &PatchboardScene::autoSetSize);
|
|
}
|
|
}
|
|
|
|
void PatchboardScene::autoSetSize() {
|
|
if (view->scene() != this) return;
|
|
auto vrect = view->mapToScene(view->viewport()->visibleRegion().boundingRect()).boundingRect();
|
|
auto rect = itemsBoundingRect()
|
|
.united(vrect)
|
|
.united(QRectF(0, 0, 1, 1));
|
|
rect.setTopLeft(QPointF(0, 0));
|
|
setSceneRect(rect);
|
|
graph->viewX = static_cast<int>(vrect.left());
|
|
graph->viewY = static_cast<int>(vrect.top());
|
|
resizeQueued = false;
|
|
}
|
|
|
|
void PatchboardScene::refresh() {
|
|
// build scene from graph
|
|
clear();
|
|
|
|
for (auto n : graph->children) {
|
|
auto* o = new NodeObject(n);
|
|
addItem(o);
|
|
}
|
|
}
|