diff --git a/src/connection-manager.h b/src/connection-manager.h index f56d83a..6c31338 100644 --- a/src/connection-manager.h +++ b/src/connection-manager.h @@ -2,6 +2,7 @@ #include "connection.h" #include +#include class ConnectionManager{ @@ -13,30 +14,40 @@ class ConnectionManager{ std::map counter; - Node* next(Node* current){ + Node* next(Node* current, Node* last){ std::vector paths; + bool last_ok = false; for(auto& p : connections){ - if((p.v1 == current && p.v1_v2) || (p.v2 == current && p.v2_v1)) { + if(((p.v1 == current && p.v1_v2) || (p.v2 == current && p.v2_v1)) && (p.v1 != last || p.v2 != last)) { p.active = false; paths.push_back(&p); } + if(p.v1 == last || p.v2 == last) last_ok = true; } + if(paths.empty() && last_ok) return last; if(paths.empty()) return nullptr; int return_path = 0; - if(counter.find(current) == counter.end()) { - counter[current] = 0; - } else { - counter[current] = (counter[current] + 1) % paths.size(); - return_path = counter[current]; + + if(current->mode == Distribution::ROUNDROBIN){ + if(counter.find(current) == counter.end()) { + counter[current] = 0; + } else { + counter[current] = (counter[current] + 1) % paths.size(); + return_path = counter[current]; + } } - paths[return_path]->active = true; - return paths[return_path]->v1 == current ? paths[return_path]->v2 : paths[return_path]->v1; + if(current->mode == Distribution::RANDOM){ + return_path = rand() % paths.size(); + } + paths.at(return_path)->active = true; + return paths.at(return_path)->v1 == current ? paths.at(return_path)->v2 : paths.at(return_path)->v1; } void draw(){ + std::erase_if(connections, [](Connection c){ return c.remove == true;}); for(auto& c : connections){ c.draw(); } diff --git a/src/connection.h b/src/connection.h index c432586..e017ca9 100644 --- a/src/connection.h +++ b/src/connection.h @@ -15,6 +15,7 @@ class Connection{ bool v1_v2 = true; bool v2_v1 = true; bool active = false; + bool remove = false; void draw(){ Vec2D v1_position = v1->position - ((v1->position - v2->position)).norm() * (v1->radius + 10.0f); @@ -26,8 +27,11 @@ class Connection{ Vec2D from_to_handle = v1->position - ((v1->position - v2->position)).norm() * (v1->radius + 35); Vec2D to_from_handle = v2->position - ((v2->position - v1->position)).norm() * (v2->radius + 35); + Vec2D middle_handle = v2->position - ((v2->position - v1->position))*0.5f; if(ViButton(from_to_handle.x, from_to_handle.y, 8.0f, v1_v2 ? (Color){232, 125, 62, 255} : (Color){232, 50, 32, 255} )) v1_v2 = !v1_v2; if(ViButton(to_from_handle.x, to_from_handle.y, 8.0f, v2_v1 ? (Color){232, 125, 62, 255} : (Color){232, 50, 32, 255} )) v2_v1 = !v2_v1; + + if(ViButton(middle_handle.x, middle_handle.y, 8.0f, (Color){232, 50, 32, 255} )) remove = true; } }; diff --git a/src/datatypes.h b/src/datatypes.h index 1ece9e8..0ffb7f0 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -3,6 +3,9 @@ #include #include + +enum Distribution {ROUNDROBIN, RANDOM}; + // 2D Vectors template diff --git a/src/main.cpp b/src/main.cpp index e8d2112..b11da89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,8 @@ /*Pink: (176, 82, 121); #b05279*/ /*Blue: (108, 153, 187); #6c99bb*/ +#include "datatypes.h" +#include #include #include @@ -30,11 +32,9 @@ #include #include #include -#include #include "node.h" #include "signal.h" -#include "connection.h" #include "connection-manager.h" @@ -46,7 +46,6 @@ std::vector midi_out_ports; std::vector nodes; std::vector signals; -//std::vector connections; ConnectionManager cm; Vec2D mouse_pos; @@ -98,20 +97,25 @@ int main(){ } for(int i = 0; i < 10; i++){ - nodes.emplace(nodes.end(), Node((float)(rand() % 2160 + 200), (float)(rand() % 1040 + 200), 15.0f)); + nodes.emplace(nodes.end(), Node((float)(rand() % app.width*0.5 + app.width*0.25), (float)(rand() % app.height*0.5 + app.height*0.25), 15.0f)); + + std::cout << nodes.back().position.x << " " << nodes.back().position.y << std::endl; } - for(int i = 0; i < 2; i++){ - signals.emplace(signals.end(), Signal(1280, 720, 5.0f, 2.0f)); - signals[i].next = &nodes[0]; + for(int i = 0; i < 1; i++){ + signals.emplace(signals.end(), Signal(nodes.front().position.x+1, nodes.front().position.y+1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea! + signals[i].next = &nodes.front(); + signals[i].last = &nodes.front(); } midi_out.open_port(midi_out_ports[2]); Vec2D drag_offset; - Node* connecting_from; - + Node* connecting_from = nullptr; + + double drag_timer = GetTime(); + while(!WindowShouldClose()){ Vector2 mp = GetScreenToWorld2D(GetMousePosition(), camera); @@ -130,6 +134,8 @@ int main(){ ClearBackground((Color){46,46,46}); BeginMode2D(camera); + bool connecting = false; + bool dragging = false; for(auto& n : nodes){ Vec2D connector_position = n.position - ((n.position - mouse_pos)).norm() * (n.radius + 10.0f); @@ -144,9 +150,10 @@ int main(){ n.hover_connect = false; } - if(dist_connector <= 6.0f && mouse_clicked) { + if(dist_connector <= 6.0f && mouse_clicked && !connecting) { connecting_from = &n; n.connecting = true; + connecting = true; } if(n.connecting && mouse_down){ @@ -155,6 +162,7 @@ int main(){ if(mouse_released && n.connecting) { n.connecting = false; + //connecting_from = nullptr; } if(mouse_released && (n.hover_connect || n.hover_move)) { @@ -163,24 +171,32 @@ int main(){ connecting_from = nullptr; } } + if(!connecting){ + // move node + if((n.position - mouse_pos).length() <= n.radius || n.picked_up){ + n.hover_move = true; + } else { + n.hover_move = false; + } - // move node - if((n.position - mouse_pos).length() <= n.radius || n.picked_up){ - n.hover_move = true; - } else { - n.hover_move = false; - } + if(mouse_clicked && n.hover_move && !dragging){ + n.picked_up = true; + drag_offset = n.position - mouse_pos; + dragging = true; + drag_timer = GetTime(); + } + if(mouse_down && n.picked_up){ + if(GetTime() - drag_timer > 0.1) n.position = mouse_pos + drag_offset; + } - if(mouse_clicked && n.hover_move){ - n.picked_up = true; - drag_offset = n.position - mouse_pos; - } - if(mouse_down && n.picked_up){ - n.position = mouse_pos + drag_offset; - } + if(mouse_released && n.picked_up){ + if(GetTime() - drag_timer < 0.1) n.config = true; + } + + if(mouse_released) { + n.picked_up = false; + } - if(mouse_released) { - n.picked_up = false; } n.draw(&mouse_pos); } @@ -188,11 +204,13 @@ int main(){ cm.draw(); for(auto& s : signals){ - s.direction = s.next->position - s.position; + s.direction = (s.next->position - s.position).norm(); if(s.position.dist(&s.next->position) < s.speed * 1.5) { - Node* n = cm.next(s.next); + Node* n = cm.next(s.next, s.last); if(n != s.next && n != nullptr) { + s.last = s.next; s.next = n; + std::cout << s.last << " " << s.next << std::endl; midi_out.send_message(libremidi::channel_events::control_change(2, 10, 50)); } } @@ -200,9 +218,24 @@ int main(){ } EndMode2D(); - GuiWindowBox((Rectangle){16,16,232,400}, "config"); - - GuiButton((Rectangle){32, 64, 96, 20}, "button"); + GuiWindowBox((Rectangle){0,0,280,600}, "config"); + + if(GuiButton((Rectangle){20, 60, 240, 20}, "button")){ + signals.emplace_back(Signal(nodes.front().position.x + 1, nodes.front().position.y + 1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea! + signals.back().next = &nodes[0]; + signals.back().last = &nodes[0]; + } + + for(auto& n : nodes){ + if(n.config){ + int option = n.mode; + GuiComboBox((Rectangle){ 20, 100, 240, 20 }, "Round Robin;Random", &option); + n.mode = (Distribution)option; + if(GuiButton((Rectangle){20, 140, 240, 20 }, "button")){ + + } + } + } EndDrawing(); } diff --git a/src/node.h b/src/node.h index 9b3c44d..015929f 100644 --- a/src/node.h +++ b/src/node.h @@ -5,8 +5,6 @@ #include "datatypes.h" #include "moveable.h" -#include - #define R 10.0f class Node : public Movable{ @@ -21,20 +19,14 @@ class Node : public Movable{ bool hover_move = false; bool hover_connect = false; bool connecting = false; - -// int next = 0; + bool config = false; int midi_out = 0; int midi_note = 0; int midi_cc = 0; -// std::vector connections; - - /*Node* get_next(){*/ - /* next = (next+1) % connections.size();*/ - /* return connections[next];*/ - /*}*/ + Distribution mode = Distribution::ROUNDROBIN; void draw(Vec2D *mouse) { if(!hover_move) DrawCircle(position.x, position.y, radius, (Color){180, 210, 115, 255}); @@ -42,12 +34,6 @@ class Node : public Movable{ Vec2D connector = position - ((position - *mouse)).norm() * (radius + R); - /*for(auto& to : connections){*/ - /* Vec2D from_position = position - ((position - to->position)).norm() * (radius + 10.0f);*/ - /* Vec2D to_position = to->position - ((to->position - position)).norm() * (to->radius + 10.0f);*/ - /* DrawLine(from_position.x, from_position.y, to_position.x, to_position.y, (Color){229, 181, 103, 255});*/ - /*}*/ - if(hover_connect){ DrawCircleLines(position.x, position.y, radius + R, (Color){108, 153, 187, 255}); DrawCircle(connector.x, connector.y, 6.0f, (Color){108, 153, 187, 255}); diff --git a/src/signal.h b/src/signal.h index 259260a..8c6b209 100644 --- a/src/signal.h +++ b/src/signal.h @@ -15,6 +15,7 @@ class Signal : public Movable{ int id = 0; Node *next; + Node *last; bool at_target = false; int target_node_id = 1;