Fun with config nodes that modifiy other config nodes. Circular connections lead to a crash.

This commit is contained in:
Sebastian
2024-12-11 01:16:06 +01:00
parent 456528f230
commit bc8c433e47
7 changed files with 162 additions and 41 deletions
+1
View File
@@ -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}); 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});
} }
}; };
} }
+87 -25
View File
@@ -15,7 +15,7 @@ namespace VISEQ::GRAPH::NODES {
ConfigNode() {std::cout << "ConfigNode Constructor std" << std::endl;} ConfigNode() {std::cout << "ConfigNode Constructor std" << std::endl;}
ConfigNode(Vec2Df position) : Node(position) {} ConfigNode(Vec2Df position) : Node(position) {}
std::shared_ptr<ConfigNode> getPtr(){ std::shared_ptr<ConfigNode> getPtr() {
return std::static_pointer_cast<ConfigNode>(shared_from_this()); return std::static_pointer_cast<ConfigNode>(shared_from_this());
} }
@@ -39,28 +39,63 @@ namespace VISEQ::GRAPH::NODES {
mode = _mode; mode = _mode;
} }
MIDI::MidiNote getNotes(){ MIDI::MidiNote getNotes() const {
return midiNote; MIDI::MidiNote cNote;
for(auto cn : getConnectedConfigNodes()){
cNote += cn.lock()->getNotes();
}
return midiNote + cNote;
} }
MIDI::MidiCC getCC(){ MIDI::MidiCC getCC() const {
return midiCC; MIDI::MidiCC cCC;
for(auto cn : getConnectedConfigNodes()){
cCC += cn.lock()->getCC();
}
return midiCC + cCC;
} }
MIDI::MidiPC getPC(){ MIDI::MidiPC getPC() const {
return midiPC; MIDI::MidiPC cPC;
for(auto cn : getConnectedConfigNodes()){
cPC += cn.lock()->getPC();
}
return midiPC + cPC;
} }
MIDI::MidiPitchBend getPitchBend(){ MIDI::MidiPitchBend getPitchBend() const {
return midiPitchBend; MIDI::MidiPitchBend cPitchBend;
for(auto cn : getConnectedConfigNodes()){
cPitchBend += cn.lock()->getPitchBend();
}
return midiPitchBend + cPitchBend;
} }
MIDI::MidiPolyPressure getPolyPressure(){ MIDI::MidiAftertouch getAftertouch() const {
return midiPolyPressure; MIDI::MidiAftertouch cAftertouch;
for(auto cn : getConnectedConfigNodes()){
cAftertouch += cn.lock()->getAftertouch();
}
return midiAftertouch + cAftertouch;
} }
MIDI::MidiAftertouch getAftertouch(){ MIDI::MidiPolyPressure getPolyPressure() const {
return midiAftertouch; MIDI::MidiPolyPressure cPolyPressure;
for(auto cn : getConnectedConfigNodes()){
cPolyPressure += cn.lock()->getPolyPressure();
}
return midiPolyPressure + cPolyPressure;
}
std::vector<std::weak_ptr<ConfigNode>> 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<std::shared_ptr<EDGES::Edge>>>();
std::vector<std::weak_ptr<ConfigNode>> 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<ConfigNode>(e->start.lock()));
//if(e->end.lock().get() != this && e->end.lock()->getNodeType() == NodeType::CONFIGNODE) config_nodes.push_back(std::dynamic_pointer_cast<ConfigNode>(e->end.lock()));
}
/*std::cout << "id: " << id << " n cn: " << config_nodes.size() << std::endl;*/
return config_nodes;
} }
void update() override { void update() override {
@@ -148,34 +183,61 @@ namespace VISEQ::GRAPH::NODES {
int offset_gate = 0; int offset_gate = 0;
switch(mode){ switch(mode){
case 0: case 0:
value = (float)midiNote.channel; value = (float)getNotes().channel;
offset_gate = MeasureText(std::format("{}", value).c_str(), 12); 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; break;
case 1: case 1:
value = (float)midiCC.channel; value = (float)getCC().channel;
offset_gate = MeasureText(std::format("{}", value).c_str(), 12); 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; break;
case 2: case 2:
value = (float)midiPitchBend.channel; value = (float)getPC().channel;
offset_gate = MeasureText(std::format("{}", value).c_str(), 12); 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; break;
} }
} else { } else {
switch(mode){ switch(mode){
case 0:{ case 0:{
int offset = MeasureText(std::format("{:+}", midiNote.note).c_str(), 12); int offset = MeasureText(std::format("{:+}", getNotes().note).c_str(), 12);
DrawText(std::format("{:+}", midiNote.note).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); DrawText(std::format("{:+}", getNotes().note).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK );
break;} break;}
case 1:{ case 1:{
int offset = MeasureText(std::format("{:+}", midiCC.value).c_str(), 12); int offset = MeasureText(std::format("{:+}", getCC().value).c_str(), 12);
DrawText(std::format("{:+}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); DrawText(std::format("{:+}", getCC().value).c_str(), position.x-offset/2.0f, position.y-5, 12, VS_COLOR_BLACK );
break;} break;}
case 2:{ case 2:{
int offset = MeasureText(std::format("{:+}", midiPitchBend.value).c_str(), 12); int offset = MeasureText(std::format("{:+}", getPC().value).c_str(), 12);
DrawText(std::format("{:+}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); 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;} break;}
} }
} }
+1
View File
@@ -4,6 +4,7 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#endif #endif
#define VS_COLOR_BLACK (Color){20, 20, 20, 255}
#define VS_COLOR_DARKGREY (Color){46, 46, 46, 255} #define VS_COLOR_DARKGREY (Color){46, 46, 46, 255}
#define VS_COLOR_LIGHTGREY (Color){100, 100, 100, 255} #define VS_COLOR_LIGHTGREY (Color){100, 100, 100, 255}
#define VS_COLOR_WHITE (Color){214, 214, 214, 255} #define VS_COLOR_WHITE (Color){214, 214, 214, 255}
+6 -2
View File
@@ -81,8 +81,12 @@ namespace VISEQ::INTERACTION{
removeNodes(gm->getSelection()); removeNodes(gm->getSelection());
} }
if(IsKeyPressed(KEY_TAB)) { if(!KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
state->node_mode = (state->node_mode + 1) % 3; state->node_mode = (state->node_mode + 1) % 6;
}
if(KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
state->node_mode -= state->node_mode > 0 ? 1 : -5;
} }
} }
+51 -7
View File
@@ -23,10 +23,10 @@ namespace VISEQ::GRAPH::NODES {
private: private:
MIDI::MidiNote midiNote; MIDI::MidiNote midiNote;
MIDI::MidiCC midiCC; MIDI::MidiCC midiCC;
MIDI::MidiPC midiPC;
MIDI::MidiPitchBend midiPitchBend; MIDI::MidiPitchBend midiPitchBend;
MIDI::MidiAftertouch midiAftertouch; MIDI::MidiAftertouch midiAftertouch;
MIDI::MidiPolyPressure midiPolyPressure; MIDI::MidiPolyPressure midiPolyPressure;
MIDI::MidiPC midiPC;
std::vector<APP::UI::ButtonRound> channelButtons; std::vector<APP::UI::ButtonRound> channelButtons;
@@ -166,12 +166,30 @@ namespace VISEQ::GRAPH::NODES {
if(midiCC.control > 127 ) midiCC.control = 0; 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){ void modMidiPitchBend(int incr){
midiPitchBend.value += incr; midiPitchBend.value += incr;
if(midiPitchBend.value < 0 ) midiPitchBend.value = 0; if(midiPitchBend.value < 0 ) midiPitchBend.value = 0;
if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; 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(){ void interact(){
float wheel = GetMouseWheelMove(); float wheel = GetMouseWheelMove();
@@ -184,8 +202,17 @@ namespace VISEQ::GRAPH::NODES {
modMidiCC(wheel); modMidiCC(wheel);
break;} break;}
case 2:{ case 2:{
modMidiPC(wheel);
break;}
case 3:{
modMidiPitchBend(wheel); modMidiPitchBend(wheel);
break;} break;}
case 4:{
modMidiAftertouch(wheel);
break;}
case 5:{
modMidiPolyPressure(wheel);
break;}
}; };
} else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) { } else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) {
midiNote.velocity += wheel; midiNote.velocity += wheel;
@@ -204,11 +231,28 @@ namespace VISEQ::GRAPH::NODES {
if(midiCC.value > 127 ) midiCC.value = 127; if(midiCC.value > 127 ) midiCC.value = 127;
break;} break;}
case 2:{ 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); float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f);
midiPitchBend.value += incr; midiPitchBend.value += incr;
if(midiPitchBend.value < 0 ) midiPitchBend.value = 0; if(midiPitchBend.value < 0 ) midiPitchBend.value = 0;
if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383;
break;} 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: case 0:
value = (float)getNotes().gate/1000.0f; value = (float)getNotes().gate/1000.0f;
offset_gate = MeasureText(std::format("{:.2f}", value).c_str(), 12); 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; break;
case 1: case 1:
value = (float)getCC().value; value = (float)getCC().value;
offset_gate = MeasureText(std::format("{}", value).c_str(), 12); 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; break;
case 2: case 2:
value = (float)getPitchBend().value; value = (float)getPitchBend().value;
offset_gate = MeasureText(std::format("{}", value).c_str(), 12); 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; break;
} }
} else { } else {
switch(mode){ switch(mode){
case 0:{ case 0:{
int offset = MeasureText(MIDI::Notes[(int)getNotes().note].c_str(), 12); 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;} break;}
case 1:{ case 1:{
int offset = MeasureText(std::format("{}", getCC().control).c_str(), 12); 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;} break;}
case 2:{ case 2:{
int offset = MeasureText(std::format("{}", getPitchBend().value).c_str(), 12); 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;} break;}
} }
} }
+2 -2
View File
@@ -129,9 +129,9 @@ namespace VISEQ::APP{
keys_released.shift = IsKeyReleased(KEY_LEFT_SHIFT) || IsKeyReleased(KEY_RIGHT_SHIFT); keys_released.shift = IsKeyReleased(KEY_LEFT_SHIFT) || IsKeyReleased(KEY_RIGHT_SHIFT);
keys_released.alt = IsKeyReleased(KEY_LEFT_ALT) || IsKeyReleased(KEY_RIGHT_ALT); 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}; raw_mouse = {GetMousePosition().x, GetMousePosition().y};
mod_mouse = mouse_pos; mod_mouse = {round(mouse_pos.x), round(mouse_pos.y)};
if(keys_down.ctrl) { if(keys_down.ctrl) {
mod_mouse.x = round(mouse_pos.x / settings.grid) * settings.grid; mod_mouse.x = round(mouse_pos.x / settings.grid) * settings.grid;
+9
View File
@@ -96,6 +96,15 @@ namespace VISEQ::APP::UI{
} }
DrawText(std::format("{}", gm->getNodesSize()).c_str(), 20, state->settings.height - 70, 15, VS_COLOR_WHITE); DrawText(std::format("{}", gm->getNodesSize()).c_str(), 20, state->settings.height - 70, 15, VS_COLOR_WHITE);
DrawFPS(20, state->settings.height - 30); 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){ void DrawCenteredText(std::string text, Vec2Df position, int size, Color color){