copy nodes with connections
This commit is contained in:
+68
-43
@@ -40,35 +40,36 @@ bool mouse_clicked = false;
|
||||
bool mouse_touched = false;
|
||||
bool mouse_dragging = false;
|
||||
|
||||
//#include "ui.h"
|
||||
|
||||
int main(){
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
InitWindow(2560, 1440, "VISEQ");
|
||||
|
||||
InitWindow(1920, 1080, "VISEQ");
|
||||
|
||||
int current_monitor = GetCurrentMonitor();
|
||||
int monitor_width = GetMonitorWidth(current_monitor);
|
||||
int monitor_height = GetMonitorHeight(current_monitor);
|
||||
|
||||
SetWindowMonitor(current_monitor);
|
||||
SetWindowState(FLAG_WINDOW_RESIZABLE);
|
||||
|
||||
SetWindowSize(monitor_width - 300, monitor_height - 300);
|
||||
|
||||
//ToggleFullscreen();
|
||||
|
||||
app.ui.init();
|
||||
|
||||
int monitor = 1; //GetCurrentMonitor();
|
||||
|
||||
SetWindowMonitor(monitor);
|
||||
|
||||
app.settings.fps = 1.0f;
|
||||
app.settings.fps = 60.0f;
|
||||
app.settings.bpm = 120.0f;
|
||||
app.settings.grid = 120.0f; //round(((app.settings.fps / (app.settings.bpm / 60.0f)) * app.settings.speed) / 4.0f); // from quarter notes to 16th notes = div by 4
|
||||
// app.settings.speed = round((((app.settings.fps / (app.settings.bpm / 60.0f)) / app.settings.grid) / 4.0f) / 10.0f) * 10.0f;
|
||||
app.settings.grid = 120.0f; // 120px for a 16th note
|
||||
|
||||
// 16th note = 120px (festgelegt)
|
||||
// ganze note = 1920px
|
||||
// ganze note bei 120bpm = 2s
|
||||
// 120bpm = 960px/s
|
||||
app.settings.speed = (app.settings.grid * 8.0f) * (app.settings.bpm / 120.f);
|
||||
|
||||
app.settings.width = GetMonitorWidth(monitor);
|
||||
app.settings.height = GetMonitorHeight(monitor);
|
||||
app.settings.width = monitor_width;
|
||||
app.settings.height = monitor_height;
|
||||
|
||||
SetTargetFPS(60.0f);
|
||||
SetTargetFPS(app.settings.fps);
|
||||
|
||||
camera.target = (Vector2){ app.settings.width/2.0f, app.settings.height/2.0f };
|
||||
camera.offset = (Vector2){ app.settings.width/2.0f, app.settings.height/2.0f };
|
||||
@@ -86,24 +87,15 @@ int main(){
|
||||
app.cm.addConnection(app.nm.nodes[i].id, app.nm.nodes[(i+1) % 8].id);
|
||||
}
|
||||
|
||||
app.sm.addSignalAtNode((app.nm.nodes | std::views::values).front().id);
|
||||
|
||||
app.sm.addSignalAtNode((app.nm.nodes | std::views::values).front().id);
|
||||
app.sm.startSignalThread();
|
||||
|
||||
Vec2D<float> drag_offset;
|
||||
|
||||
Vec2D<float> cam_drag_offset;
|
||||
Vec2D<float> cam_mouse_drag_offset;
|
||||
|
||||
double drag_timer = GetTime();
|
||||
|
||||
enum InteractionState {HOVER_CANVAS, HOVER_NODE, HOVER_CONNECTOR, DRAG_NODE, CONNECT_NODE, DRAW_SELECTION, DELETE_SELECTED_NODES};
|
||||
enum InteractionState {HOVER_CANVAS, HOVER_NODE, HOVER_CONNECTOR, DRAG_NODE, CONNECT_NODE, DRAW_SELECTION, DELETE_SELECTED_NODES, COPY_SELECTED_NODES, PASTE_SELECTED_NODES};
|
||||
InteractionState istate = HOVER_CANVAS;
|
||||
|
||||
Vec2D<float> select_start;
|
||||
Rectangle selection;
|
||||
|
||||
ToggleFullscreen();
|
||||
|
||||
while(!WindowShouldClose()){
|
||||
|
||||
@@ -129,6 +121,7 @@ int main(){
|
||||
Vec2D<float> delta = mouse_delta * (-1.0f/camera.zoom);
|
||||
|
||||
auto dragging_nodes = app.nm.nodes | std::ranges::views::values | std::ranges::views::filter([](Node n) { return n.dragging;});
|
||||
auto copied_nodes = app.nm.nodes | std::ranges::views::values | std::ranges::views::filter([](Node n) { return n.copied;});
|
||||
auto connecting_nodes = app.nm.nodes | std::ranges::views::values| std::ranges::views::filter([](Node n) { return n.connecting;});
|
||||
auto selected_nodes = app.nm.nodes | std::ranges::views::values| std::ranges::views::filter([](Node n) { return n.selected && !n.dragging;});
|
||||
auto hovering_nodes = app.nm.nodes | std::ranges::views::values| std::ranges::views::filter([&mouse_pos](Node n) { return CheckCollisionPointCircle(mouse_pos, n.position, n.radius);});
|
||||
@@ -143,6 +136,9 @@ int main(){
|
||||
if(!connecting_nodes.empty()) istate = InteractionState::CONNECT_NODE;
|
||||
|
||||
if(!selected_nodes.empty() && IsKeyPressed(KEY_DELETE)) istate = InteractionState::DELETE_SELECTED_NODES;
|
||||
if(!selected_nodes.empty() && IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)) istate = InteractionState::COPY_SELECTED_NODES;
|
||||
|
||||
if(!copied_nodes.empty() && IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V)) istate = InteractionState::PASTE_SELECTED_NODES;
|
||||
|
||||
switch(istate){
|
||||
case InteractionState::HOVER_CANVAS:
|
||||
@@ -200,22 +196,31 @@ int main(){
|
||||
}
|
||||
case InteractionState::DRAG_NODE:
|
||||
{
|
||||
if(IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
dragging_nodes.front().position = (Vec2D<float>){round((mouse_pos.x+dragging_nodes.front().drag_offset.x)/app.settings.grid)*app.settings.grid, round((mouse_pos.y+dragging_nodes.front().drag_offset.y)/app.settings.grid)*app.settings.grid};
|
||||
} else {
|
||||
dragging_nodes.front().position = mouse_pos + dragging_nodes.front().drag_offset;
|
||||
}
|
||||
|
||||
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;
|
||||
if(!dragging_nodes.empty()){
|
||||
for(auto &n : selected_nodes){
|
||||
n.picked_up = false;
|
||||
if(!n.picked_up) n.drag_offset = n.position - dragging_nodes.front().position;
|
||||
n.picked_up = true;
|
||||
}
|
||||
|
||||
if(IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
dragging_nodes.front().position = (Vec2D<float>){round((mouse_pos.x+dragging_nodes.front().drag_offset.x)/app.settings.grid)*app.settings.grid, round((mouse_pos.y+dragging_nodes.front().drag_offset.y)/app.settings.grid)*app.settings.grid};
|
||||
} else {
|
||||
dragging_nodes.front().position = mouse_pos + dragging_nodes.front().drag_offset;
|
||||
}
|
||||
|
||||
for(auto &n : selected_nodes){
|
||||
n.position = dragging_nodes.front().position + n.drag_offset;
|
||||
}
|
||||
|
||||
if(mouse_released) {
|
||||
for(auto &n : dragging_nodes){
|
||||
n.dragging = false;
|
||||
n.picked_up = false;
|
||||
}
|
||||
for(auto &n : selected_nodes){
|
||||
n.picked_up = false;
|
||||
n.dragging = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -257,6 +262,26 @@ int main(){
|
||||
app.removeNodes();
|
||||
break;
|
||||
}
|
||||
case InteractionState::COPY_SELECTED_NODES:
|
||||
{
|
||||
for(auto &n: copied_nodes){
|
||||
n.copied = false;
|
||||
}
|
||||
for(auto &n: selected_nodes){
|
||||
n.copied = true;
|
||||
n.selected = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case InteractionState::PASTE_SELECTED_NODES:
|
||||
{
|
||||
for(auto &n: copied_nodes){
|
||||
n.drag_offset = (n.position - copied_nodes.front().position);
|
||||
}
|
||||
// app.nm.copyNodes(mouse_pos);
|
||||
app.copyNodesAndConnections(mouse_pos);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
float wheel = GetMouseWheelMove();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "node.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class NodeManager{
|
||||
@@ -21,6 +23,28 @@ class NodeManager{
|
||||
return o.front();
|
||||
}
|
||||
|
||||
void copyNodes(Vec2D<float> position){
|
||||
for(auto n: nodes | std::ranges::views::filter([](std::pair<int, Node> n){ return n.second.copied;})){
|
||||
n.second.position = position + n.second.drag_offset;
|
||||
n.second.id = iterator;
|
||||
n.second.copied = false;
|
||||
n.second.selected = true;
|
||||
nodes.insert(std::make_pair(iterator, n.second));
|
||||
keys.push_back(iterator);
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
|
||||
int copyNode(int id, Vec2D<float> position){
|
||||
Node n = nodes.at(id);
|
||||
n.position = position;
|
||||
n.id = iterator;
|
||||
nodes.insert(std::make_pair(iterator, n));
|
||||
keys.push_back(iterator);
|
||||
iterator++;
|
||||
return iterator - 1;
|
||||
}
|
||||
|
||||
int addNode(float x, float y){
|
||||
return addNode(Vec2D<float>(x,y));
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class Node : public Movable{
|
||||
bool selected = false;
|
||||
bool erase = false;
|
||||
bool highlighted = false;
|
||||
bool copied = false;
|
||||
|
||||
int midi_out = -1;
|
||||
|
||||
|
||||
+19
-2
@@ -44,6 +44,25 @@ class AppState{
|
||||
}
|
||||
}
|
||||
|
||||
void copyNodesAndConnections(Vec2D<float> position){
|
||||
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);});
|
||||
|
||||
for(auto &n : copy_nodes_ids){
|
||||
int old_id = n;
|
||||
int new_id = nm.copyNode(n, position + nm.nodes[n].drag_offset);
|
||||
|
||||
for(auto &c : copy_connections){
|
||||
if(c.v1 == old_id) c.v1 = new_id;
|
||||
if(c.v2 == old_id) c.v2 = new_id;
|
||||
}
|
||||
}
|
||||
|
||||
cm.connections.insert(cm.connections.end(), copy_connections.cbegin(), copy_connections.cend());
|
||||
}
|
||||
|
||||
void removeNodes(){
|
||||
|
||||
for(auto &n : nm.nodes){
|
||||
@@ -66,8 +85,6 @@ class AppState{
|
||||
if(!nm.nodes.at(c.v2).selected) adjacent_nodes_ids.push_back(c.v2);
|
||||
}
|
||||
|
||||
// std::ranges::for_each(adjacent_nodes_ids, [this](int id){ nm.nodes.at(id).highlighted = true;} );
|
||||
|
||||
auto reroute_signals = sm.signals | std::ranges::views::filter([erase_nodes_ids](Signal s){
|
||||
return std::ranges::contains(erase_nodes_ids, s.next);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user