NodeUIScene, mostly

portability/boost
zetaPRIME 2019-06-21 17:50:42 -04:00
parent 36e5705377
commit d8c345f7e3
10 changed files with 156 additions and 6 deletions

View File

@ -154,9 +154,9 @@ void AudioEngine::stop() {
}, Qt::QueuedConnection);
}
uint16_t AudioEngine::preview(std::shared_ptr<Project> p, int16_t port, int16_t note, uint16_t nId) {
uint16_t AudioEngine::preview(std::shared_ptr<Project> p, int16_t port, int16_t note, uint16_t nId, Data::Node* node) {
if (note > -1) nId = previewNote_++;
QMetaObject::invokeMethod(this, [this, p, port, note, nId] {
QMetaObject::invokeMethod(this, [this, p, port, note, nId, node] {
if (!p) return;
if (mode == Playing || mode == Rendering || mode == PlaybackMode::Paused) return;
if (project != p || mode != Previewing) {
@ -182,6 +182,9 @@ uint16_t AudioEngine::preview(std::shared_ptr<Project> p, int16_t port, int16_t
if (port >= 0 && port <= 255 && (note > -1 || note < -3)) previewPort_ = static_cast<uint8_t>(port); // assign port if valid (and note on)
if (note < -3) return; // invalid note (port is set before it so that setting the port can be a separate action)
if (node && node->project == p.get()) previewNode = node;
else previewNode = nullptr;
// assemble message
size_t bi = buf.size();
buf.resize(bi+5);
@ -310,8 +313,10 @@ void AudioEngine::nextTick() {
if (!queueValid) buildQueue();
// TODO: send previewing commands
if (auto p = std::static_pointer_cast<CommandPort>(project->rootGraph->port(Port::Input, Port::Command, previewPort_)); p) {
// send previewing commands
auto pnode = previewNode;
if (!pnode) pnode = project->rootGraph.get();
if (auto p = std::static_pointer_cast<CommandPort>(pnode->port(Port::Input, Port::Command, previewPort_)); p) {
p->push(buf);
}
buf.clear();

View File

@ -82,6 +82,7 @@ namespace Xybrid::Audio {
uint8_t previewPort_ = 0;
uint16_t previewNote_ = 0;
Data::Node* previewNode = nullptr;
// playback timing and position
double tempo = 140.0;
@ -101,7 +102,7 @@ namespace Xybrid::Audio {
inline constexpr const std::shared_ptr<Data::Project>& playingProject() const { return project; }
void play(std::shared_ptr<Data::Project>, int fromPos = -1);
void stop();
uint16_t preview(std::shared_ptr<Data::Project>, int16_t port, int16_t note, uint16_t nId = 0);
uint16_t preview(std::shared_ptr<Data::Project>, int16_t port, int16_t note, uint16_t nId = 0, Data::Node* node = nullptr);
inline uint8_t previewPort() const { return previewPort_; }
inline void invalidateQueue(Data::Project* p) { if (p == project.get()) queueValid = false; }

View File

@ -22,6 +22,7 @@ class QCborMap;
namespace Xybrid::UI {
class NodeObject;
class PortObject;
class NodeUIScene;
}
namespace Xybrid::Config {
@ -132,6 +133,7 @@ namespace Xybrid::Data {
virtual void onGadgetCreated() { }
virtual void drawCustomChrome(QPainter*, const QStyleOptionGraphicsItem*) { }
virtual void initUI(UI::NodeUIScene*) { }
virtual void onRename() { }
virtual void onUnparent(std::shared_ptr<Graph>) { }

View File

@ -33,6 +33,7 @@ using Xybrid::MainWindow;
#include "ui/patterneditoritemdelegate.h"
#include "ui/patchboard/patchboardscene.h"
#include "ui/patchboard/nodeuiscene.h"
#include "ui/samplelistmodel.h"
@ -55,6 +56,7 @@ using Xybrid::UI::PatternEditorModel;
using Xybrid::UI::PatternEditorItemDelegate;
using Xybrid::UI::PatchboardScene;
using Xybrid::UI::NodeUIScene;
using Xybrid::UI::SampleListModel;
@ -358,6 +360,15 @@ MainWindow::MainWindow(QWidget *parent) :
openGraph(gg);
});
});
connect(socket, &UISocket::openNodeUI, this, [this](Node* n) {
if (!n) return;
auto nn = n->shared_from_this();
QString name = nn->name;
if (name.isEmpty()) name = nn->pluginName();
ui->patchboardBreadcrumbs->push(name, this, [this, nn] {
openNodeUI(nn);
});
});
// and from audio engine
connect(audioEngine, &AudioEngine::playbackModeChanged, this, [this, undoAction, redoAction] {
@ -578,6 +589,15 @@ void MainWindow::openGraph(const std::shared_ptr<Data::Graph>& g) {
QScroller::scroller(ui->patchboardView)->scrollTo(scrollPt, 1);
}
void MainWindow::openNodeUI(const std::shared_ptr<Data::Node>& n) {
if (!n) return;
delete ui->patchboardView->scene();
ui->patchboardView->setScene(new NodeUIScene(ui->patchboardView, n));
QPointF scrollPt(0.0, 0.0);
QScroller::scroller(ui->patchboardView)->scrollTo(scrollPt, 0);
QScroller::scroller(ui->patchboardView)->scrollTo(scrollPt, 1);
}
void MainWindow::openPatternProperties(const std::shared_ptr<Xybrid::Data::Pattern>& p) {
if (!p || p->project != project.get()) return;
auto dlg = new QDialog(this);

View File

@ -13,6 +13,7 @@ namespace Ui {
}
namespace Xybrid {
namespace Data { class Node; }
class MainWindow : public QMainWindow {
friend class Data::Graph;
Q_OBJECT
@ -36,6 +37,7 @@ namespace Xybrid {
void selectSampleForEditing(std::shared_ptr<Data::Sample>);
void openGraph(const std::shared_ptr<Data::Graph>&);
void openNodeUI(const std::shared_ptr<Data::Node>&);
void openPatternProperties(const std::shared_ptr<Data::Pattern>&);

View File

@ -20,6 +20,9 @@ using namespace Xybrid::Audio;
#include "ui/gadgets/knobgadget.h"
using namespace Xybrid::UI;
#include "ui/patchboard/nodeuiscene.h"
#include "uisocket.h"
#include <cmath>
#include <QDebug>
@ -133,3 +136,25 @@ void BeatPad::onGadgetCreated() {
//
}
void BeatPad::onDoubleClick() { emit project->socket->openNodeUI(this); }
void BeatPad::initUI(NodeUIScene* scene) {
//scene->addItem()
{
KnobGadget* k;
k = new KnobGadget(nullptr);
k->setPos(32, 32);
k->min = 0;
k->max = 99999;
k->step = 1;
k->stepPx = KnobGadget::BigStep;
k->bind(x);
//k->fText = wavetxt;
k->setLabel("Bananagram.");
scene->addItem(k);
}
}

View File

@ -42,9 +42,11 @@ namespace Xybrid::Instruments {
//void onParent(std::shared_ptr<Data::Graph>) override;
void onGadgetCreated() override;
//void onDoubleClick() override;
//void drawCustomChrome(QPainter*, const QStyleOptionGraphicsItem*) override;
void onDoubleClick() override;
void initUI(UI::NodeUIScene*) override;
};
}

View File

@ -0,0 +1,56 @@
#include "nodeuiscene.h"
using Xybrid::UI::NodeUIScene;
#include "data/project.h"
#include "data/node.h"
using namespace Xybrid::Data;
#include "audio/audioengine.h"
using namespace Xybrid::Audio;
#include "util/keys.h"
#include "config/colorscheme.h"
#include <QPainter>
#include <QKeyEvent>
NodeUIScene::NodeUIScene(QGraphicsView* view, const std::shared_ptr<Xybrid::Data::Node>& node) : QGraphicsScene(view), node(node) {
node->initUI(this);
}
void NodeUIScene::drawBackground(QPainter* p, const QRectF& rect) {
p->fillRect(rect, Config::colorScheme.patternBg);
}
void NodeUIScene::keyPressEvent(QKeyEvent* e) {
QGraphicsScene::keyPressEvent(e);
if (!e->isAccepted() && !e->isAutoRepeat()) {
auto note = Util::keyToNote(e->key());
if (note >= 0) {
if (e->modifiers() & Qt::Modifier::SHIFT) note += 24;
startPreview(Util::unshiftedKey(e->key()), note);
}
}
}
void NodeUIScene::keyReleaseEvent(QKeyEvent* e) {
QGraphicsScene::keyReleaseEvent(e);
if (!e->isAccepted() && !e->isAutoRepeat()) stopPreview(Util::unshiftedKey(e->key()));
}
void NodeUIScene::startPreview(int key, int16_t note) {
stopPreview(key); // end current preview first, if applicable
auto p = node->project->shared_from_this();
previewKey[key] = {audioEngine->previewPort(), audioEngine->preview(p, 0, note, 0, node.get())};
}
void NodeUIScene::stopPreview(int key) {
if (auto k = previewKey.find(key); k != previewKey.end()) {
auto p = node->project->shared_from_this();
//audioEngine->preview(p, k->second[0], k->second[1], false);
audioEngine->preview(p, k->second.first, -2, k->second.second, node.get());
previewKey.erase(k);
}
}

View File

@ -0,0 +1,35 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <QGraphicsScene>
#include <QGraphicsView>
class QShortcut;
namespace Xybrid::Data { class Node; }
namespace Xybrid::UI {
class NodeUIScene : public QGraphicsScene {
std::shared_ptr<Data::Node> node;
QGraphicsView* view;
std::unordered_map<int, std::pair<int16_t, uint16_t>> previewKey;
void startPreview(int, int16_t);
void stopPreview(int);
//QShortcut* shortcut(QKeySequence);
public:
NodeUIScene(QGraphicsView* view, const std::shared_ptr<Data::Node>& node);
~NodeUIScene() override = default;
void drawBackground(QPainter*, const QRectF&) override;
//void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override;
void keyPressEvent(QKeyEvent*) override;
void keyReleaseEvent(QKeyEvent*) override;
};
}

View File

@ -8,6 +8,7 @@ namespace Xybrid::Data {
class Project;
class Pattern;
class Graph;
class Node;
}
namespace Xybrid {
@ -24,5 +25,6 @@ namespace Xybrid {
void rowUpdated(Data::Pattern* pattern, int channel, int row);
void openGraph(Data::Graph*);
void openNodeUI(Data::Node*);
};
}