add gain to beatpad, layoutgadget panel flag, nodeuiscene improvements
parent
d0db5a6b4d
commit
affb86d76a
13
notes
13
notes
|
@ -32,15 +32,22 @@ parameters {
|
|||
|
||||
TODO {
|
||||
immediate frontburner {
|
||||
- standardized "draw panel" function in nodeobject
|
||||
- ^ use in both default draw and quicklevel
|
||||
- add per-sample gain to BeatPad
|
||||
|
||||
- node scene constructor for layoutgadget
|
||||
- ^ use in beatpad
|
||||
|
||||
distortion effect
|
||||
single-selection sampler
|
||||
|
||||
add ,XX support to global tempo
|
||||
}
|
||||
|
||||
buffer helper akin to what quicklevel does {
|
||||
keeps a buffer length, running averages, etc.
|
||||
can lerp across tick for speed
|
||||
useful for level reading, waveform output, compression/sidechaining etc.
|
||||
}
|
||||
|
||||
solo gadget {
|
||||
interprets incoming commands as monophonic with portamento
|
||||
probably not super useful for tracked things but good for playing live
|
||||
|
|
|
@ -19,6 +19,7 @@ using namespace Xybrid::Audio;
|
|||
#include "ui/waveformpreviewwidget.h"
|
||||
|
||||
#include "ui/patchboard/nodeobject.h"
|
||||
#include "ui/gadgets/layoutgadget.h"
|
||||
#include "ui/gadgets/knobgadget.h"
|
||||
#include "ui/gadgets/selectorgadget.h"
|
||||
#include "ui/gadgets/sampleselectorgadget.h"
|
||||
|
@ -111,7 +112,7 @@ void BeatPad::init() {
|
|||
|
||||
auto out = NodeLib::resamp(smp.get(), sp, rate);
|
||||
|
||||
(*p)[i] += out.gainBalance(0, note.pan) * note.ampMult();
|
||||
(*p)[i] += out.gainBalance(data.config->gain, note.pan) * note.ampMult();
|
||||
data.sampleTime += 1;
|
||||
}
|
||||
};
|
||||
|
@ -129,6 +130,7 @@ void BeatPad::saveData(QCborMap& m) const {
|
|||
e[qs("sample")] = QCborValue(smp->uuid);
|
||||
e[qs("start")] = static_cast<qint64>(c.second->start);
|
||||
e[qs("end")] = static_cast<qint64>(c.second->end);
|
||||
e[qs("gain")] = c.second->gain;
|
||||
cm[c.first] = e;
|
||||
smp->markForExport();
|
||||
}
|
||||
|
@ -145,6 +147,7 @@ void BeatPad::loadData(const QCborMap& m) {
|
|||
c->smp = f.value();
|
||||
c->start = cm.value("start").toInteger(-1);
|
||||
c->end = cm.value("end").toInteger(-1);
|
||||
c->gain = cm.value("gain").toDouble(0.0);
|
||||
cfg[static_cast<int16_t>(ce.first.toInteger())] = c;
|
||||
}
|
||||
}
|
||||
|
@ -172,10 +175,11 @@ void BeatPad::initUI(NodeUIScene* scene) {
|
|||
};
|
||||
auto state = scene->makeStateObject<UIState>();
|
||||
|
||||
// init layout
|
||||
auto ol = (new LayoutGadget(scene, true))->setPanel(true);
|
||||
|
||||
// set up gadgets
|
||||
auto noteSelector = new SelectorGadget();
|
||||
scene->addItem(noteSelector);
|
||||
noteSelector->setPos(0, 0);
|
||||
auto noteSelector = new SelectorGadget(ol);
|
||||
noteSelector->setWidth(320);
|
||||
|
||||
noteSelector->fGetList = [=] {
|
||||
|
@ -206,11 +210,12 @@ void BeatPad::initUI(NodeUIScene* scene) {
|
|||
}
|
||||
};
|
||||
|
||||
auto sampleSelector = new SampleSelectorGadget(project);
|
||||
scene->addItem(sampleSelector);
|
||||
sampleSelector->setPos(0, 28);
|
||||
auto sampleSelector = new SampleSelectorGadget(project, ol);
|
||||
sampleSelector->setSize(320, 96);
|
||||
|
||||
auto r1 = (new LayoutGadget(ol))->setMetrics(0, -1, 0.0);
|
||||
auto gain = (new KnobGadget(r1))->setRange(-60, 12, .1)->setLabel("Gain")->setTextFunc([](double d) { return QString("%1dB").arg(d); });
|
||||
|
||||
// create functions now that all UI elements exist to be referenced
|
||||
state->selectNote = [=](int16_t n) {
|
||||
if (auto f = cfg.find(n); f != cfg.end()) state->cfg = f->second;
|
||||
|
@ -218,6 +223,7 @@ void BeatPad::initUI(NodeUIScene* scene) {
|
|||
state->note = n;
|
||||
auto smp = state->cfg->smp.lock();
|
||||
sampleSelector->setSample(smp);
|
||||
gain->bind(state->cfg->gain);
|
||||
|
||||
noteSelector->setEntry({n, qs("%1 %2").arg(Util::noteName(n)).arg(smp ? smp->name.section('/', -1, -1) : "")}, false);
|
||||
};
|
||||
|
@ -230,6 +236,8 @@ void BeatPad::initUI(NodeUIScene* scene) {
|
|||
noteSelector->setEntry({n, qs("%1 %2").arg(Util::noteName(n)).arg(smp ? smp->name : "")}, false);
|
||||
};
|
||||
|
||||
//ol->updateGeometry();
|
||||
|
||||
// hook up relevantsignals
|
||||
QObject::connect(scene, &NodeUIScene::notePreview, [=](int16_t note) { state->selectNote(note); });
|
||||
QObject::connect(noteSelector, &SelectorGadget::onSelect, [=](auto e) { state->selectNote(e.first); });
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace Xybrid::Instruments {
|
|||
std::weak_ptr<Data::Sample> smp = std::weak_ptr<Data::Sample>();
|
||||
ptrdiff_t start = -1;
|
||||
ptrdiff_t end = -1;
|
||||
|
||||
double gain = 0.0;
|
||||
};
|
||||
|
||||
struct NoteData {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using Xybrid::UI::LayoutGadget;
|
||||
|
||||
#include "ui/patchboard/nodeobject.h"
|
||||
#include "ui/patchboard/nodeuiscene.h"
|
||||
|
||||
namespace Xybrid::UI {
|
||||
class LayoutSpacerGadget : public Gadget {
|
||||
|
@ -51,6 +52,13 @@ LayoutGadget::LayoutGadget(NodeObject* parent, bool vertical) : LayoutGadget(par
|
|||
});
|
||||
}
|
||||
|
||||
LayoutGadget::LayoutGadget(NodeUIScene* parent, bool vertical) : LayoutGadget(static_cast<QGraphicsItem*>(nullptr), vertical) {
|
||||
QObject::connect(parent, &NodeUIScene::finalized, this, [this] {
|
||||
updateGeometry();
|
||||
});
|
||||
parent->addItem(this);
|
||||
}
|
||||
|
||||
LayoutGadget* LayoutGadget::addSpacer() { new LayoutSpacerGadget(this); return this; }
|
||||
|
||||
void LayoutGadget::updateGeometry() {
|
||||
|
@ -74,3 +82,7 @@ void LayoutGadget::updateGeometry() {
|
|||
}
|
||||
|
||||
QRectF LayoutGadget::boundingRect() const { return { QPointF(), size }; }
|
||||
|
||||
void LayoutGadget::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget*) {
|
||||
if (drawPanel) NodeObject::drawPanel(painter, opt, boundingRect().adjusted(-panelMargin, -panelMargin, panelMargin, panelMargin));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace Xybrid::UI {
|
||||
class NodeObject;
|
||||
class NodeUIScene;
|
||||
class LayoutGadget : public Gadget {
|
||||
QSizeF size;
|
||||
|
||||
|
@ -19,9 +20,12 @@ namespace Xybrid::UI {
|
|||
qreal bias = 0.5;
|
||||
|
||||
bool vertical = false;
|
||||
bool drawPanel = false;
|
||||
qreal panelMargin = 6;
|
||||
|
||||
LayoutGadget(QGraphicsItem* parent = nullptr, bool vertical = false);
|
||||
LayoutGadget(NodeObject* parent, bool vertical = false);
|
||||
LayoutGadget(NodeUIScene* parent, bool vertical = false);
|
||||
~LayoutGadget() override = default;
|
||||
|
||||
inline LayoutGadget* setMetrics(qreal margin = -1, qreal spacing = -1, qreal bias = -1) {
|
||||
|
@ -30,11 +34,17 @@ namespace Xybrid::UI {
|
|||
if (bias >= 0) this->bias = std::clamp(bias, 0.0, 1.0);
|
||||
return this;
|
||||
}
|
||||
inline LayoutGadget* setPanel(bool draw, qreal margin = 6) {
|
||||
drawPanel = draw;
|
||||
panelMargin = margin;
|
||||
return this;
|
||||
}
|
||||
|
||||
LayoutGadget* addSpacer();
|
||||
|
||||
void updateGeometry() override;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,7 +29,14 @@ NodeUIScene::NodeUIScene(QGraphicsView* v, const std::shared_ptr<Xybrid::Data::N
|
|||
connect(view->horizontalScrollBar(), &QScrollBar::rangeChanged, this, &NodeUIScene::queueResize);
|
||||
connect(view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &NodeUIScene::queueResize);
|
||||
|
||||
autoResize();
|
||||
// force full redraw to eliminate graphical glitches
|
||||
connect(this, &QGraphicsScene::changed, this, [this] { update(); });
|
||||
|
||||
// queue up final setup in event loop; this should happen after code surrounding creation but before display
|
||||
QMetaObject::invokeMethod(this, [this] {
|
||||
emit finalized(); // emit before display
|
||||
autoResize();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
NodeUIScene::~NodeUIScene() {
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace Xybrid::UI {
|
|||
template<typename T> inline T* makeStateObject() { auto o = std::make_shared<T>(); stateObject = o; return o.get(); }
|
||||
|
||||
signals:
|
||||
void finalized();
|
||||
void notePreview(int16_t);
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue