From 15ee01cb56791cb59ac0123fc1dec7d6046ff298 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 23 Oct 2024 00:23:24 +0200 Subject: [PATCH] move multiple nodes around with selection box --- src/connection-manager.h | 4 +++ src/datatypes.h | 5 ++++ src/main.cpp | 60 ++++++++++++++++++++++++++++++---------- src/node.h | 5 +++- 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/connection-manager.h b/src/connection-manager.h index 3efa5de..fb73d68 100644 --- a/src/connection-manager.h +++ b/src/connection-manager.h @@ -53,6 +53,10 @@ class ConnectionManager{ return paths.at(return_path)->v1 == current ? paths.at(return_path)->v2 : paths.at(return_path)->v1; } + void addConnection(Node *from, Node *to){ + connections.emplace(connections.end(), from, to); + } + void drawConnections(Vec2D *mouse_pos, Camera2D *cam){ std::erase_if(connections, [](Connection c){ return c.remove == true;}); for(auto& c : connections){ diff --git a/src/datatypes.h b/src/datatypes.h index 5cf18bc..bd362e4 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -7,6 +7,7 @@ #include #include #include "libremidi/libremidi.hpp" +#include "raylib.h" enum Distribution {ROUNDROBIN, RANDOM}; @@ -41,6 +42,10 @@ class Vec2D{ return (x*v.x) + (y*v.y); }; + operator Vector2() const { + return (Vector2){x,y}; + } + Vec2D orth(Vec2D &v){ return Vec2D(-v.y, v.x); }; diff --git a/src/main.cpp b/src/main.cpp index 12a093e..cabaef2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,7 +32,7 @@ #include -//#include "midi.h" +#include "midi.h" #include "node.h" #include "connection-manager.h" @@ -99,10 +99,17 @@ int main(){ ToggleFullscreen(); - for(int i = 0; i < 8; i++){ - nodes.emplace(nodes.end(), Node((float)i * app.grid, 0.0f, 15.0f)); + for(int i = 0; i < 4; ++i){ + nodes.emplace(nodes.end(), Node((float)i * app.grid + 10 * app.grid, 5 * app.grid, 15.0f)); + } + for(int i = 3; i >= 0; --i){ + nodes.emplace(nodes.end(), Node((float)i * app.grid + 10 * app.grid, 6 * app.grid, 15.0f)); } + for(int i = 0; i < 8; ++i){ + cm.addConnection(&nodes[i], &nodes[(i+1) % 8]); + } + sm.addSignalAtNode(&nodes.front()); sm.startSignalThread(); @@ -116,6 +123,11 @@ int main(){ double drag_timer = GetTime(); + Vec2D select_start; + Rectangle selection; + + bool hovering = false; + while(!WindowShouldClose()){ app.grid = round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4 @@ -128,16 +140,14 @@ int main(){ bool mouse_clicked = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); bool mouse_released = IsMouseButtonReleased(MOUSE_BUTTON_LEFT); - if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) - { + if(IsMouseButtonDown(MOUSE_BUTTON_RIGHT)){ Vector2 delta = GetMouseDelta(); delta = Vector2Scale(delta, -1.0f/camera.zoom); camera.target = Vector2Add(camera.target, delta); } float wheel = GetMouseWheelMove(); - if (wheel != 0) - { + if(wheel != 0){ Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera); camera.offset = GetMousePosition(); camera.target = mouseWorldPos; @@ -160,11 +170,31 @@ int main(){ for(int x = -app.grid*100; x < app.grid*100; x+=app.grid){ for(int y = -app.grid*100; y < app.grid*100; y+=app.grid){ -// DrawLine(-5000, i, 5000, i, (Color){80,80,80,100}); - DrawPixel(x, y, (Color){120,120,120,200}); + DrawPixel(x, y, (Color){130,130,130,200}); } } + if(!hovering){ + if(mouse_clicked){ + select_start = mouse_pos; + } + + if(mouse_down){ + Vec2D select1 = {mouse_pos.x > select_start.x ? select_start.x : mouse_pos.x, mouse_pos.y > select_start.y ? select_start.y : mouse_pos.y}; + Vec2D select2 = {mouse_pos.x > select_start.x ? mouse_pos.x - select_start.x : select_start.x - mouse_pos.x, mouse_pos.y > select_start.y ? mouse_pos.y - select_start.y : select_start.y - mouse_pos.y}; + DrawRectangleLines(select1.x, select1.y, select2.x, select2.y, (Color){150,150,150,150}); + selection = (Rectangle){select1.x, select1.y, select2.x, select2.y}; + } + + for(auto& n : nodes){ + if(CheckCollisionPointRec(n.position, selection)) { + n.selected = true; + } else { + n.selected = false; + } + } + } + hovering = false; for(auto& n : nodes){ Vec2D connector_position = n.position - ((n.position - mouse_pos)).norm() * (n.radius + 14.0f); float dist_connector = (connector_position - mouse_pos).length(); @@ -195,30 +225,32 @@ int main(){ if(mouse_released && (n.hover_connect || n.hover_move)) { if(&n != connecting_from && connecting_from != nullptr){ - cm.connections.emplace(cm.connections.end(), connecting_from, &n); + cm.addConnection(connecting_from, &n); connecting_from = nullptr; } } + if(!connecting){ // move node if((n.position - mouse_pos).length() <= n.radius || n.picked_up){ n.hover_move = true; + hovering = true; } else { n.hover_move = false; } - if(mouse_clicked && n.hover_move && !dragging){ + if(mouse_clicked && (n.hover_move || n.selected)){ // && !dragging){ n.picked_up = true; - drag_offset = n.position - mouse_pos; + n.drag_offset = n.position - mouse_pos; dragging = true; drag_timer = GetTime(); } if(mouse_down && n.picked_up){ if(GetTime() - drag_timer > 0.1) { if(IsKeyDown(KEY_LEFT_CONTROL)) { - n.position = (Vec2D){round((mouse_pos.x+drag_offset.x)/app.grid)*app.grid, round((mouse_pos.y+drag_offset.y)/app.grid)*app.grid}; + n.position = (Vec2D){round((mouse_pos.x+n.drag_offset.x)/app.grid)*app.grid, round((mouse_pos.y+n.drag_offset.y)/app.grid)*app.grid}; } else { - n.position = mouse_pos + drag_offset; + n.position = mouse_pos + n.drag_offset; } } } diff --git a/src/node.h b/src/node.h index d38c4d4..6a109f7 100644 --- a/src/node.h +++ b/src/node.h @@ -28,9 +28,12 @@ class Node : public Movable{ bool hover_connect = false; bool connecting = false; bool config = false; + bool selected = false; int midi_out = -1; + Vec2D drag_offset; + std::map midi_outs; bool gui_midi_channel_edit = false; @@ -49,7 +52,7 @@ class Node : public Movable{ void draw(Vec2D *mouse, Camera2D *cam) { if(!hover_move) DrawCircle(position.x, position.y, radius, (Color){180, 210, 115, 255}); - if(hover_move) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255}); + if(hover_move || selected) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255}); int offset = MeasureText(MIDI::Notes[midi_note].c_str(), 10); DrawText(MIDI::Notes[midi_note].c_str(), position.x-offset/2.0f, position.y-5, 10, WHITE );