From bc8c433e4740fd4e8822352efada1eb131b62e34 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 11 Dec 2024 01:16:06 +0100 Subject: [PATCH] Fun with config nodes that modifiy other config nodes. Circular connections lead to a crash. --- src/canvas.h | 1 + src/config-node.h | 122 ++++++++++++++++++++++++++++---------- src/datatypes.h | 1 + src/interaction-manager.h | 8 ++- src/midi-node.h | 58 +++++++++++++++--- src/state.h | 4 +- src/ui.h | 9 +++ 7 files changed, 162 insertions(+), 41 deletions(-) diff --git a/src/canvas.h b/src/canvas.h index be43a79..a871080 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -92,6 +92,7 @@ namespace VISEQ::APP::CANVAS { } } if(state->selection.width > 0 || state->selection.height > 0) DrawRectangleLines(state->selection.x, state->selection.y, state->selection.width, state->selection.height, (Color){150,150,150,150}); + } }; } diff --git a/src/config-node.h b/src/config-node.h index 207529f..6fe3129 100644 --- a/src/config-node.h +++ b/src/config-node.h @@ -15,7 +15,7 @@ namespace VISEQ::GRAPH::NODES { ConfigNode() {std::cout << "ConfigNode Constructor std" << std::endl;} ConfigNode(Vec2Df position) : Node(position) {} - std::shared_ptr getPtr(){ + std::shared_ptr getPtr() { return std::static_pointer_cast(shared_from_this()); } @@ -39,28 +39,63 @@ namespace VISEQ::GRAPH::NODES { mode = _mode; } - MIDI::MidiNote getNotes(){ - return midiNote; + MIDI::MidiNote getNotes() const { + MIDI::MidiNote cNote; + for(auto cn : getConnectedConfigNodes()){ + cNote += cn.lock()->getNotes(); + } + return midiNote + cNote; } - - MIDI::MidiCC getCC(){ - return midiCC; + + MIDI::MidiCC getCC() const { + MIDI::MidiCC cCC; + for(auto cn : getConnectedConfigNodes()){ + cCC += cn.lock()->getCC(); + } + return midiCC + cCC; } - - MIDI::MidiPC getPC(){ - return midiPC; + + MIDI::MidiPC getPC() const { + MIDI::MidiPC cPC; + for(auto cn : getConnectedConfigNodes()){ + cPC += cn.lock()->getPC(); + } + return midiPC + cPC; } - - MIDI::MidiPitchBend getPitchBend(){ - return midiPitchBend; + + MIDI::MidiPitchBend getPitchBend() const { + MIDI::MidiPitchBend cPitchBend; + for(auto cn : getConnectedConfigNodes()){ + cPitchBend += cn.lock()->getPitchBend(); + } + return midiPitchBend + cPitchBend; } - - MIDI::MidiPolyPressure getPolyPressure(){ - return midiPolyPressure; + + MIDI::MidiAftertouch getAftertouch() const { + MIDI::MidiAftertouch cAftertouch; + for(auto cn : getConnectedConfigNodes()){ + cAftertouch += cn.lock()->getAftertouch(); + } + return midiAftertouch + cAftertouch; } - - MIDI::MidiAftertouch getAftertouch(){ - return midiAftertouch; + + MIDI::MidiPolyPressure getPolyPressure() const { + MIDI::MidiPolyPressure cPolyPressure; + for(auto cn : getConnectedConfigNodes()){ + cPolyPressure += cn.lock()->getPolyPressure(); + } + return midiPolyPressure + cPolyPressure; + } + + std::vector> getConnectedConfigNodes() const { + auto config_conns = connections | RANGE_FILTER([](EDGES::SPTR_Edge c){ return c->start.lock()->getNodeType() == NodeType::CONFIGNODE || c->end.lock()->getNodeType() == NodeType::CONFIGNODE;}) | std::ranges::to>>(); + std::vector> config_nodes; + for(auto e : config_conns){ + if(e->start.lock().get() != this && e->start.lock()->getNodeType() == NodeType::CONFIGNODE) config_nodes.push_back(std::dynamic_pointer_cast(e->start.lock())); + //if(e->end.lock().get() != this && e->end.lock()->getNodeType() == NodeType::CONFIGNODE) config_nodes.push_back(std::dynamic_pointer_cast(e->end.lock())); + } + /*std::cout << "id: " << id << " n cn: " << config_nodes.size() << std::endl;*/ + return config_nodes; } void update() override { @@ -148,34 +183,61 @@ namespace VISEQ::GRAPH::NODES { int offset_gate = 0; switch(mode){ case 0: - value = (float)midiNote.channel; + value = (float)getNotes().channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); - DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; case 1: - value = (float)midiCC.channel; + value = (float)getCC().channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); - DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; case 2: - value = (float)midiPitchBend.channel; + value = (float)getPC().channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); - DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break; + case 3: + value = (float)getPitchBend().channel; + offset_gate = MeasureText(std::format("{}", value).c_str(), 12); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break; + case 4: + value = (float)getAftertouch().channel; + offset_gate = MeasureText(std::format("{}", value).c_str(), 12); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break; + case 5: + value = (float)getPolyPressure().channel; + offset_gate = MeasureText(std::format("{}", value).c_str(), 12); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; } } else { switch(mode){ case 0:{ - int offset = MeasureText(std::format("{:+}", midiNote.note).c_str(), 12); - DrawText(std::format("{:+}", midiNote.note).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", getNotes().note).c_str(), 12); + DrawText(std::format("{:+}", getNotes().note).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} case 1:{ - int offset = MeasureText(std::format("{:+}", midiCC.value).c_str(), 12); - DrawText(std::format("{:+}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", getCC().value).c_str(), 12); + DrawText(std::format("{:+}", getCC().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} case 2:{ - int offset = MeasureText(std::format("{:+}", midiPitchBend.value).c_str(), 12); - DrawText(std::format("{:+}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", getPC().value).c_str(), 12); + DrawText(std::format("{:+}", getPC().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break;} + case 3:{ + int offset = MeasureText(std::format("{:+}", getPitchBend().value).c_str(), 12); + DrawText(std::format("{:+}", getPitchBend().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break;} + case 4:{ + int offset = MeasureText(std::format("{:+}", getAftertouch().value).c_str(), 12); + DrawText(std::format("{:+}", getAftertouch().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); + break;} + case 5:{ + int offset = MeasureText(std::format("{:+}", getPolyPressure().value).c_str(), 12); + DrawText(std::format("{:+}", getPolyPressure().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} } } diff --git a/src/datatypes.h b/src/datatypes.h index e9bbc3e..493b3ef 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -4,6 +4,7 @@ #define _USE_MATH_DEFINES #endif +#define VS_COLOR_BLACK (Color){20, 20, 20, 255} #define VS_COLOR_DARKGREY (Color){46, 46, 46, 255} #define VS_COLOR_LIGHTGREY (Color){100, 100, 100, 255} #define VS_COLOR_WHITE (Color){214, 214, 214, 255} diff --git a/src/interaction-manager.h b/src/interaction-manager.h index 57a5062..cd05add 100644 --- a/src/interaction-manager.h +++ b/src/interaction-manager.h @@ -81,8 +81,12 @@ namespace VISEQ::INTERACTION{ removeNodes(gm->getSelection()); } - if(IsKeyPressed(KEY_TAB)) { - state->node_mode = (state->node_mode + 1) % 3; + if(!KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) { + state->node_mode = (state->node_mode + 1) % 6; + } + + if(KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) { + state->node_mode -= state->node_mode > 0 ? 1 : -5; } } diff --git a/src/midi-node.h b/src/midi-node.h index 65d0516..9bdf11f 100644 --- a/src/midi-node.h +++ b/src/midi-node.h @@ -23,10 +23,10 @@ namespace VISEQ::GRAPH::NODES { private: MIDI::MidiNote midiNote; MIDI::MidiCC midiCC; + MIDI::MidiPC midiPC; MIDI::MidiPitchBend midiPitchBend; MIDI::MidiAftertouch midiAftertouch; MIDI::MidiPolyPressure midiPolyPressure; - MIDI::MidiPC midiPC; std::vector channelButtons; @@ -166,11 +166,29 @@ namespace VISEQ::GRAPH::NODES { if(midiCC.control > 127 ) midiCC.control = 0; } + void modMidiPC(int incr){ + midiPC.program += incr; + if(midiPC.program < 0 ) midiPC.program = 127; + if(midiPC.program > 127 ) midiPC.program = 0; + } + void modMidiPitchBend(int incr){ midiPitchBend.value += incr; if(midiPitchBend.value < 0 ) midiPitchBend.value = 0; if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; } + + void modMidiAftertouch(int incr){ + midiAftertouch.value += incr; + if(midiAftertouch.value < 0 ) midiAftertouch.value = 0; + if(midiAftertouch.value > 127 ) midiAftertouch.value = 127; + } + + void modMidiPolyPressure(int incr){ + midiPolyPressure.value += incr; + if(midiPolyPressure.value < 0 ) midiPolyPressure.value = 0; + if(midiPolyPressure.value > 127 ) midiPolyPressure.value = 127; + } void interact(){ float wheel = GetMouseWheelMove(); @@ -184,8 +202,17 @@ namespace VISEQ::GRAPH::NODES { modMidiCC(wheel); break;} case 2:{ + modMidiPC(wheel); + break;} + case 3:{ modMidiPitchBend(wheel); break;} + case 4:{ + modMidiAftertouch(wheel); + break;} + case 5:{ + modMidiPolyPressure(wheel); + break;} }; } else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) { midiNote.velocity += wheel; @@ -204,11 +231,28 @@ namespace VISEQ::GRAPH::NODES { if(midiCC.value > 127 ) midiCC.value = 127; break;} case 2:{ + midiPC.value += wheel; + if(midiPC.value < 0 ) midiPC.value = 0; + if(midiPC.value > 127 ) midiPC.value = 127; + break;} + case 3:{ float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f); midiPitchBend.value += incr; if(midiPitchBend.value < 0 ) midiPitchBend.value = 0; if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; break;} + case 4:{ + float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f); + midiAftertouch.value += incr; + if(midiAftertouch.value < 0 ) midiAftertouch.value = 0; + if(midiAftertouch.value > 127 ) midiAftertouch.value = 127; + break;} + case 5:{ + float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f); + midiPolyPressure.value += incr; + if(midiPolyPressure.value < 0 ) midiPolyPressure.value = 0; + if(midiPolyPressure.value > 127 ) midiPolyPressure.value = 127; + break;} }; } } @@ -285,32 +329,32 @@ namespace VISEQ::GRAPH::NODES { case 0: value = (float)getNotes().gate/1000.0f; offset_gate = MeasureText(std::format("{:.2f}", value).c_str(), 12); - DrawText(std::format("{:.2f}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{:.2f}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; case 1: value = (float)getCC().value; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); - DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; case 2: value = (float)getPitchBend().value; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); - DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break; } } else { switch(mode){ case 0:{ int offset = MeasureText(MIDI::Notes[(int)getNotes().note].c_str(), 12); - DrawText(MIDI::Notes[getNotes().note].c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + DrawText(MIDI::Notes[getNotes().note].c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} case 1:{ int offset = MeasureText(std::format("{}", getCC().control).c_str(), 12); - DrawText(std::format("{}", getCC().control).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}", getCC().control).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} case 2:{ int offset = MeasureText(std::format("{}", getPitchBend().value).c_str(), 12); - DrawText(std::format("{}", getPitchBend().value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + DrawText(std::format("{}", getPitchBend().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK ); break;} } } diff --git a/src/state.h b/src/state.h index fb5208a..53a74fd 100644 --- a/src/state.h +++ b/src/state.h @@ -129,9 +129,9 @@ namespace VISEQ::APP{ keys_released.shift = IsKeyReleased(KEY_LEFT_SHIFT) || IsKeyReleased(KEY_RIGHT_SHIFT); keys_released.alt = IsKeyReleased(KEY_LEFT_ALT) || IsKeyReleased(KEY_RIGHT_ALT); - screen_mouse = mouse_pos; + screen_mouse = {round(mouse_pos.x), round(mouse_pos.y)}; raw_mouse = {GetMousePosition().x, GetMousePosition().y}; - mod_mouse = mouse_pos; + mod_mouse = {round(mouse_pos.x), round(mouse_pos.y)}; if(keys_down.ctrl) { mod_mouse.x = round(mouse_pos.x / settings.grid) * settings.grid; diff --git a/src/ui.h b/src/ui.h index a25bbeb..61c0300 100644 --- a/src/ui.h +++ b/src/ui.h @@ -96,6 +96,15 @@ namespace VISEQ::APP::UI{ } DrawText(std::format("{}", gm->getNodesSize()).c_str(), 20, state->settings.height - 70, 15, VS_COLOR_WHITE); DrawFPS(20, state->settings.height - 30); + + std::string shorts[6] = {"NT","CC","PC","PB","AT","PP"}; + for(int i = 0; i < 6; ++i){ + Color col = VS_COLOR_GREEN; + if(state->node_mode == i) col = VS_COLOR_SUN; + Vec2Df pos = {state->settings.width - (6.0f*75.0f) + i*75.0f, state->settings.height - 75.0f}; + DrawCircleV(pos, 30.0f, col); + DrawCenteredText(shorts[i], pos, 20, VS_COLOR_BLACK); + } } void DrawCenteredText(std::string text, Vec2Df position, int size, Color color){