split edge: check, copy paste: check with a little bug
This commit is contained in:
+1
-1
@@ -96,7 +96,7 @@ class Vec2D{
|
|||||||
Vec2D norm() { return *this / length();};
|
Vec2D norm() { return *this / length();};
|
||||||
|
|
||||||
Vec2D center(Vec2D v){
|
Vec2D center(Vec2D v){
|
||||||
return Vec2D<T>{x,y} + (Vec2D<T>{x,y} - v)*0.5f;
|
return Vec2D<T>{x,y} - (Vec2D<T>{x,y} - v)*0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D& operator=(const Vec2D& vec){
|
Vec2D& operator=(const Vec2D& vec){
|
||||||
|
|||||||
@@ -31,9 +31,4 @@ class Edge : public GraphItem{
|
|||||||
void draw(Vec2D<float> mouse_pos, Camera2D cam) {
|
void draw(Vec2D<float> mouse_pos, Camera2D cam) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(){
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
+33
-19
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -30,6 +31,7 @@ class GraphManager{
|
|||||||
VEC_SPTR_Edge edges;
|
VEC_SPTR_Edge edges;
|
||||||
|
|
||||||
VEC_SPTR_Edge remove_edges;
|
VEC_SPTR_Edge remove_edges;
|
||||||
|
VEC_SPTR_Edge split_edges;
|
||||||
|
|
||||||
std::map<SPTR_Node, int> counter;
|
std::map<SPTR_Node, int> counter;
|
||||||
|
|
||||||
@@ -45,32 +47,32 @@ class GraphManager{
|
|||||||
return std::dynamic_pointer_cast<Edge>(o.front());
|
return std::dynamic_pointer_cast<Edge>(o.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyNodes(VEC_SPTR_Node nodes, Vec2D<float> position){
|
void copyNodes(VEC_SPTR_Node _nodes, Vec2D<float> position){
|
||||||
for(auto n: nodes){
|
for(auto n: _nodes){
|
||||||
auto nc = std::make_shared<Node>(*n);
|
nodes.insert(nodes.end(), std::make_shared<Node>(*n));
|
||||||
nc->position = position + nc->drag_offset;
|
nodes.back()->setPosition(position + nodes.back()->drag_offset);
|
||||||
nc->selected = true;
|
nodes.back()->selected = false;
|
||||||
nodes.push_back(nc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyNodes(std::vector<std::shared_ptr<MidiNode>> nodes, Vec2D<float> position){
|
void copyNodes(std::vector<std::shared_ptr<MidiNode>> _nodes, Vec2D<float> position){
|
||||||
for(auto n: nodes){
|
for(auto n: _nodes){
|
||||||
std::shared_ptr<MidiNode> nc = std::make_shared<MidiNode>(*n);
|
nodes.insert(nodes.end(), std::make_shared<MidiNode>(*n));
|
||||||
nc->position = position + nc->drag_offset;
|
nodes.back()->setPosition(position + nodes.back()->drag_offset);
|
||||||
nc->selected = true;
|
nodes.back()->selected = false;
|
||||||
nodes.push_back(nc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPTR_Node copyNode(SPTR_Node n, Vec2D<float> position){
|
SPTR_Node copyNode(SPTR_Node n, Vec2D<float> position){
|
||||||
nodes.emplace_back(std::make_shared<Node>(*n));
|
std::cout << "copy basenode" << std::endl;
|
||||||
|
nodes.insert(nodes.end(), std::make_shared<Node>(*n));
|
||||||
nodes.back()->setPosition(position);
|
nodes.back()->setPosition(position);
|
||||||
return nodes.back();
|
return nodes.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Node> copyNode(std::shared_ptr<MidiNode> n, Vec2D<float> position){
|
SPTR_Node copyNode(std::shared_ptr<MidiNode> n, Vec2D<float> position){
|
||||||
nodes.emplace_back(std::make_shared<Node>(*n));
|
std::cout << "copy midinode" << std::endl;
|
||||||
|
nodes.insert(nodes.end(), std::make_shared<MidiNode>(*n));
|
||||||
nodes.back()->setPosition(position);
|
nodes.back()->setPosition(position);
|
||||||
return nodes.back();
|
return nodes.back();
|
||||||
}
|
}
|
||||||
@@ -131,15 +133,28 @@ class GraphManager{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addConnection(SPTR_Node from, SPTR_Node to){
|
void addConnection(SPTR_Node from, SPTR_Node to){
|
||||||
|
if(from != to) {
|
||||||
edges.emplace_back(std::make_shared<Edge>());
|
edges.emplace_back(std::make_shared<Edge>());
|
||||||
edges.back()->start = from;
|
edges.back()->start = from;
|
||||||
edges.back()->end = to;
|
edges.back()->end = to;
|
||||||
from->connections.push_back(edges.back());
|
from->connections.push_back(edges.back());
|
||||||
to->connections.push_back(edges.back());
|
to->connections.push_back(edges.back());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void splitEdge(SPTR_Edge edge){
|
void splitEdge(SPTR_Edge edge){
|
||||||
|
split_edges.push_back(edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
void splitEdges(){
|
||||||
|
for(auto s : split_edges){
|
||||||
|
Vec2D<float> 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){
|
void removeEdge(SPTR_Edge edge){
|
||||||
@@ -152,12 +167,13 @@ class GraphManager{
|
|||||||
std::erase(edge->end->connections, edge);
|
std::erase(edge->end->connections, edge);
|
||||||
std::erase(edges, edge);
|
std::erase(edges, edge);
|
||||||
}
|
}
|
||||||
|
remove_edges.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawEdges(Vec2D<float> mouse_pos, Camera2D cam){
|
void drawEdges(Vec2D<float> mouse_pos, Camera2D cam){
|
||||||
// std::erase_if(connections, [](Connection c){ return c.remove == true;});
|
|
||||||
if(!remove_edges.empty()) removeEdges();
|
if(!remove_edges.empty()) removeEdges();
|
||||||
for(auto& c : edges){
|
if(!split_edges.empty()) splitEdges();
|
||||||
|
for(auto c : edges){
|
||||||
Vec2D<float> v1_position = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c->connector_offset);
|
Vec2D<float> v1_position = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c->connector_offset);
|
||||||
Vec2D<float> v2_position = c->end->position - ((c->end->position - c->start->position)).norm() * (c->end->radius + c->connector_offset);
|
Vec2D<float> 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);
|
float v1_v2_distance = v1_position.dist(&v2_position);
|
||||||
@@ -185,7 +201,6 @@ class GraphManager{
|
|||||||
Vec2D<float> 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<float> 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<float> 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);
|
Vec2D<float> 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
|
// Dynamic opacity by distance to mouse
|
||||||
unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f);
|
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);
|
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});
|
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.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);
|
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 125, 62, opacity} )) splitEdge(c);
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "midi-node.h"
|
#include "midi-node.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -291,6 +292,8 @@ int main(){
|
|||||||
case InteractionState::COPY_SELECTED_NODES:
|
case InteractionState::COPY_SELECTED_NODES:
|
||||||
{
|
{
|
||||||
std::ranges::copy(selected_nodes.begin(), selected_nodes.end(), std::back_inserter(copied_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;
|
break;
|
||||||
}
|
}
|
||||||
case InteractionState::PASTE_SELECTED_NODES:
|
case InteractionState::PASTE_SELECTED_NODES:
|
||||||
@@ -299,7 +302,7 @@ int main(){
|
|||||||
n->drag_offset = (n->position - copied_nodes.front()->position);
|
n->drag_offset = (n->position - copied_nodes.front()->position);
|
||||||
}
|
}
|
||||||
app.copyNodesAndConnections(copied_nodes, mouse_pos);
|
app.copyNodesAndConnections(copied_nodes, mouse_pos);
|
||||||
copied_nodes.clear();
|
//copied_nodes.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -307,7 +310,12 @@ int main(){
|
|||||||
float wheel = GetMouseWheelMove();
|
float wheel = GetMouseWheelMove();
|
||||||
if(wheel != 0){
|
if(wheel != 0){
|
||||||
if(!hovering_nodes.empty() && hovering_nodes.front()->getNodeType() == NodeType::MIDINODE) {
|
if(!hovering_nodes.empty() && hovering_nodes.front()->getNodeType() == NodeType::MIDINODE) {
|
||||||
std::shared_ptr<MidiNode> midiNode = std::dynamic_pointer_cast<MidiNode>(hovering_nodes.front());
|
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);});
|
||||||
|
|
||||||
|
for(auto n : modify_nodes){
|
||||||
|
std::shared_ptr<MidiNode> midiNode = std::dynamic_pointer_cast<MidiNode>(n);
|
||||||
if(IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){
|
if(IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){
|
||||||
switch(app.settings.mode){
|
switch(app.settings.mode){
|
||||||
case 0:{
|
case 0:{
|
||||||
@@ -329,11 +337,11 @@ int main(){
|
|||||||
if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0;
|
if(midiNode->midi_pitch_bend < 0 ) midiNode->midi_pitch_bend = 0;
|
||||||
if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383;
|
if(midiNode->midi_pitch_bend > 16383 ) midiNode->midi_pitch_bend = 16383;
|
||||||
|
|
||||||
} else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_ALT)) {
|
} else if(IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_ALT)) {
|
||||||
midiNode->midi_velocity += wheel;
|
midiNode->midi_velocity += wheel;
|
||||||
if(midiNode->midi_velocity < 0 ) midiNode->midi_velocity = 127;
|
if(midiNode->midi_velocity < 0 ) midiNode->midi_velocity = 127;
|
||||||
if(midiNode->midi_velocity > 127 ) midiNode->midi_velocity = 0;
|
if(midiNode->midi_velocity > 127 ) midiNode->midi_velocity = 0;
|
||||||
} else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_ALT)) {
|
} else if(IsKeyDown(KEY_LEFT_ALT)) {
|
||||||
switch(app.settings.mode){
|
switch(app.settings.mode){
|
||||||
case 0:{
|
case 0:{
|
||||||
float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f);
|
float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f);
|
||||||
@@ -354,6 +362,7 @@ int main(){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(hovering_nodes.empty()){
|
if(hovering_nodes.empty()){
|
||||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||||
camera.offset = GetMousePosition();
|
camera.offset = GetMousePosition();
|
||||||
|
|||||||
+28
-8
@@ -49,22 +49,38 @@ class AppState{
|
|||||||
|
|
||||||
VEC_SPTR_Edge copy_connections;
|
VEC_SPTR_Edge copy_connections;
|
||||||
for(auto n : nodes){
|
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<Edge>(*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<MidiNode>(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->copied = false;
|
||||||
new_node->selected = false;
|
new_node->selected = false;
|
||||||
|
|
||||||
for(auto c : copy_connections){
|
for(auto c : copy_connections){
|
||||||
if(c->start == old_node) c->start = new_node;
|
if(c->start == old_node) {
|
||||||
if(c->end == old_node) c->end = new_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){
|
void removeNodes(VEC_SPTR_Node nodes){
|
||||||
@@ -103,6 +119,10 @@ class AppState{
|
|||||||
s->start = s->next;
|
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){
|
for(auto n : nodes){
|
||||||
std::erase_if(gm.edges, [n](SPTR_Edge c){ return c->start == n || c->end == n;});
|
std::erase_if(gm.edges, [n](SPTR_Edge c){ return c->start == n || c->end == n;});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user