connection split button added, but no functionality yes
This commit is contained in:
+11
-13
@@ -3,7 +3,6 @@
|
||||
#include "connection.h"
|
||||
#include "node-manager.h"
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
@@ -28,19 +27,12 @@ class ConnectionManager{
|
||||
std::vector<int> next_node_ids;
|
||||
|
||||
for(auto& c : connections){
|
||||
if((c.v1 == current && c.v1_v2) || (c.v2 == current && c.v2_v1)) {
|
||||
if((c.node_id_start == current && c.v1_v2) || (c.node_id_end == current && c.v2_v1)) {
|
||||
c.active = false;
|
||||
possible_connections.push_back(&c);
|
||||
next_node_ids.push_back( c.v1 == current ? c.v2 : c.v1 );
|
||||
next_node_ids.push_back( c.node_id_start == current ? c.node_id_end : c.node_id_start );
|
||||
}
|
||||
}
|
||||
|
||||
/*if(possible_connections.size() == 2) {*/
|
||||
/* int next = next_node_ids[0] == last ? next_node_ids[1] : next_node_ids[0];*/
|
||||
/* if(possible_connections[0]->v1 == next || possible_connections[0]->v2 == next) possible_connections[0]->active = true;*/
|
||||
/* if(possible_connections[1]->v1 == next || possible_connections[1]->v2 == next) possible_connections[1]->active = true;*/
|
||||
/* return next;*/
|
||||
/*}*/
|
||||
|
||||
if(possible_connections.empty()) return -1;
|
||||
|
||||
@@ -50,7 +42,7 @@ class ConnectionManager{
|
||||
Vec2D<float> coming_from = (nm->nodes.at(current).position - nm->nodes.at(last).position).norm();
|
||||
int i = 0;
|
||||
for(auto n : possible_connections){
|
||||
int next_position = n->v1 == current ? n->v2 : n->v1;
|
||||
int next_position = n->node_id_start == current ? n->node_id_end : n->node_id_start;
|
||||
float angle_v1_v2 = coming_from.norm().dot((nm->nodes.at(next_position).position - nm->nodes.at(current).position).norm());
|
||||
if(angle_v1_v2 > angle) {
|
||||
return_path = i;
|
||||
@@ -74,16 +66,22 @@ class ConnectionManager{
|
||||
}
|
||||
|
||||
possible_connections.at(return_path)->active = true;
|
||||
return possible_connections.at(return_path)->v1 == current ? possible_connections.at(return_path)->v2 : possible_connections.at(return_path)->v1;
|
||||
return possible_connections.at(return_path)->node_id_start == current ? possible_connections.at(return_path)->node_id_end : possible_connections.at(return_path)->node_id_start;
|
||||
}
|
||||
|
||||
void addConnection(int from, int to){
|
||||
connections.emplace_back(&nm->nodes, from, to);
|
||||
connections.emplace_back(nm, from, to);
|
||||
}
|
||||
|
||||
void splitConnection(Connection *c){
|
||||
Vec2D<float> center = c->node_start->position.center(c->node_end->position);
|
||||
|
||||
}
|
||||
|
||||
void drawConnections(Vec2D<float> *mouse_pos, Camera2D *cam){
|
||||
std::erase_if(connections, [](Connection c){ return c.remove == true;});
|
||||
for(auto& c : connections){
|
||||
if(c.split) splitConnection(&c);
|
||||
c.draw(mouse_pos, cam);
|
||||
}
|
||||
}
|
||||
|
||||
+25
-17
@@ -2,41 +2,49 @@
|
||||
|
||||
#include "button.h"
|
||||
#include "datatypes.h"
|
||||
#include "node-manager.h"
|
||||
#include "node.h"
|
||||
#include "raylib.h"
|
||||
|
||||
class Connection{
|
||||
|
||||
public:
|
||||
Connection(std::map<int, Node> *nodes, int v1, int v2) : v1(v1), v2(v2), nodes(nodes) {}
|
||||
Connection(NodeManager *nm, int v1, int v2) : node_id_start(v1), node_id_end(v2), nm(nm) {}
|
||||
|
||||
int v1;
|
||||
int v2;
|
||||
int node_id_start;
|
||||
int node_id_end;
|
||||
|
||||
std::map<int, Node> *nodes;
|
||||
Node* node_start;
|
||||
Node* node_end;
|
||||
|
||||
NodeManager *nm;
|
||||
|
||||
bool v1_v2 = true;
|
||||
bool v2_v1 = true;
|
||||
bool active = false;
|
||||
bool remove = false;
|
||||
bool config = false;
|
||||
bool split = false;
|
||||
|
||||
float connector_offset = 8.0f;
|
||||
float switches_offset = 25.0f;
|
||||
|
||||
void flip(){
|
||||
int vt = v1;
|
||||
v1 = v2;
|
||||
v2 = vt;
|
||||
int vt = node_id_start;
|
||||
node_id_start = node_id_end;
|
||||
node_id_end = vt;
|
||||
Node* nt = node_start;
|
||||
node_start = node_end;
|
||||
node_end = nt;
|
||||
}
|
||||
|
||||
void draw(Vec2D<float> *mouse_pos, Camera2D *cam){
|
||||
Vec2D<float> v1_position = nodes->at(v1).position - ((nodes->at(v1).position - nodes->at(v2).position)).norm() * (nodes->at(v1).radius + connector_offset);
|
||||
Vec2D<float> v2_position = nodes->at(v2).position - ((nodes->at(v2).position - nodes->at(v1).position)).norm() * (nodes->at(v2).radius + connector_offset);
|
||||
Vec2D<float> v1_position = nm->node(node_id_start)->position - ((nm->node(node_id_start)->position - nm->node(node_id_end)->position)).norm() * (nm->node(node_id_start)->radius + connector_offset);
|
||||
Vec2D<float> v2_position = nm->node(node_id_end)->position - ((nm->node(node_id_end)->position - nm->node(node_id_start)->position)).norm() * (nm->node(node_id_end)->radius + connector_offset);
|
||||
float v1_v2_distance = v1_position.dist(&v2_position);
|
||||
|
||||
float midi_gate_v1 = Clamp((4.f / 1000.f) * nodes->at(v1).midi_gate, 1.f, 4.f);
|
||||
float midi_gate_v2 = Clamp((4.f / 1000.f) * nodes->at(v2).midi_gate, 1.f, 4.f);
|
||||
float midi_gate_v1 = Clamp((4.f / 1000.f) * nm->node(node_id_start)->midi_gate, 1.f, 4.f);
|
||||
float midi_gate_v2 = Clamp((4.f / 1000.f) * nm->node(node_id_end)->midi_gate, 1.f, 4.f);
|
||||
// Line with small connector circles
|
||||
|
||||
Color c = {229, 181, 103, 255};
|
||||
@@ -51,11 +59,12 @@ class Connection{
|
||||
DrawCircle(v2_position.x, v2_position.y, midi_gate_v2, c);
|
||||
|
||||
if(v1_v2_distance < 100) switches_offset = v1_v2_distance/2.3f;
|
||||
Vec2D<float> from_to_handle = nodes->at(v1).position - ((nodes->at(v1).position - nodes->at(v2).position)).norm() * (nodes->at(v1).radius + switches_offset);
|
||||
Vec2D<float> to_from_handle = nodes->at(v2).position - ((nodes->at(v2).position - nodes->at(v1).position)).norm() * (nodes->at(v2).radius + switches_offset);
|
||||
Vec2D<float> middle_handle = nodes->at(v2).position - ((nodes->at(v2).position - nodes->at(v1).position))*0.5f;
|
||||
// Vec2D<float> config_handle = nodes.at(v2)->position - ((nodes.at(v2)->position - nodes.at(v1)->position))*0.66f;
|
||||
Vec2D<float> from_to_handle = nm->node(node_id_start)->position - ((nm->node(node_id_start)->position - nm->node(node_id_end)->position)).norm() * (nm->node(node_id_start)->radius + switches_offset);
|
||||
Vec2D<float> to_from_handle = nm->node(node_id_end)->position - ((nm->node(node_id_end)->position - nm->node(node_id_start)->position)).norm() * (nm->node(node_id_end)->radius + switches_offset);
|
||||
Vec2D<float> middle_handle = nm->node(node_id_end)->position - ((nm->node(node_id_end)->position - nm->node(node_id_start)->position))*0.4f;
|
||||
Vec2D<float> middle_handle_2 = nm->node(node_id_end)->position - ((nm->node(node_id_end)->position - nm->node(node_id_start)->position))*0.6f;
|
||||
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);
|
||||
|
||||
|
||||
// Dynamic opacity by distance to mouse
|
||||
@@ -81,7 +90,6 @@ class Connection{
|
||||
|
||||
|
||||
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) remove = true;
|
||||
//if(ViButton(mouse_pos, config_handle.x, config_handle.y, 8.0f, (Color){158, 134, 200, opacity})) config = !config;
|
||||
//if(ViButton(mouse_pos, config_handle.x + flip_handle.x, config_handle.y + flip_handle.y, 8.0f, (Color){158, 0, 200, opacity})) flip();
|
||||
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 50, 32, opacity} )) split = true;
|
||||
}
|
||||
};
|
||||
|
||||
+11
-7
@@ -75,7 +75,10 @@ class Vec2D{
|
||||
};
|
||||
|
||||
Vec2D norm() { return *this / length();};
|
||||
|
||||
|
||||
Vec2D center(Vec2D v){
|
||||
return Vec2D<T>{x,y} + (Vec2D<T>{x,y} - v)*0.5f;
|
||||
}
|
||||
|
||||
Vec2D& operator=(const Vec2D& vec){
|
||||
if (this == &vec){
|
||||
@@ -125,32 +128,32 @@ class Vec2D{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator+(const Vec2D<T>& left, const Vec2D<T>& right){
|
||||
Vec2D<T> operator+(const Vec2D<T> left, const Vec2D<T> right){
|
||||
return Vec2D<T>(left.x + right.x, left.y + right.y);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator-(const Vec2D<T>& left, const Vec2D<T>& right){
|
||||
Vec2D<T> operator-(const Vec2D<T> left, const Vec2D<T> right){
|
||||
return Vec2D<T>(left.x - right.x, left.y - right.y);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator*(const Vec2D<T>& left, const Vec2D<T>& right){
|
||||
Vec2D<T> operator*(const Vec2D<T> left, const Vec2D<T> right){
|
||||
return Vec2D<T>(left.x * right.x, left.y * right.y);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator/(const Vec2D<T>& left, const Vec2D<T>& right){
|
||||
Vec2D<T> operator/(const Vec2D<T> left, const Vec2D<T> right){
|
||||
return Vec2D<T>(left.x / right.x, left.y / right.y);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator/(const Vec2D<T>& left, T scalar){
|
||||
Vec2D<T> operator/(const Vec2D<T> left, T scalar){
|
||||
return Vec2D<T>(left.x / scalar, left.y / scalar);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vec2D<T> operator*(const Vec2D<T>& left, T scalar){
|
||||
Vec2D<T> operator*(const Vec2D<T> left, T scalar){
|
||||
return Vec2D<T>(left.x * scalar, left.y * scalar);
|
||||
};
|
||||
|
||||
@@ -180,6 +183,7 @@ struct MidiOut{
|
||||
};
|
||||
|
||||
namespace MIDI{
|
||||
inline std::vector<std::string> Fractions = {"1/32","1/16","3/32","1/8","5/32","3/16","7/32","1/4","9/32","5/16","11/32","3/8","13/32","7/16","15/32","1/2","17/32","9/16","19/32","5/8","21/32","11/16","23/32","3/4","25/32","13/16","27/32","7/8","29/32","15/16","31/32","1/1"};
|
||||
inline std::vector<std::string> Notes = {
|
||||
"C-1", "C#-1", "D-1", "D#-1", "E-1", "F-1", "F#-1", "G-1",
|
||||
"G#-1", "A-1", "A#-1", "B-1", "C0", "C#0", "D0", "D#0",
|
||||
|
||||
+4
-2
@@ -20,7 +20,9 @@ class NodeManager{
|
||||
std::vector<int> keys;
|
||||
int iterator = 0;
|
||||
|
||||
std::vector<std::string> fractions = {"1/32","1/16","3/32","1/8","5/32","3/16","7/32","1/4","9/32","5/16","11/32","3/8","13/32","7/16","15/32","1/2","17/32","9/16","19/32","5/8","21/32","11/16","23/32","3/4","25/32","13/16","27/32","7/8","29/32","15/16","31/32","1/1"};
|
||||
Node* node(int id){
|
||||
return &nodes.at(id);
|
||||
}
|
||||
|
||||
int getRandomNode(){
|
||||
std::vector<int> o;
|
||||
@@ -80,7 +82,7 @@ class NodeManager{
|
||||
for(auto it = (neighbors.begin()); it != neighbors.end(); it++, i++){
|
||||
float d = it->position.dist(n.position);
|
||||
if(d > 0 && d < min_d*1.5 && d < 960) {
|
||||
std::string frac = fractions.at((int)Clamp(round(d/60) - 1, 0, 31));
|
||||
std::string frac = MIDI::Fractions.at((int)Clamp(round(d/60) - 1, 0, 31));
|
||||
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
|
||||
Vector2 text_length_frac = MeasureTextEx(GetFontDefault(), frac.c_str(), 10.0f, 2.0f);
|
||||
|
||||
|
||||
+7
-7
@@ -48,7 +48,7 @@ class AppState{
|
||||
auto copy_nodes_ids = nm.nodes | std::ranges::views::values | std::ranges::views::filter([](Node n){return n.copied;}) | std::views::transform([](Node n){return n.id;}) | std::ranges::to<std::vector<int>>();
|
||||
|
||||
std::vector<Connection> copy_connections;
|
||||
std::ranges::copy_if(cm.connections, std::back_inserter(copy_connections), [copy_nodes_ids](Connection c){return std::ranges::contains(copy_nodes_ids, c.v1) && std::ranges::contains(copy_nodes_ids, c.v2);});
|
||||
std::ranges::copy_if(cm.connections, std::back_inserter(copy_connections), [copy_nodes_ids](Connection c){return std::ranges::contains(copy_nodes_ids, c.node_id_start) && std::ranges::contains(copy_nodes_ids, c.node_id_end);});
|
||||
|
||||
for(auto &n : copy_nodes_ids){
|
||||
int old_id = n;
|
||||
@@ -57,8 +57,8 @@ class AppState{
|
||||
nm.nodes[new_id].selected = true;
|
||||
|
||||
for(auto &c : copy_connections){
|
||||
if(c.v1 == old_id) c.v1 = new_id;
|
||||
if(c.v2 == old_id) c.v2 = new_id;
|
||||
if(c.node_id_start == old_id) c.node_id_start = new_id;
|
||||
if(c.node_id_end == old_id) c.node_id_end = new_id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,13 +78,13 @@ class AppState{
|
||||
erase_nodes_ids.push_back(e.id);
|
||||
}
|
||||
|
||||
auto erase_connections = cm.connections | std::ranges::views::filter([erase_nodes_ids](Connection c){ return std::ranges::contains(erase_nodes_ids, c.v1) || std::ranges::contains(erase_nodes_ids, c.v2);});
|
||||
auto erase_connections = cm.connections | std::ranges::views::filter([erase_nodes_ids](Connection c){ return std::ranges::contains(erase_nodes_ids, c.node_id_start) || std::ranges::contains(erase_nodes_ids, c.node_id_end);});
|
||||
|
||||
std::vector<int> adjacent_nodes_ids;
|
||||
|
||||
for(auto &c : erase_connections){
|
||||
if(!nm.nodes.at(c.v1).selected) adjacent_nodes_ids.push_back(c.v1);
|
||||
if(!nm.nodes.at(c.v2).selected) adjacent_nodes_ids.push_back(c.v2);
|
||||
if(!nm.nodes.at(c.node_id_start).selected) adjacent_nodes_ids.push_back(c.node_id_start);
|
||||
if(!nm.nodes.at(c.node_id_end).selected) adjacent_nodes_ids.push_back(c.node_id_end);
|
||||
}
|
||||
|
||||
auto reroute_signals = sm.signals | std::ranges::views::filter([erase_nodes_ids](Signal s){
|
||||
@@ -113,7 +113,7 @@ class AppState{
|
||||
}
|
||||
|
||||
for(auto &n : erase_nodes){
|
||||
std::erase_if(cm.connections, [n](Connection c){ return c.v1 == n.id || c.v2 == n.id;});
|
||||
std::erase_if(cm.connections, [n](Connection c){ return c.node_id_start == n.id || c.node_id_end == n.id;});
|
||||
}
|
||||
std::erase_if(nm.nodes, [](std::pair<int, Node> n){ return n.second.erase;});
|
||||
nm.keys.clear();
|
||||
|
||||
Reference in New Issue
Block a user