Working on config nodes. They exist now, but do nothing yet.

This commit is contained in:
Sebastian
2024-12-07 03:44:03 +01:00
parent ade33b0608
commit 36273ba7ac
8 changed files with 247 additions and 105 deletions
+14 -9
View File
@@ -63,16 +63,25 @@ namespace VISEQ::APP {
json graph = json::parse(f); json graph = json::parse(f);
for(auto n : graph.at("gm").at("nodes")){ for(auto n : graph.at("gm").at("nodes")){
gm->addNode(n.template get<std::shared_ptr<MidiNode>>()); std::cout << "object? " << n.is_object() << std::endl;
if(n.is_object()){
std::cout << "nodeType = " << n.at("nodeType").get<int>() << std::endl;
if(n.at("nodeType").get<int>() == NodeType::MIDINODE) gm->addNode(n.template get<std::shared_ptr<MidiNode>>());
if(n.at("nodeType").get<int>() == NodeType::CONFIGNODE) gm->addNode(n.template get<std::shared_ptr<ConfigNode>>());
}
} }
int highest_id = 0; int highest_id = 0;
Node hid; Node hid;
for(auto n : graph.at("gm").at("nodes")){ for(auto n : graph.at("gm").at("nodes")){
MidiNode mn = n.template get<MidiNode>(); std::cout << n << std::endl;
if(mn.id > highest_id) { if(n.is_object()){
highest_id = mn.id; Node mn = n.template get<Node>();
hid = mn; if(mn.id > highest_id) {
highest_id = mn.id;
hid = mn;
}
} }
} }
@@ -89,14 +98,10 @@ namespace VISEQ::APP {
VEC_WPTR_Node start = gm->getNodesByID(start_id); VEC_WPTR_Node start = gm->getNodesByID(start_id);
VEC_WPTR_Node end = gm->getNodesByID(end_id); VEC_WPTR_Node end = gm->getNodesByID(end_id);
// VEC_SPTR_Node start = gm->nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
// VEC_SPTR_Node end = gm->nodes | RANGE_FILTER([end_id](SPTR_Node n){return n->id == end_id;}) | std::ranges::to<VEC_SPTR_Node>();
if(!start.empty() && !end.empty()) { if(!start.empty() && !end.empty()) {
std::cout << std::format("connection {} to {}", start_id, end_id) << std::endl; std::cout << std::format("connection {} to {}", start_id, end_id) << std::endl;
gm->addConnection(start.front(), end.front()); gm->addConnection(start.front(), end.front());
} }
} }
gm->lastEdge().lock()->newId(highest_id); gm->lastEdge().lock()->newId(highest_id);
+90 -36
View File
@@ -9,6 +9,13 @@ namespace VISEQ::GRAPH::NODES {
class ConfigNode : public Node{ class ConfigNode : public Node{
public: public:
ConfigNode() : Node() {std::cout << "ConfigNode Constructor std" << std::endl;}
ConfigNode(Vec2Df position) : Node(position) {}
std::shared_ptr<ConfigNode> getPtr(){
return std::static_pointer_cast<ConfigNode>(shared_from_this());
}
NodeType nodeType = NodeType::CONFIGNODE; NodeType nodeType = NodeType::CONFIGNODE;
MIDI::MidiNote midiNote; MIDI::MidiNote midiNote;
@@ -18,55 +25,110 @@ namespace VISEQ::GRAPH::NODES {
MIDI::MidiPC midiPC; MIDI::MidiPC midiPC;
int mode = 0; int mode = 0;
float radius = 20.0f;
virtual NodeType getNodeType() const override {return nodeType;} virtual NodeType getNodeType() const override {return nodeType;}
int GGate(){
return 0;
}
void update() override {
Node::update();
mode = state->node_mode;
}
void interact(){
float wheel = GetMouseWheelMove();
if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){
switch(state->node_mode){
case 0:{
midiNote.note += wheel;
break;}
case 1:{
midiCC.value += wheel;
break;}
case 2:{
midiPitchBend.value += wheel;
break;}
};
if(midiNote.note < 0 ) midiNote.note = VISEQ::MIDI::Notes.size()-1;
if(midiNote.note >= (int)VISEQ::MIDI::Notes.size()) midiNote.note = 0;
if(midiCC.value < 0 ) midiCC.value = 127;
if(midiCC.value > 127 ) midiCC.value = 0;
if(midiPitchBend.value < 0 ) midiPitchBend.value = 0;
if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383;
} else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) {
} else if(KEYS_DOWN.alt) {
switch(state->node_mode){
case 0:{
midiNote.channel += wheel;
if(midiNote.channel < 0 ) midiNote.channel = 0;
if(midiNote.channel > 15) midiNote.channel = 15;
break;}
case 1:{
midiCC.channel += wheel;
if(midiCC.channel < 0 ) midiCC.channel = 0;
if(midiCC.channel > 15 ) midiCC.channel = 15;
break;}
case 2:{
midiPitchBend.channel += wheel;
if(midiPitchBend.channel < 0 ) midiPitchBend.channel = 0;
if(midiPitchBend.channel > 15 ) midiPitchBend.channel = 15;
break;}
};
}
}
void draw(Vec2Df mouse, Camera2D cam) override { void draw(Vec2Df mouse, Camera2D cam) override {
Node::draw();
if(hovering() || selected) interact();
DrawRing(position, radius, radius+4, 0, 360, 24, (Color){60, 60, 60, 255}); DrawRing(position, radius, radius+4, 0, 360, 24, (Color){60, 60, 60, 255});
DrawRing(position, radius, radius+4, 0.0f - 90.0f, (360.0f/127.0f) * midiNote.velocity - 90.0f, 24, (Color){158, 134, 200, 255});
DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255}); DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255});
float fade = 0;
float midi_gate_map = round((255.f / midiNote.gate) * fade);
Color gate_color = VS_COLOR_GREEN; Color gate_color = VS_COLOR_GREEN;
switch(mode){ switch(mode){
case 0:{ case 0:{
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){180, 210, 115, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE); gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){180, 210, 115 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE);
break;} break;}
case 1:{ case 1:{
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){229, 181, 103, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE); gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){229, 181, 103 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE);
break;} break;}
case 2:{ case 2:{
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){232, 125, 62, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE); gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){232, 125, 62 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE);
break;} break;}
} }
if(!picked_up && !selected && !in_rect && !hovering()) DrawCircle(position.x, position.y, radius, gate_color); if(!picked_up && !selected && !in_selection_rect && !hovering()) DrawCircle(position.x, position.y, radius, gate_color);
if(selected || picked_up || in_rect || hovering()) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255}); if(picked_up || in_selection_rect || hovering()) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255});
if(selected) DrawCircle(position.x, position.y, radius, (Color){255, 153, 187, 255});
if(distributionMode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK); if(distributionMode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK);
if(distributionMode == Distribution::ROUNDROBIN) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_YELLOW); if(distributionMode == Distribution::ROUNDROBIN) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_YELLOW);
if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255}); if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255});
if(IsKeyDown(KEY_LEFT_ALT)){ if(KEYS_DOWN.alt){
float value = 0; float value = 0;
int offset_gate = 0; int offset_gate = 0;
switch(mode){ switch(mode){
case 0: case 0:
value = (float)midiNote.gate/1000.0f; value = (float)midiNote.channel;
offset_gate = MeasureText(std::format("{:.2f}", value).c_str(), 12); offset_gate = MeasureText(std::format("{}", 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("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE );
break; break;
case 1: case 1:
value = (float)midiCC.value; value = (float)midiCC.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, WHITE );
break; break;
case 2: case 2:
value = (float)midiPitchBend.value; value = (float)midiPitchBend.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, WHITE );
break; break;
@@ -74,28 +136,20 @@ namespace VISEQ::GRAPH::NODES {
} else { } else {
switch(mode){ switch(mode){
case 0:{ case 0:{
int offset = MeasureText(MIDI::Notes[(int)midiNote.note].c_str(), 12); int offset = MeasureText(MIDI::Notes[(int)midiNote.note].c_str(), 12);
DrawText(MIDI::Notes[midiNote.note].c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); DrawText(MIDI::Notes[midiNote.note].c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
break;} break;}
case 1:{ case 1:{
int offset = MeasureText(std::format("{}", midiCC.value).c_str(), 12); 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 ); DrawText(std::format("{}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
break;} break;}
case 2:{ case 2:{
int offset = MeasureText(std::format("{}", midiPitchBend.value).c_str(), 12); 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 ); DrawText(std::format("{}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
break;} break;}
} }
} }
Vec2Df connector = position - ((position - mouse)).norm() * (radius + 30);
float opacity = 150.0f - Clamp(position.dist(mouse), 0.0f, 150.0f);
if(hover_connect){
DrawCircle(connector.x, connector.y, 8.0f, (Color){108, 153, 187, 255});
} else {
DrawCircle(connector.x, connector.y, 8.0f, (Color){108, 153, 187, (unsigned char)opacity});
}
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200}); if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
DrawText(std::format("{}", id).c_str(), position.x + 20.0f, position.y + 20.0f, 10, WHITE); DrawText(std::format("{}", id).c_str(), position.x + 20.0f, position.y + 20.0f, 10, WHITE);
} }
-4
View File
@@ -70,10 +70,6 @@ namespace VISEQ::GRAPH {
BASE::Connectable::draw(); BASE::Connectable::draw();
float opacity = 150.0f - Clamp(position.dist(SCREEN_MOUSE), 0.0f, 150.0f); float opacity = 150.0f - Clamp(position.dist(SCREEN_MOUSE), 0.0f, 150.0f);
if(!partner.expired()){
DrawLineV(position, partner.lock()->position, VS_COLOR_RED);
}
if(hovering()){ if(hovering()){
DrawCircle(position.x, position.y, 8.0f, (Color){108, 203, 237, 255}); DrawCircle(position.x, position.y, 8.0f, (Color){108, 203, 237, 255});
} else { } else {
+72 -47
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "config-node.h"
#include "datatypes.h" #include "datatypes.h"
#include "state.h" #include "state.h"
#include "vmath.h" #include "vmath.h"
@@ -20,6 +21,7 @@
#include <iterator> #include <iterator>
#include <map> #include <map>
#include <memory> #include <memory>
#include <ostream>
#include <random> #include <random>
#include <ranges> #include <ranges>
#include <vector> #include <vector>
@@ -64,6 +66,11 @@ namespace VISEQ::GRAPH {
nodes.back()->update(); nodes.back()->update();
} }
void createConfigNode(Vec2Df position){
nodes.emplace_back(std::make_shared<ConfigNode>(position));
nodes.back()->update();
}
void setMidiPortForAll(int number, bool _state){ void setMidiPortForAll(int number, bool _state){
for(auto n : nodes){ for(auto n : nodes){
if(n->getNodeType() == NodeType::MIDINODE) std::dynamic_pointer_cast<MidiNode>(n)->setMidiPort(number, _state); if(n->getNodeType() == NodeType::MIDINODE) std::dynamic_pointer_cast<MidiNode>(n)->setMidiPort(number, _state);
@@ -71,6 +78,7 @@ namespace VISEQ::GRAPH {
} }
void addNode(SPTR_Node node){ void addNode(SPTR_Node node){
std::cout << "added node " << node->id << std::endl;
nodes.insert(nodes.end(), node); nodes.insert(nodes.end(), node);
node->update(); node->update();
} }
@@ -169,6 +177,10 @@ namespace VISEQ::GRAPH {
return nodes.front(); return nodes.front();
} }
WPTR_Node getLastNode(){
return nodes.back();
}
VEC_WPTR_Node getMidiNodes(){ VEC_WPTR_Node getMidiNodes(){
return nodes | RANGE_FILTER([](VISEQ::GRAPH::NODES::SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;}) | std::ranges::to<VEC_WPTR_Node>(); return nodes | RANGE_FILTER([](VISEQ::GRAPH::NODES::SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;}) | std::ranges::to<VEC_WPTR_Node>();
} }
@@ -346,35 +358,6 @@ namespace VISEQ::GRAPH {
Vec2Df v2_position = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (c->end.lock()->radius + c->connector_offset); Vec2Df v2_position = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (c->end.lock()->radius + c->connector_offset);
float v1_v2_distance = v1_position.dist(&v2_position); float v1_v2_distance = v1_position.dist(&v2_position);
float midi_gate_v1 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->start.lock())->GGate(), 1.f, 4.f);
float midi_gate_v2 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->end.lock())->GGate(), 1.f, 4.f);
// Line with small connector circles
Color col = {229, 181, 103, 255};
if(c->GActive()) col = {108, 153, 187, 255};
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, col);
{
float d = c->start.lock()->position.dist(c->end.lock()->position);
std::string frac = MIDI::Fractions.at(std::clamp<int>(round(d/60) - 1, 0, 31));
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
Vector2 text_length_frac = MeasureTextEx(GetFontDefault(), frac.c_str(), 10.0f, 2.0f);
Vec2Df middle_handle = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length.x)*0.5f)/d;
Vec2Df middle_handle_frac = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length_frac.x)*0.5f)/d;
Vec2Df text_position = middle_handle + (c->start.lock()->position - c->end.lock()->position).norm().orth() * 12.0f;
Vec2Df text_position_frac = middle_handle_frac - (c->start.lock()->position - c->end.lock()->position).norm().orth() * 4.0f;
float rotation = Vector2Angle((Vector2){1,0}, (c->end.lock()->position - c->start.lock()->position)) * RAD2DEG;
DrawTextPro(GetFontDefault(), std::format("{:.1f}",d).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
if( (int)d % 60 == 0) DrawTextPro(GetFontDefault(), frac.c_str(), text_position_frac, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
}
if(midi_gate_v1 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v1_position.x, v1_position.y, midi_gate_v1, col);
col = {229, 181, 103, 255};
if(midi_gate_v2 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v2_position.x, v2_position.y, midi_gate_v2, col);
if(v1_v2_distance < 100) c->switches_offset = v1_v2_distance/2.3f; if(v1_v2_distance < 100) c->switches_offset = v1_v2_distance/2.3f;
Vec2Df from_to_handle = c->start.lock()->position - ((c->start.lock()->position - c->end.lock()->position)).norm() * (c->start.lock()->radius + c->switches_offset); Vec2Df from_to_handle = c->start.lock()->position - ((c->start.lock()->position - c->end.lock()->position)).norm() * (c->start.lock()->radius + c->switches_offset);
Vec2Df to_from_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (c->end.lock()->radius + c->switches_offset); Vec2Df to_from_handle = c->end.lock()->position - ((c->end.lock()->position - c->start.lock()->position)).norm() * (c->end.lock()->radius + c->switches_offset);
@@ -388,26 +371,68 @@ namespace VISEQ::GRAPH {
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f); unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f); unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
if(!c->start.lock()->picked_up && !c->end.lock()->picked_up){ float midi_gate_v1 = 0.0f;
// On/Off switches on both sides float midi_gate_v2 = 0.0f;
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->pass_forward ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->pass_forward = !c->pass_forward;
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c->pass_backward ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c->pass_backward = !c->pass_backward;
if(!c->pass_forward){ if(c->start.lock()->getNodeType() == NodeType::MIDINODE){
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle; midi_gate_v1 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->start.lock())->GGate(), 1.f, 4.f);
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
}
if(!c->pass_backward){
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
}
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) removeEdge(c);
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 125, 62, opacity} )) splitEdge(c);
} }
if(c->end.lock()->getNodeType() == NodeType::MIDINODE){
midi_gate_v2 = Clamp((4.f / 1000.f) * std::dynamic_pointer_cast<MidiNode>(c->end.lock())->GGate(), 1.f, 4.f);
}
// Line with small connector circles
if(c->end.lock()->getNodeType() == NodeType::MIDINODE && c->start.lock()->getNodeType() == NodeType::MIDINODE){
Color col = {229, 181, 103, 255};
if(c->GActive()) col = {108, 153, 187, 255};
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, col);
{
float d = c->start.lock()->position.dist(c->end.lock()->position);
std::string frac = MIDI::Fractions.at(std::clamp<int>(round(d/60) - 1, 0, 31));
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
Vector2 text_length_frac = MeasureTextEx(GetFontDefault(), frac.c_str(), 10.0f, 2.0f);
Vec2Df middle_handle = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length.x)*0.5f)/d;
Vec2Df middle_handle_frac = c->start.lock()->position + (c->end.lock()->position - c->start.lock()->position) * ((d - text_length_frac.x)*0.5f)/d;
Vec2Df text_position = middle_handle + (c->start.lock()->position - c->end.lock()->position).norm().orth() * 12.0f;
Vec2Df text_position_frac = middle_handle_frac - (c->start.lock()->position - c->end.lock()->position).norm().orth() * 4.0f;
float rotation = Vector2Angle((Vector2){1,0}, (c->end.lock()->position - c->start.lock()->position)) * RAD2DEG;
DrawTextPro(GetFontDefault(), std::format("{:.1f}",d).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
if( (int)d % 60 == 0) DrawTextPro(GetFontDefault(), frac.c_str(), text_position_frac, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
}
if(midi_gate_v1 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v1_position.x, v1_position.y, midi_gate_v1, col);
col = {229, 181, 103, 255};
if(midi_gate_v2 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v2_position.x, v2_position.y, midi_gate_v2, col);
if(!c->start.lock()->picked_up && !c->end.lock()->picked_up){
// On/Off switches on both sides
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->pass_forward ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->pass_forward = !c->pass_forward;
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c->pass_backward ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c->pass_backward = !c->pass_backward;
if(!c->pass_forward){
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle;
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
}
if(!c->pass_backward){
Vec2Df block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
Vec2Df block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
}
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 125, 62, opacity} )) splitEdge(c);
}
}
if(c->start.lock()->getNodeType() == NodeType::CONFIGNODE || c->end.lock()->getNodeType() == NodeType::CONFIGNODE){
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, VS_COLOR_BLUE);
}
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) removeEdge(c);
} }
} }
+11 -2
View File
@@ -197,14 +197,23 @@ namespace VISEQ::INTERACTION{
break; break;
} }
} }
auto connector = std::dynamic_pointer_cast<Connector>(e.item);
if(found && partner != e){ if(found && partner != e){
auto connector = std::dynamic_pointer_cast<Connector>(e.item);
auto connector_to = std::dynamic_pointer_cast<Connector>(partner.item); auto connector_to = std::dynamic_pointer_cast<Connector>(partner.item);
connector->partner = connector_to; connector->partner = connector_to;
connector_to->partner = connector; connector_to->partner = connector;
gm->addConnection(std::dynamic_pointer_cast<Node>(connector->parent.lock()), std::dynamic_pointer_cast<Node>(connector_to->parent.lock())); gm->addConnection(std::dynamic_pointer_cast<Node>(connector->parent.lock()), std::dynamic_pointer_cast<Node>(connector_to->parent.lock()));
connect_once = true; } else if (partner != e){
if(KEYS_DOWN.alt){
gm->createConfigNode(SCREEN_MOUSE);
} else {
gm->createMidiNode(SCREEN_MOUSE);
}
gm->addConnection(std::dynamic_pointer_cast<Node>(connector->parent.lock()), gm->getLastNode());
} }
connect_once = true;
break;
} }
} }
+1
View File
@@ -86,6 +86,7 @@ namespace VISEQ::GRAPH::NODES {
int GGate(){ int GGate(){
return midi_gate; return midi_gate;
} }
void update() override { void update() override {
Node::update(); Node::update();
mode = state->node_mode; mode = state->node_mode;
+52
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "config-node.h"
#include "midi-node.h" #include "midi-node.h"
#include "graph-item.h" #include "graph-item.h"
#include "node.h" #include "node.h"
@@ -124,6 +125,50 @@ namespace VISEQ::GRAPH::NODES {
j = json{{"port_id", MO.i}, {"enabled", MO.enabled}, {"name", MO.name}}; j = json{{"port_id", MO.i}, {"enabled", MO.enabled}, {"name", MO.name}};
} }
/* ----------------- CONFIG NODE -----------------*/
inline void to_json(json& j, const ConfigNode& N){
std::vector<int> conns;
std::ranges::transform(N.connections.begin(), N.connections.end(), std::back_inserter(conns), [](VISEQ::GRAPH::EDGES::SPTR_Edge e){ return e->id;});
j = json{
{"id", N.id},
{"position", N.position},
{"distributionMode", N.distributionMode},
{"nodeType", N.nodeType},
{"midi_note_channel",N.midiNote.channel},
{"midi_note",N.midiNote.note},
{"midi_cc_channel",N.midiCC.channel},
{"midi_cc",N.midiCC.value},
{"midi_pitch_bend_channel",N.midiPitchBend.channel},
{"midi_pitch_bend",N.midiPitchBend.value},
{"connections",conns}};
}
inline void from_json(const json& j, ConfigNode& N){
std::cout << "ConfigNode" << std::endl;
j.at("id").get_to(N.id);
j.at("position").get_to<Vec2Df>(N.position);
j.at("distributionMode").get_to(N.distributionMode);
j.at("nodeType").get_to(N.nodeType);
j.at("midi_note_channel").get_to(N.midiNote.channel);
j.at("midi_note").get_to(N.midiNote.note);
j.at("midi_cc_channel").get_to(N.midiCC.channel);
j.at("midi_cc").get_to(N.midiCC.value);
j.at("midi_pitch_bend_channel").get_to(N.midiPitchBend.channel);
j.at("midi_pitch_bend").get_to(N.midiPitchBend.value);
//j.at("connections").get_to(N.connections);
}
inline void to_json(json& j, const std::shared_ptr<ConfigNode>& N){
j = *N;
}
inline void from_json(const json& j, std::shared_ptr<ConfigNode>& N){
N.reset(new ConfigNode(j.get<ConfigNode>()));
}
/* ------------------- NODE ---------------------- */ /* ------------------- NODE ---------------------- */
@@ -132,6 +177,9 @@ namespace VISEQ::GRAPH::NODES {
if(N.getNodeType() == NodeType::MIDINODE){ if(N.getNodeType() == NodeType::MIDINODE){
j = dynamic_cast<const MidiNode&>(N); j = dynamic_cast<const MidiNode&>(N);
} }
if(N.getNodeType() == NodeType::CONFIGNODE){
j = dynamic_cast<const ConfigNode&>(N);
}
} }
inline void from_json(const json& j, Node& N){ inline void from_json(const json& j, Node& N){
@@ -140,6 +188,10 @@ namespace VISEQ::GRAPH::NODES {
std::cout << j.at("nodeType") << std::endl; std::cout << j.at("nodeType") << std::endl;
N = j.template get<MidiNode>(); N = j.template get<MidiNode>();
} }
if(j.at("nodeType") == NodeType::CONFIGNODE){
std::cout << j.at("nodeType") << std::endl;
N = j.template get<ConfigNode>();
}
} }
inline void to_json(json& j, const SPTR_Node& N){ inline void to_json(json& j, const SPTR_Node& N){
+1 -1
View File
@@ -32,7 +32,7 @@ namespace VISEQ::APP::UI{
void drawSideBar(){ void drawSideBar(){
GuiPanel((Rectangle){-1,-30,280,(float)state->settings.height + 31}, ""); GuiPanel((Rectangle){-1,-30,380,(float)state->settings.height + 31}, "");
const int s_controls = 25; const int s_controls = 25;
//GuiSetStyle(BUTTON, STATE_FOCUSED, 0xFF0000FF); //GuiSetStyle(BUTTON, STATE_FOCUSED, 0xFF0000FF);
if(GuiButton((Rectangle){20, (float)s_controls, 80, 30}, "PLAY")) sm->play ? sm->pause() : sm->start(); if(GuiButton((Rectangle){20, (float)s_controls, 80, 30}, "PLAY")) sm->play ? sm->pause() : sm->start();