move multiple nodes around with selection box

This commit is contained in:
Sebastian
2024-10-23 00:23:24 +02:00
parent f1860d2597
commit 15ee01cb56
4 changed files with 59 additions and 15 deletions
+4
View File
@@ -53,6 +53,10 @@ class ConnectionManager{
return paths.at(return_path)->v1 == current ? paths.at(return_path)->v2 : paths.at(return_path)->v1; 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<float> *mouse_pos, Camera2D *cam){ void drawConnections(Vec2D<float> *mouse_pos, Camera2D *cam){
std::erase_if(connections, [](Connection c){ return c.remove == true;}); std::erase_if(connections, [](Connection c){ return c.remove == true;});
for(auto& c : connections){ for(auto& c : connections){
+5
View File
@@ -7,6 +7,7 @@
#include <cmath> #include <cmath>
#include <math.h> #include <math.h>
#include "libremidi/libremidi.hpp" #include "libremidi/libremidi.hpp"
#include "raylib.h"
enum Distribution {ROUNDROBIN, RANDOM}; enum Distribution {ROUNDROBIN, RANDOM};
@@ -41,6 +42,10 @@ class Vec2D{
return (x*v.x) + (y*v.y); return (x*v.x) + (y*v.y);
}; };
operator Vector2() const {
return (Vector2){x,y};
}
Vec2D orth(Vec2D &v){ Vec2D orth(Vec2D &v){
return Vec2D(-v.y, v.x); return Vec2D(-v.y, v.x);
}; };
+46 -14
View File
@@ -32,7 +32,7 @@
#include <cmath> #include <cmath>
//#include "midi.h" #include "midi.h"
#include "node.h" #include "node.h"
#include "connection-manager.h" #include "connection-manager.h"
@@ -99,8 +99,15 @@ int main(){
ToggleFullscreen(); ToggleFullscreen();
for(int i = 0; i < 8; i++){ for(int i = 0; i < 4; ++i){
nodes.emplace(nodes.end(), Node((float)i * app.grid, 0.0f, 15.0f)); 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.addSignalAtNode(&nodes.front());
@@ -116,6 +123,11 @@ int main(){
double drag_timer = GetTime(); double drag_timer = GetTime();
Vec2D<float> select_start;
Rectangle selection;
bool hovering = false;
while(!WindowShouldClose()){ while(!WindowShouldClose()){
app.grid = round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4 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_clicked = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
bool mouse_released = IsMouseButtonReleased(MOUSE_BUTTON_LEFT); bool mouse_released = IsMouseButtonReleased(MOUSE_BUTTON_LEFT);
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) if(IsMouseButtonDown(MOUSE_BUTTON_RIGHT)){
{
Vector2 delta = GetMouseDelta(); Vector2 delta = GetMouseDelta();
delta = Vector2Scale(delta, -1.0f/camera.zoom); delta = Vector2Scale(delta, -1.0f/camera.zoom);
camera.target = Vector2Add(camera.target, delta); camera.target = Vector2Add(camera.target, delta);
} }
float wheel = GetMouseWheelMove(); float wheel = GetMouseWheelMove();
if (wheel != 0) if(wheel != 0){
{
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera); Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
camera.offset = GetMousePosition(); camera.offset = GetMousePosition();
camera.target = mouseWorldPos; camera.target = mouseWorldPos;
@@ -160,11 +170,31 @@ int main(){
for(int x = -app.grid*100; x < app.grid*100; x+=app.grid){ 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){ 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){130,130,130,200});
DrawPixel(x, y, (Color){120,120,120,200});
} }
} }
if(!hovering){
if(mouse_clicked){
select_start = mouse_pos;
}
if(mouse_down){
Vec2D<float> 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<float> 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){ for(auto& n : nodes){
Vec2D<float> connector_position = n.position - ((n.position - mouse_pos)).norm() * (n.radius + 14.0f); Vec2D<float> connector_position = n.position - ((n.position - mouse_pos)).norm() * (n.radius + 14.0f);
float dist_connector = (connector_position - mouse_pos).length(); float dist_connector = (connector_position - mouse_pos).length();
@@ -195,30 +225,32 @@ int main(){
if(mouse_released && (n.hover_connect || n.hover_move)) { if(mouse_released && (n.hover_connect || n.hover_move)) {
if(&n != connecting_from && connecting_from != nullptr){ if(&n != connecting_from && connecting_from != nullptr){
cm.connections.emplace(cm.connections.end(), connecting_from, &n); cm.addConnection(connecting_from, &n);
connecting_from = nullptr; connecting_from = nullptr;
} }
} }
if(!connecting){ if(!connecting){
// move node // move node
if((n.position - mouse_pos).length() <= n.radius || n.picked_up){ if((n.position - mouse_pos).length() <= n.radius || n.picked_up){
n.hover_move = true; n.hover_move = true;
hovering = true;
} else { } else {
n.hover_move = false; n.hover_move = false;
} }
if(mouse_clicked && n.hover_move && !dragging){ if(mouse_clicked && (n.hover_move || n.selected)){ // && !dragging){
n.picked_up = true; n.picked_up = true;
drag_offset = n.position - mouse_pos; n.drag_offset = n.position - mouse_pos;
dragging = true; dragging = true;
drag_timer = GetTime(); drag_timer = GetTime();
} }
if(mouse_down && n.picked_up){ if(mouse_down && n.picked_up){
if(GetTime() - drag_timer > 0.1) { if(GetTime() - drag_timer > 0.1) {
if(IsKeyDown(KEY_LEFT_CONTROL)) { if(IsKeyDown(KEY_LEFT_CONTROL)) {
n.position = (Vec2D<float>){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<float>){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 { } else {
n.position = mouse_pos + drag_offset; n.position = mouse_pos + n.drag_offset;
} }
} }
} }
+4 -1
View File
@@ -28,9 +28,12 @@ class Node : public Movable{
bool hover_connect = false; bool hover_connect = false;
bool connecting = false; bool connecting = false;
bool config = false; bool config = false;
bool selected = false;
int midi_out = -1; int midi_out = -1;
Vec2D<float> drag_offset;
std::map<int, NodeMidiOut> midi_outs; std::map<int, NodeMidiOut> midi_outs;
bool gui_midi_channel_edit = false; bool gui_midi_channel_edit = false;
@@ -49,7 +52,7 @@ class Node : public Movable{
void draw(Vec2D<float> *mouse, Camera2D *cam) { void draw(Vec2D<float> *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){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); 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 ); DrawText(MIDI::Notes[midi_note].c_str(), position.x-offset/2.0f, position.y-5, 10, WHITE );