From 70d0a186a4ca93a7e187cda9b7076a6be6c049ce Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 2 Nov 2024 02:06:26 +0100 Subject: [PATCH] split edge: check, copy paste: check with a little bug --- src/datatypes.h | 2 +- src/edge.h | 5 --- src/graph-manager.h | 64 +++++++++++++++++----------- src/main.cpp | 101 ++++++++++++++++++++++++-------------------- src/state-manager.h | 36 ++++++++++++---- 5 files changed, 123 insertions(+), 85 deletions(-) diff --git a/src/datatypes.h b/src/datatypes.h index 5008d51..5503e0c 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -96,7 +96,7 @@ class Vec2D{ Vec2D norm() { return *this / length();}; Vec2D center(Vec2D v){ - return Vec2D{x,y} + (Vec2D{x,y} - v)*0.5f; + return Vec2D{x,y} - (Vec2D{x,y} - v)*0.5f; } Vec2D& operator=(const Vec2D& vec){ diff --git a/src/edge.h b/src/edge.h index c85dfb3..0ab2074 100644 --- a/src/edge.h +++ b/src/edge.h @@ -31,9 +31,4 @@ class Edge : public GraphItem{ void draw(Vec2D mouse_pos, Camera2D cam) { } - - void remove(){ - delete this; - } - }; diff --git a/src/graph-manager.h b/src/graph-manager.h index 842f0b6..07de33d 100644 --- a/src/graph-manager.h +++ b/src/graph-manager.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,7 @@ class GraphManager{ VEC_SPTR_Edge edges; VEC_SPTR_Edge remove_edges; + VEC_SPTR_Edge split_edges; std::map counter; @@ -45,32 +47,32 @@ class GraphManager{ return std::dynamic_pointer_cast(o.front()); } - void copyNodes(VEC_SPTR_Node nodes, Vec2D position){ - for(auto n: nodes){ - auto nc = std::make_shared(*n); - nc->position = position + nc->drag_offset; - nc->selected = true; - nodes.push_back(nc); + void copyNodes(VEC_SPTR_Node _nodes, Vec2D position){ + for(auto n: _nodes){ + nodes.insert(nodes.end(), std::make_shared(*n)); + nodes.back()->setPosition(position + nodes.back()->drag_offset); + nodes.back()->selected = false; } } - void copyNodes(std::vector> nodes, Vec2D position){ - for(auto n: nodes){ - std::shared_ptr nc = std::make_shared(*n); - nc->position = position + nc->drag_offset; - nc->selected = true; - nodes.push_back(nc); + void copyNodes(std::vector> _nodes, Vec2D position){ + for(auto n: _nodes){ + nodes.insert(nodes.end(), std::make_shared(*n)); + nodes.back()->setPosition(position + nodes.back()->drag_offset); + nodes.back()->selected = false; } } SPTR_Node copyNode(SPTR_Node n, Vec2D position){ - nodes.emplace_back(std::make_shared(*n)); + std::cout << "copy basenode" << std::endl; + nodes.insert(nodes.end(), std::make_shared(*n)); nodes.back()->setPosition(position); return nodes.back(); } - std::shared_ptr copyNode(std::shared_ptr n, Vec2D position){ - nodes.emplace_back(std::make_shared(*n)); + SPTR_Node copyNode(std::shared_ptr n, Vec2D position){ + std::cout << "copy midinode" << std::endl; + nodes.insert(nodes.end(), std::make_shared(*n)); nodes.back()->setPosition(position); return nodes.back(); } @@ -131,15 +133,28 @@ class GraphManager{ } void addConnection(SPTR_Node from, SPTR_Node to){ - edges.emplace_back(std::make_shared()); - edges.back()->start = from; - edges.back()->end = to; - from->connections.push_back(edges.back()); - to->connections.push_back(edges.back()); + if(from != to) { + edges.emplace_back(std::make_shared()); + edges.back()->start = from; + edges.back()->end = to; + from->connections.push_back(edges.back()); + to->connections.push_back(edges.back()); + } } void splitEdge(SPTR_Edge edge){ - + split_edges.push_back(edge); + } + + void splitEdges(){ + for(auto s : split_edges){ + Vec2D center = s->end->position.center(s->start->position); + SPTR_Node cn = addMidiNode(center); + addConnection(s->start, cn); + addConnection(cn, s->end); + remove_edges.push_back(s); + } + split_edges.clear(); } void removeEdge(SPTR_Edge edge){ @@ -152,12 +167,13 @@ class GraphManager{ std::erase(edge->end->connections, edge); std::erase(edges, edge); } + remove_edges.clear(); } void drawEdges(Vec2D mouse_pos, Camera2D cam){ -// std::erase_if(connections, [](Connection c){ return c.remove == true;}); if(!remove_edges.empty()) removeEdges(); - for(auto& c : edges){ + if(!split_edges.empty()) splitEdges(); + for(auto c : edges){ Vec2D v1_position = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c->connector_offset); Vec2D v2_position = c->end->position - ((c->end->position - c->start->position)).norm() * (c->end->radius + c->connector_offset); float v1_v2_distance = v1_position.dist(&v2_position); @@ -185,7 +201,6 @@ class GraphManager{ Vec2D flip_handle = middle_handle + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*0.2, 0.f, 20.f) : 1.0f); Vec2D flip_handle_2 = middle_handle_2 + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*-0.2, -20.f, 0.f) : 1.0f); - // Dynamic opacity by distance to mouse unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f); unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f); @@ -208,7 +223,6 @@ class GraphManager{ 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); } diff --git a/src/main.cpp b/src/main.cpp index 471b269..4b6a2ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ */ #include "midi-node.h" +#include #include #include #include @@ -291,6 +292,8 @@ int main(){ case InteractionState::COPY_SELECTED_NODES: { std::ranges::copy(selected_nodes.begin(), selected_nodes.end(), std::back_inserter(copied_nodes)); + std::ranges::for_each(selected_nodes.begin(), selected_nodes.end(), [](SPTR_Node n){n->selected = false;}); + selected_nodes.clear(); break; } case InteractionState::PASTE_SELECTED_NODES: @@ -299,59 +302,65 @@ int main(){ n->drag_offset = (n->position - copied_nodes.front()->position); } app.copyNodesAndConnections(copied_nodes, mouse_pos); - copied_nodes.clear(); + //copied_nodes.clear(); break; } }; float wheel = GetMouseWheelMove(); if(wheel != 0){ - if(!hovering_nodes.empty() && hovering_nodes.front()->getNodeType() == NodeType::MIDINODE) { - std::shared_ptr midiNode = std::dynamic_pointer_cast(hovering_nodes.front()); - if(IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){ - switch(app.settings.mode){ - case 0:{ - midiNode->midi_note += wheel; - break;} - case 1:{ - midiNode->midi_cc += wheel; - break;} - case 2:{ - midiNode->midi_pitch_bend += wheel; - break;} - }; - if(midiNode->midi_note < 0 ) midiNode->midi_note = app.sm.midi.midiNotes.size()-1; - if(midiNode->midi_note >= app.sm.midi.midiNotes.size() ) midiNode->midi_note = 0; - - if(midiNode->midi_cc < 0 ) midiNode->midi_cc = 127; - if(midiNode->midi_cc > 127 ) midiNode->midi_cc = 0; - - if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0; - if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383; + if(!hovering_nodes.empty() && hovering_nodes.front()->getNodeType() == NodeType::MIDINODE) { + VEC_SPTR_Node modify_nodes; + std::copy_if(selected_nodes.begin(), selected_nodes.end(), std::back_inserter(modify_nodes), [](SPTR_Node n){ return n->getNodeType() == NodeType::MIDINODE;}); + std::copy_if(hovering_nodes.begin(), hovering_nodes.end(), std::back_inserter(modify_nodes), [modify_nodes](SPTR_Node n){ return n->getNodeType() == NodeType::MIDINODE && !std::ranges::contains(modify_nodes, n);}); - } else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_ALT)) { - midiNode->midi_velocity += wheel; - if(midiNode->midi_velocity < 0 ) midiNode->midi_velocity = 127; - if(midiNode->midi_velocity > 127 ) midiNode->midi_velocity = 0; - } else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_ALT)) { - switch(app.settings.mode){ - case 0:{ - float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f); - midiNode->midi_gate += incr; - if(midiNode->midi_gate < 0 ) midiNode->midi_gate = 0; - break;} - case 1:{ - midiNode->midi_cc_value += wheel; - if(midiNode->midi_cc_value < 0 ) midiNode->midi_cc_value = 0; - if(midiNode->midi_cc_value > 127 ) midiNode->midi_cc_value = 127; - break;} - case 2:{ - float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f); - midiNode->midi_pitch_bend += incr; - if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0; - if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383; - break;} - }; + for(auto n : modify_nodes){ + std::shared_ptr midiNode = std::dynamic_pointer_cast(n); + if(IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){ + switch(app.settings.mode){ + case 0:{ + midiNode->midi_note += wheel; + break;} + case 1:{ + midiNode->midi_cc += wheel; + break;} + case 2:{ + midiNode->midi_pitch_bend += wheel; + break;} + }; + if(midiNode->midi_note < 0 ) midiNode->midi_note = app.sm.midi.midiNotes.size()-1; + if(midiNode->midi_note >= app.sm.midi.midiNotes.size() ) midiNode->midi_note = 0; + + if(midiNode->midi_cc < 0 ) midiNode->midi_cc = 127; + if(midiNode->midi_cc > 127 ) midiNode->midi_cc = 0; + + if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0; + if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383; + + } else if(IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_ALT)) { + midiNode->midi_velocity += wheel; + if(midiNode->midi_velocity < 0 ) midiNode->midi_velocity = 127; + if(midiNode->midi_velocity > 127 ) midiNode->midi_velocity = 0; + } else if(IsKeyDown(KEY_LEFT_ALT)) { + switch(app.settings.mode){ + case 0:{ + float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f); + midiNode->midi_gate += incr; + if(midiNode->midi_gate < 0 ) midiNode->midi_gate = 0; + break;} + case 1:{ + midiNode->midi_cc_value += wheel; + if(midiNode->midi_cc_value < 0 ) midiNode->midi_cc_value = 0; + if(midiNode->midi_cc_value > 127 ) midiNode->midi_cc_value = 127; + break;} + case 2:{ + float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f); + midiNode->midi_pitch_bend += incr; + if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0; + if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383; + break;} + }; + } } } if(hovering_nodes.empty()){ diff --git a/src/state-manager.h b/src/state-manager.h index 7fd0457..7dc68bb 100644 --- a/src/state-manager.h +++ b/src/state-manager.h @@ -49,22 +49,38 @@ class AppState{ VEC_SPTR_Edge copy_connections; for(auto n : nodes){ - std::ranges::copy_if(n->connections.begin(), n->connections.end(), std::back_inserter(copy_connections), [nodes](SPTR_Edge e){ return std::ranges::contains(nodes, e->start) && std::ranges::contains(nodes, e->end);}); + for(auto c : n->connections){ + if(std::ranges::contains(nodes, c->start) && std::ranges::contains(nodes, c->end)) { + copy_connections.push_back(std::make_shared(*c)); + } + } } + std::cout << copy_connections.size() << std::endl; + + for(auto old_node : nodes){ + SPTR_Node new_node; + + if(old_node->getNodeType() == NodeType::MIDINODE) { + new_node = gm.copyNode(std::dynamic_pointer_cast(old_node), position + old_node->drag_offset); + } else { + new_node = gm.copyNode(old_node, position + old_node->drag_offset); + } - for(auto n : nodes){ - SPTR_Node old_node = n; - SPTR_Node new_node = gm.copyNode(n, position + n->drag_offset); new_node->copied = false; new_node->selected = false; for(auto c : copy_connections){ - if(c->start == old_node) c->start = new_node; - if(c->end == old_node) c->end = new_node; + if(c->start == old_node) { + c->start = new_node; + c->start->connections.push_back(c); + } + if(c->end == old_node) { + c->end = new_node; + c->end->connections.push_back(c); + } } } - - gm.edges.insert(gm.edges.end(), copy_connections.cbegin(), copy_connections.cend()); + std::ranges::copy(copy_connections.begin(), copy_connections.end(), std::back_inserter(gm.edges)); } void removeNodes(VEC_SPTR_Node nodes){ @@ -103,6 +119,10 @@ class AppState{ s->start = s->next; } + for(auto n : adjacent_nodes){ + std::erase_if(n->connections, [n, nodes](SPTR_Edge c){ return std::ranges::contains(nodes, c->start) || std::ranges::contains(nodes, c->end);}); + } + for(auto n : nodes){ std::erase_if(gm.edges, [n](SPTR_Edge c){ return c->start == n || c->end == n;}); }