diff --git a/src/connection-manager.h b/src/connection-manager.h index fb73d68..ff8cbdc 100644 --- a/src/connection-manager.h +++ b/src/connection-manager.h @@ -54,7 +54,7 @@ class ConnectionManager{ } void addConnection(Node *from, Node *to){ - connections.emplace(connections.end(), from, to); + connections.emplace_back(from, to); } void drawConnections(Vec2D *mouse_pos, Camera2D *cam){ diff --git a/src/datatypes.h b/src/datatypes.h index bd362e4..b9bd5de 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -141,9 +141,9 @@ enum States {IDLE, CONFIG}; struct AppState{ int width; int height; - int grid; - int bpm; - int fps; + float grid; + float bpm; + float fps; float speed = 16.0f; int gui_selected_midi_out; States state; diff --git a/src/main.cpp b/src/main.cpp index cabaef2..171f5fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,7 @@ #include "datatypes.h" #include "signal-manager.h" #include +#include #include #include #include @@ -68,9 +69,12 @@ int main(){ SetWindowMonitor(monitor); - app.fps = 60; - app.bpm = 120; - app.grid = round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4 + app.fps = 60.0f; + app.bpm = 120.0f; + app.grid = 120.0f; //round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4 +// app.speed = round((((app.fps / (app.bpm / 60.0f)) / app.grid) / 4.0f) / 10.0f) * 10.0f; + + app.speed = (app.grid * 4.0f) / (app.fps / (app.bpm / 60.0f)); // 120 fps // 120bpm = 120 1/4 Noten pro Minute = 2 1/4 Noten / s @@ -126,12 +130,11 @@ int main(){ 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 - + //app.grid = round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4 + app.speed = (app.grid * 4.0f) / (app.fps / (app.bpm / 60.0f)); + Vector2 mp = GetScreenToWorld2D(GetMousePosition(), camera); Vec2D mouse_pos = {(float)mp.x, (float)mp.y}; Vec2D cam_pos = {camera.offset.x, camera.offset.y}; @@ -166,7 +169,6 @@ int main(){ BeginMode2D(camera); bool connecting = false; - bool dragging = false; 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){ @@ -174,27 +176,92 @@ int main(){ } } - if(!hovering){ - if(mouse_clicked){ - select_start = mouse_pos; - } + for(auto &n : nodes){ + n.hovering = false; + } - 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}; - } + auto dragging_nodes = nodes | std::ranges::views::filter([](Node n) { return n.dragging;}); - for(auto& n : nodes){ - if(CheckCollisionPointRec(n.position, selection)) { - n.selected = true; - } else { - n.selected = false; + if(dragging_nodes.empty()) { + auto hovering_nodes = nodes | std::ranges::views::filter([&mouse_pos](Node n) { return CheckCollisionPointCircle(mouse_pos, n.position, n.radius);}); + + if(hovering_nodes.empty() || selection.width > 0){ + if(mouse_clicked){ + select_start = mouse_pos; + for(auto &n : nodes){ + n.selected = false; + } + } + + 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.in_rect = true; + } else { + n.in_rect = false; + } + } + } + + if(mouse_released){ + for(auto& n : nodes){ + if(CheckCollisionPointRec(n.position, selection)) { + n.selected = true; + } + } + selection = (Rectangle){0,0,0,0}; + } + } else { + hovering_nodes.front().hovering = true; + if(selection.width == 0.0f){ + if(mouse_clicked){ + drag_timer = GetTime(); + } + if(mouse_down && GetTime() - drag_timer > 0.07){ + hovering_nodes.front().drag_offset = hovering_nodes.front().position - mouse_pos; + hovering_nodes.front().dragging = true; + } + if(mouse_released && GetTime() - drag_timer <= 0.07){ + hovering_nodes.front().config = true; + } } } + + } else { + + if(mouse_down){ + if(IsKeyDown(KEY_LEFT_CONTROL)) { + dragging_nodes.front().position = (Vec2D){round((mouse_pos.x+dragging_nodes.front().drag_offset.x)/app.grid)*app.grid, round((mouse_pos.y+dragging_nodes.front().drag_offset.y)/app.grid)*app.grid}; + } else { + dragging_nodes.front().position = mouse_pos + dragging_nodes.front().drag_offset; + } + } + if(mouse_released) { + dragging_nodes.front().dragging = false; + } + + auto selected_nodes = nodes | std::ranges::views::filter([](Node n) { return n.selected && !n.dragging;}); + if(!selected_nodes.empty() && mouse_down){ + for(auto &n : selected_nodes){ + if(!n.picked_up) n.drag_offset = n.position - dragging_nodes.front().position; + n.picked_up = true; + n.position = dragging_nodes.front().position + n.drag_offset; + } + } + if(mouse_released) { + dragging_nodes.front().dragging = false; + for(auto &n : selected_nodes){ + n.picked_up = 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(); @@ -223,47 +290,12 @@ int main(){ //connecting_from = nullptr; } - if(mouse_released && (n.hover_connect || n.hover_move)) { + if(mouse_released && (n.hover_connect || n.dragging)) { if(&n != connecting_from && connecting_from != nullptr){ 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 || n.selected)){ // && !dragging){ - n.picked_up = true; - 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+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 + n.drag_offset; - } - } - } - - if(mouse_released && n.picked_up){ - if(GetTime() - drag_timer < 0.1) n.config = true; - } - - if(mouse_released) { - n.picked_up = false; - } - - } n.draw(&mouse_pos, &camera); } @@ -322,7 +354,7 @@ int main(){ int s_nodes = s_signal + 60 + signal_configs*20; GuiLabel((Rectangle){20, (float)s_nodes + 30, 240, 20}, "NODES"); if(GuiButton((Rectangle){20, (float)s_nodes + 60, 240, 20}, "ADD RANDOM NODE")){ - nodes.emplace_back(Node((float)(rand() % app.width*0.5 + app.width*0.25), (float)(rand() % app.height*0.5 + app.height*0.25), 15.0f)); + nodes.emplace_back(Node(200.0f, 200.0f, 15.0f)); } diff --git a/src/node.h b/src/node.h index 6a109f7..c67e7dc 100644 --- a/src/node.h +++ b/src/node.h @@ -24,8 +24,10 @@ class Node : public Movable{ float radius; bool picked_up = false; - bool hover_move = false; + bool dragging = false; + bool in_rect = false; bool hover_connect = false; + bool hovering = false; bool connecting = false; bool config = false; bool selected = false; @@ -51,8 +53,8 @@ class Node : public Movable{ Distribution mode = Distribution::ROUNDROBIN; void draw(Vec2D *mouse, Camera2D *cam) { - if(!hover_move) DrawCircle(position.x, position.y, radius, (Color){180, 210, 115, 255}); - if(hover_move || selected) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255}); + if(!dragging && !selected && !in_rect && !hovering) DrawCircle(position.x, position.y, radius, (Color){180, 210, 115, 255}); + if(dragging || selected || in_rect || hovering) 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 );