LayoutGadget, stability fixes
parent
0e8c25ccae
commit
98249b553a
|
@ -129,7 +129,7 @@ void AudioEngine::play(std::shared_ptr<Project> p, int fromPos) {
|
|||
}
|
||||
|
||||
seqPos = fromPos;
|
||||
curRow = -2;
|
||||
curRow = 0;
|
||||
curTick = -2;
|
||||
tempo = project->tempo;
|
||||
tickAcc = 0;
|
||||
|
|
|
@ -392,6 +392,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
if (audioEngine->playingProject() == project) audioEngine->stop();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
@ -535,7 +536,7 @@ void MainWindow::updateTitle() {
|
|||
|
||||
if (!undoStack->isClean()) songTitle.append(" (modified)");
|
||||
ui->labelSongInfo->setText(songTitle);
|
||||
setWindowTitle(qs("Xybrid - %1%2").arg(songTitle));
|
||||
setWindowTitle(qs("Xybrid - ") % songTitle);
|
||||
}
|
||||
|
||||
void MainWindow::setSongInfoPaneExpanded(bool open) {
|
||||
|
@ -587,7 +588,8 @@ void MainWindow::selectSampleForEditing(std::shared_ptr<Xybrid::Data::Sample> sm
|
|||
void MainWindow::openGraph(const std::shared_ptr<Data::Graph>& g) {
|
||||
if (!g) return; // invalid
|
||||
QPointF scrollPt(g->viewX, g->viewY);
|
||||
delete ui->patchboardView->scene();
|
||||
//delete ui->patchboardView->scene();
|
||||
if (auto s = ui->patchboardView->scene(); s) s->deleteLater();
|
||||
//ui->patchboardView->setScene(nullptr);
|
||||
ui->patchboardView->setScene(new PatchboardScene(ui->patchboardView, g));
|
||||
auto sz = ui->patchboardView->viewport()->visibleRegion().boundingRect().size();
|
||||
|
@ -596,7 +598,8 @@ void MainWindow::openGraph(const std::shared_ptr<Data::Graph>& g) {
|
|||
|
||||
void MainWindow::openNodeUI(const std::shared_ptr<Data::Node>& n) {
|
||||
if (!n) return;
|
||||
delete ui->patchboardView->scene();
|
||||
//delete ui->patchboardView->scene();
|
||||
if (auto s = ui->patchboardView->scene(); s) s->deleteLater();
|
||||
ui->patchboardView->setScene(new NodeUIScene(ui->patchboardView, n));
|
||||
// scene handles initial scroll; don't need to do it here
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ using namespace Xybrid::Config;
|
|||
using namespace Xybrid::Audio;
|
||||
|
||||
#include "ui/patchboard/nodeobject.h"
|
||||
#include "ui/gadgets/layoutgadget.h"
|
||||
#include "ui/gadgets/knobgadget.h"
|
||||
using namespace Xybrid::UI;
|
||||
|
||||
|
@ -127,10 +128,11 @@ void Xriek::loadData(const QCborMap& m) {
|
|||
void Xriek::onGadgetCreated() {
|
||||
qreal xfirst = 6;
|
||||
qreal line = 38;
|
||||
auto l = new LayoutGadget(obj->contents);
|
||||
obj->setGadgetSize((xfirst*2)+(line*1)+32, 32+32);
|
||||
{
|
||||
auto k = new KnobGadget(obj->contents);
|
||||
k->setPos(xfirst, 16);
|
||||
auto k = new KnobGadget(l);
|
||||
//k->setPos(xfirst, 16);
|
||||
k->min = 0.0;
|
||||
k->max = 5.0;
|
||||
k->step = .01;
|
||||
|
@ -139,12 +141,16 @@ void Xriek::onGadgetCreated() {
|
|||
}
|
||||
|
||||
{
|
||||
auto k = new KnobGadget(obj->contents);
|
||||
k->setPos(xfirst+line*1, 16);
|
||||
auto k = new KnobGadget(l);
|
||||
//k->setPos(xfirst+line*1, 16);
|
||||
k->min = 0.0;
|
||||
k->max = 5.0;
|
||||
k->step = .01;
|
||||
k->bind(saturation);
|
||||
k->setLabel("Saturate");
|
||||
}
|
||||
|
||||
KnobGadget::autoCreate(l, adsr);
|
||||
l->updateLayout();
|
||||
obj->setGadgetSize(obj->contents->childrenBoundingRect().bottomRight());
|
||||
}
|
||||
|
|
|
@ -9,3 +9,7 @@ void Gadget::centerOn(const QPointF& newPos) {
|
|||
// check and compensate
|
||||
if (auto nc = pos() + c; nc != newPos) setPos(newPos - (nc - newPos));
|
||||
}
|
||||
|
||||
QRectF Gadget::layoutBoundingRect() const { return boundingRect(); }
|
||||
|
||||
void Gadget::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { }
|
||||
|
|
|
@ -11,5 +11,9 @@ namespace Xybrid::UI {
|
|||
|
||||
void centerOn(const QPointF&);
|
||||
inline void centerOn(qreal x, qreal y) { centerOn(QPointF(x, y)); }
|
||||
|
||||
virtual QRectF layoutBoundingRect() const;
|
||||
|
||||
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include "knobgadget.h"
|
||||
using namespace Xybrid::UI;
|
||||
|
||||
#include "ui/gadgets/layoutgadget.h"
|
||||
#include "nodelib/basics.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QDebug>
|
||||
|
@ -52,6 +55,11 @@ QRectF KnobGadget::boundingRect() const {
|
|||
return QRectF(0, 0, size, size);
|
||||
}
|
||||
|
||||
QRectF KnobGadget::layoutBoundingRect() const {
|
||||
constexpr qreal lh = 14;
|
||||
return boundingRect().adjusted(0, -lh, 0, lh);
|
||||
}
|
||||
|
||||
QPainterPath KnobGadget::shape() const {
|
||||
QPainterPath p;
|
||||
p.addEllipse(boundingRect());
|
||||
|
@ -143,3 +151,36 @@ void KnobGadget::setLabel(const QString& s) {
|
|||
label->setText(s);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void KnobGadget::autoCreate(LayoutGadget* l, NodeLib::ADSR& adsr) {
|
||||
KnobGadget* k;
|
||||
|
||||
k = new KnobGadget(l);
|
||||
k->min = 0.0;
|
||||
k->max = 5.0;
|
||||
k->step = .01;
|
||||
k->bind(adsr.a);
|
||||
k->setLabel("Attack");
|
||||
|
||||
k = new KnobGadget(l);
|
||||
k->min = 0.0;
|
||||
k->max = 5.0;
|
||||
k->step = .01;
|
||||
k->bind(adsr.d);
|
||||
k->setLabel("Decay");
|
||||
|
||||
k = new KnobGadget(l);
|
||||
k->min = 0.0;
|
||||
k->max = 1.0;
|
||||
k->defaultVal = 1.0;
|
||||
k->step = .01;
|
||||
k->bind(adsr.s);
|
||||
k->setLabel("Sustain");
|
||||
|
||||
k = new KnobGadget(l);
|
||||
k->min = 0.0;
|
||||
k->max = 5.0;
|
||||
k->step = .01;
|
||||
k->bind(adsr.r);
|
||||
k->setLabel("Release");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include <functional>
|
||||
#include <atomic>
|
||||
|
||||
namespace Xybrid::NodeLib { class ADSR; }
|
||||
namespace Xybrid::UI {
|
||||
class LayoutGadget;
|
||||
class KnobGadget : public Gadget {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -42,6 +44,7 @@ namespace Xybrid::UI {
|
|||
~KnobGadget() override = default;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
QRectF layoutBoundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||
|
||||
|
@ -63,6 +66,8 @@ namespace Xybrid::UI {
|
|||
fGet = [p] { return p->load(); };
|
||||
fSet = [p](double d) { p->store(static_cast<T>(d)); };
|
||||
}
|
||||
|
||||
static void autoCreate(LayoutGadget*, NodeLib::ADSR&);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#include "layoutgadget.h"
|
||||
using Xybrid::UI::LayoutGadget;
|
||||
|
||||
QPointF LayoutGadget::orient(const QPointF& o) const {
|
||||
if (!vertical) return o;
|
||||
return QPointF(o.y(), o.x());
|
||||
}
|
||||
|
||||
QSizeF LayoutGadget::orient(const QSizeF& o) const {
|
||||
if (!vertical) return o;
|
||||
return o.transposed();
|
||||
}
|
||||
|
||||
QRectF LayoutGadget::orient(const QRectF& o) const {
|
||||
if (!vertical) return o;
|
||||
return o.transposed();
|
||||
}
|
||||
|
||||
LayoutGadget::LayoutGadget(QGraphicsItem* parent) : Gadget(parent) { }
|
||||
|
||||
void LayoutGadget::updateLayout() {
|
||||
qreal cur = margin;
|
||||
qreal h = 0;
|
||||
for (auto c : childItems()) {
|
||||
auto g = static_cast<Gadget*>(c);
|
||||
auto r = orient(g->layoutBoundingRect());
|
||||
h = std::max(h, r.height());
|
||||
}
|
||||
for (auto c : childItems()) {
|
||||
auto g = static_cast<Gadget*>(c);
|
||||
auto r = orient(g->layoutBoundingRect());
|
||||
g->centerOn(orient(QPointF(cur + r.width()/2, h/2)));
|
||||
cur += r.width() + spacing;
|
||||
}
|
||||
cur += margin - spacing;
|
||||
size = orient(QSizeF(cur, h));
|
||||
}
|
||||
|
||||
QRectF LayoutGadget::boundingRect() const { return { QPointF(), size }; }
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "ui/gadgets/gadget.h"
|
||||
|
||||
namespace Xybrid::UI {
|
||||
class LayoutGadget : public Gadget {
|
||||
QSizeF size;
|
||||
qreal spacing = 6;
|
||||
qreal margin = 6;
|
||||
|
||||
bool vertical = false;
|
||||
|
||||
QPointF orient(const QPointF&) const;
|
||||
QSizeF orient(const QSizeF&) const;
|
||||
QRectF orient(const QRectF&) const;
|
||||
|
||||
public:
|
||||
LayoutGadget(QGraphicsItem* parent = nullptr);
|
||||
~LayoutGadget() override = default;
|
||||
|
||||
void updateLayout();
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
};
|
||||
}
|
|
@ -112,6 +112,7 @@ namespace Xybrid::UI {
|
|||
|
||||
inline QPointF gadgetSize() const { return gadgetSize_; }
|
||||
void setGadgetSize(QPointF);
|
||||
inline void setGadgetSize(QSizeF s) { setGadgetSize(QPointF(s.width(), s.height())); }
|
||||
inline void setGadgetSize(qreal w, qreal h) { setGadgetSize(QPointF(w, h)); }
|
||||
|
||||
void updatePorts() { createPorts(); }
|
||||
|
|
Loading…
Reference in New Issue