xybrid/xybrid/ui/patchboard/patchboardscene.cpp

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);
}
}