Node interactions working again, graph editing functions not complete yet

This commit is contained in:
Sebastian
2024-11-30 02:54:40 +01:00
parent 635c94e3cf
commit fcc5d74e18
12 changed files with 343 additions and 441 deletions
+8 -115
View File
@@ -2,17 +2,15 @@
#include <filesystem>
#include <fstream>
#include "interaction-manager.h"
#include "nlohmann/json.hpp"
#include "clipboard.h"
#include "datatypes.h"
#include "canvas.h"
#include "graph-manager.h"
#include "interaction-event.h"
#include "midi-node.h"
#include "mouse.h"
#include "node.h"
#include "raylib.h"
#include "selectable.h"
#include "signal-manager.h"
#include "state.h"
#include "ui.h"
@@ -30,18 +28,18 @@ namespace VISEQ::APP {
class AppManager{
public:
AppManager() : sm(&gm, &mutex), mouse(&gm), ui(&sm, &gm) {}
AppManager() : sm(&gm, &mutex), im(&gm, &sm, canvas), mouse(&gm), ui(&sm, &gm) {}
std::mutex mutex;
std::shared_ptr<APP::State> state = APP::State::get();
std::shared_ptr<CANVAS::Canvas> canvas = std::make_shared<CANVAS::Canvas>();
VISEQ::GRAPH::GraphManager gm;
VISEQ::SIGNAL::SignalManager sm;
VISEQ::APP::Clipboard cb;
VISEQ::INTERACTION::InteractionManager im;
VISEQ::APP::Mouse mouse;
std::shared_ptr<APP::State> state = APP::State::get();
UI::AppUI ui;
void init(){
@@ -152,104 +150,6 @@ namespace VISEQ::APP {
}
}
void removeNodes(VEC_SPTR_Node nodes){
VEC_SPTR_Node adjacent_nodes = gm.getAdjacentNodes(nodes);
sm.rerouteSignal(nodes, adjacent_nodes);
sm.rebaseSignal(nodes);
gm.removeNodesAndEdges(nodes);
}
void doInteraction(){
bool exit = false;
bool once = false;
state->mouse_z = canvas->z_index;
while(event_queue.size() > 0 && !exit){
auto e = event_queue.front();
std::cout << e.item->getType() << " " << e.action << std::endl;
if(e.action == Interaction::HOVER){
state->mouse_z = e.item->z_index;
std::cout << state->mouse_z << std::endl;
}
if(e.item->getType() == GraphItemType::CANVAS) {
if(e.action == Interaction::SELECT) {
gm.select();
std::cout << "app canvas select" << std::endl;
canvas->clearSelectionRect();
}
if(e.action == Interaction::DESELECT) {
std::cout << "app canvas deselect" << std::endl;
gm.deselect();
}
}
if(!once && e.item->getType() == GraphItemType::NODE){
auto node = std::dynamic_pointer_cast<Node>(e.item);
if(e.action == Interaction::PICKUP) {
node->pickUp();
if(node->selected){
for(auto s : gm.selected_nodes){
s->pickUp(node->position);
}
}
once = true;
}
if(e.action == Interaction::DRAG) {
if(KEYS_DOWN.ctrl) node->drag(MOD_MOUSE);
else node->drag(MOD_MOUSE + node->drag_offset);
if(node->selected){
for(auto s : gm.selected_nodes){
s->drag(MOD_MOUSE + s->drag_offset);
}
}
once = true;
}
if(e.action == Interaction::PUTDOWN) {
node->putDown();
if(node->selected){
for(auto s : gm.selected_nodes){
s->putDown();
}
}
}
}
if(exit) break;
if(!once && (e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS)) {
switch(e.action){
case VISEQ::APP::Interaction::PICKUP:
{
e.item->pickUp();
once = true;
break;
}
case VISEQ::APP::Interaction::DRAG:
{
e.item->drag(MOD_MOUSE);
once = true;
break;
}
case VISEQ::APP::Interaction::PUTDOWN:
{
e.item->putDown();
break;
}
default:
{}
}
}
event_queue.pop_front();
}
event_queue.clear();
}
void update(){
state->update(canvas->camera);
canvas->update();
@@ -258,18 +158,9 @@ namespace VISEQ::APP {
updateMidiPorts();
mutex.unlock();
doInteraction();
mouse.update();
im.update();
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_C)){
VEC_SPTR_Node selected_nodes = gm.getSelection();
if(!selected_nodes.empty()) cb.pushNodes(selected_nodes);
}
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_V)){
VEC_SPTR_Node paste_nodes = cb.pullNodes();
if(!paste_nodes.empty()) gm.pasteNodesAndEdges(paste_nodes, MOD_MOUSE);
}
}
void draw(){
@@ -282,6 +173,8 @@ namespace VISEQ::APP {
gm.drawEdges(SCREEN_MOUSE, canvas->camera);
sm.drawSignals(SCREEN_MOUSE, canvas->camera);
im.draw();
canvas->drawEnd();
drawUI();
EndDrawing();
+1
View File
@@ -57,6 +57,7 @@ namespace VISEQ::GRAPH {
if(new_partner) {
//TODO what happens if a new partner is connected?
new_partner = false;
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ namespace VISEQ::GRAPH::NODES {
namespace VISEQ::GRAPH{
enum GraphItemType {NODE, EDGE, CONNECTOR, CANVAS};
enum GraphItemType {NODE, EDGE, CONNECTOR, CANVAS, HANDLE};
enum NodeType {OSCNODE, MIDINODE, CONFIGNODE};
enum EdgeType {MIDIEDGE, CONFIGEDGE};
}
+1
View File
@@ -1,5 +1,6 @@
#pragma once
#include "connector.h"
#include "graph-item.h"
#include <memory>
#include "node.h"
+43 -39
View File
@@ -2,7 +2,6 @@
#include "datatypes.h"
#include "draggable.h"
#include "state.h"
#include "vmath.h"
#include "raylib.h"
@@ -34,14 +33,19 @@ using namespace VISEQ::GRAPH::EDGES;
namespace VISEQ::GRAPH {
class GraphManager{
class GraphManager : public std::enable_shared_from_this<GraphManager>{
public:
GraphManager() {}
std::shared_ptr<GraphManager> getPtr(){
return shared_from_this();
}
NODES::VEC_SPTR_Node nodes;
EDGES::VEC_SPTR_Edge edges;
std::map<SPTR_Node, VEC_SPTR_Edge> connections;
EDGES::VEC_SPTR_Edge remove_edges;
EDGES::VEC_SPTR_Edge split_edges;
@@ -52,16 +56,24 @@ namespace VISEQ::GRAPH {
std::shared_ptr<APP::State> state = APP::State::get();
NODES::SPTR_Node getRandomNode(){
VEC_SPTR_GraphItem o;
std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<VISEQ::GRAPH::NODES::Node>(o.front());
SPTR_Node addMidiNode(Vec2Df position){
nodes.emplace_back(std::make_shared<MidiNode>(position));
return nodes.back();
}
EDGES::SPTR_Edge getRandomEdge(){
VEC_SPTR_GraphItem o;
std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<VISEQ::GRAPH::EDGES::Edge>(o.front());
void addNode(SPTR_Node node){
nodes.insert(nodes.end(), node);
nodes.back()->init();
}
void addConnection(SPTR_Node from, SPTR_Node to){
if(from != to) {
edges.emplace_back(std::make_shared<Edge>());
edges.back()->start = from;
edges.back()->end = to;
from->connections.push_back(edges.back());
to->connections.push_back(edges.back());
}
}
void select(){
@@ -85,11 +97,6 @@ namespace VISEQ::GRAPH {
//return nodes | RANGE_FILTER([](SPTR_Node n){return n->selected;}) | std::ranges::to<VEC_SPTR_Node>();
}
void addNode(SPTR_Node node){
nodes.insert(nodes.end(), node);
nodes.back()->init();
}
void copyNodes(VEC_SPTR_Node _nodes, Vec2Df position){
for(auto n: _nodes){
nodes.insert(nodes.end(), std::make_shared<Node>(*n));
@@ -120,11 +127,6 @@ namespace VISEQ::GRAPH {
return nodes.back();
}
SPTR_Node addMidiNode(Vec2Df position){
nodes.emplace_back(std::make_shared<MidiNode>(position));
return nodes.back();
}
void setNodeMode(int mode){
for(auto n: nodes){
n->SMode(mode);
@@ -135,11 +137,29 @@ namespace VISEQ::GRAPH {
counter.clear();
}
SPTR_Node next_node(SPTR_Node current, SPTR_Node last){
std::vector<std::shared_ptr<Connector>> active_connectors;
NODES::SPTR_Node getRandomNode(){
VEC_SPTR_GraphItem o;
std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<VISEQ::GRAPH::NODES::Node>(o.front());
}
EDGES::SPTR_Edge getRandomEdge(){
VEC_SPTR_GraphItem o;
std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<VISEQ::GRAPH::EDGES::Edge>(o.front());
}
SPTR_Node getClosestNode(Vec2Df position){
auto neighbors = nodes | RANGE_FILTER([](SPTR_Node n){ return !n->picked_up;}) | std::ranges::to<VEC_SPTR_Node>();
std::sort(neighbors.begin(), neighbors.end(), [position](SPTR_Node na, SPTR_Node nb){ return na->position.dist(position) < nb->position.dist(position);});
return neighbors.front();
}
/*SPTR_Node next_node(SPTR_Node current, SPTR_Node last){*/
/* std::vector<std::shared_ptr<Connector>> active_connectors;*/
/**/
/*}*/
SPTR_Node next(SPTR_Node current, SPTR_Node last){
VEC_SPTR_Edge possible_connections = current->connections | RANGE_FILTER([current](SPTR_Edge c){
return (c->start == current && c->pass_forward) || (c->end == current && c->pass_backward);
@@ -180,22 +200,6 @@ namespace VISEQ::GRAPH {
return possible_connections.at(return_path)->getNextNode(current);
}
SPTR_Node getClosestNode(Vec2Df position){
auto neighbors = nodes | RANGE_FILTER([](SPTR_Node n){ return !n->picked_up;}) | std::ranges::to<VEC_SPTR_Node>();
std::sort(neighbors.begin(), neighbors.end(), [position](SPTR_Node na, SPTR_Node nb){ return na->position.dist(position) < nb->position.dist(position);});
return neighbors.front();
}
void addConnection(SPTR_Node from, SPTR_Node to){
if(from != to) {
edges.emplace_back(std::make_shared<Edge>());
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);
}
+1 -1
View File
@@ -6,7 +6,7 @@
namespace VISEQ::APP{
enum Interaction {NONE, HOVER, CLICK, HOLD, RELEASE, PICKUP, DRAG, PUTDOWN, SELECT, DESELECT};
enum Interaction {NONE, HOVER, CLICK, HOLD, RELEASE, PICKUP, DRAG, PUTDOWN, SELECT, DESELECT, CONNECT};
struct InteractionEvent{
std::shared_ptr<BASE::Interactable> item;
+274
View File
@@ -0,0 +1,274 @@
#pragma once
#include "clipboard.h"
#include "connector.h"
#include "datatypes.h"
#include "draggable.h"
#include "graph-item.h"
#include "graph-manager.h"
#include "interaction-event.h"
#include "raylib.h"
#include "signal-manager.h"
#include "state.h"
#include "canvas.h"
#include <memory>
namespace VISEQ::INTERACTION{
class ScaleHandle : public BASE::Draggable, public GraphItem{
public:
ScaleHandle(){}
float radius = 6;
std::shared_ptr<ScaleHandle> getPtr(){
return std::static_pointer_cast<ScaleHandle>(shared_from_this());
}
virtual GRAPH::GraphItemType getType() override {
return GraphItemType::HANDLE;
}
virtual bool hovering() override {
return CheckCollisionPointCircle(SCREEN_MOUSE, position, radius);
}
virtual void update() override {
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
}
virtual void draw() override {
DrawCircleV(position, radius, VS_COLOR_SUN);
}
virtual bool select() override {
return false;
}
};
class InteractionManager{
public:
InteractionManager(GRAPH::GraphManager *gm, SIGNAL::SignalManager *sm, std::shared_ptr<APP::CANVAS::Canvas> canvas) : canvas(canvas), gm(gm), sm(sm) {}
std::shared_ptr<APP::CANVAS::Canvas> canvas;
GraphManager *gm;
SIGNAL::SignalManager *sm;
VISEQ::APP::Clipboard cb;
std::shared_ptr<APP::State> state = APP::State::get();
Vec2Df scale_start;
std::shared_ptr<ScaleHandle> scale_handle = std::make_shared<ScaleHandle>();
void update(){
doInteraction();
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_C)){
VEC_SPTR_Node selected_nodes = gm->getSelection();
if(!selected_nodes.empty()) cb.pushNodes(selected_nodes);
}
if(KEYS_DOWN.ctrl && IsKeyPressed(KEY_V)){
VEC_SPTR_Node paste_nodes = cb.pullNodes();
if(!paste_nodes.empty()) gm->pasteNodesAndEdges(paste_nodes, MOD_MOUSE);
}
if(IsKeyPressed(KEY_DELETE)){
removeNodes(gm->selected_nodes | std::ranges::to<VEC_SPTR_Node>());
}
if(IsKeyPressed(KEY_TAB)) {
state->node_mode = (state->node_mode + 1) % 3;
}
scaleSelection();
}
void removeNodes(VEC_SPTR_Node nodes){
VEC_SPTR_Node adjacent_nodes = gm->getAdjacentNodes(nodes);
sm->rerouteSignal(nodes, adjacent_nodes);
sm->rebaseSignal(nodes);
gm->removeNodesAndEdges(nodes);
}
void scaleSelection(){
if(!gm->selected_nodes.empty()){
float offset = 30;
Vec2Df corner_tl = {50000, 50000};
Vec2Df corner_br = {-50000, -50000};
std::shared_ptr<Node> node_tl;
std::shared_ptr<Node> node_br;
for(auto n : gm->selected_nodes){
float x = n->position.x;
float y = n->position.y;
if(x < corner_tl.x && y < corner_tl.y) node_tl = n;
if(x > corner_br.x && y > corner_br.y) node_br = n;
if(x <= corner_tl.x) corner_tl.x = x;
if(x >= corner_br.x) corner_br.x = x;
if(y <= corner_tl.y) corner_tl.y = y;
if(y >= corner_br.y) corner_br.y = y;
}
corner_tl -= Vec2Df(offset, offset);
corner_br += Vec2Df(offset, offset);
state->bounding_box = (Rectangle){corner_tl.x, corner_tl.y, corner_br.x - corner_tl.x, corner_br.y - corner_tl.y};
scale_handle->update();
if(scale_handle->clicked()){
scale_start = (corner_br - corner_tl);
for(auto n : gm->selected_nodes){
n->drag_offset = n->position - node_tl->position;
}
}
if(scale_handle->picked_up){
Vec2Df scale = (scale_handle->position - corner_tl) / scale_start;
if(IsKeyDown(KEY_LEFT_SHIFT)) scale.y = scale.x;
DrawText(std::format("{:.2f} {:.2f}", scale.x, scale.y).c_str(), corner_br.x+5, corner_br.y+5, 10, RED);
for(auto n : gm->selected_nodes){
n->position = node_tl->position + (n->drag_offset * scale);
}
} else {
scale_handle->position = corner_br;
}
}
}
void snapPolar(std::shared_ptr<Node> dragNode){
float steps = round((dragNode->neighbors.front()->position.dist(SCREEN_MOUSE)) / state->settings.grid) * state->settings.grid;
if(dragNode->neighbors.size() > 1){
Vec2Df dn1 = dragNode->neighbors[0]->position;
Vec2Df dn2 = dragNode->neighbors[1]->position;
Vec2Df v1_orth = dn1.center(dn2);
if(dn1.x < dn2.x) std::swap(dn1,dn2);
float dist = dn1.dist(dn2);
float dist_orth = std::sqrt(std::pow(steps,2) - std::pow(dist/2,2));
if(SCREEN_MOUSE.y < v1_orth.y) dist_orth *= -1;
Vec2Df v1_orth_t = v1_orth + (dn1-dn2).norm().orth() * dist_orth;
DrawLineV(dn1, dn2, VS_COLOR_RED);
DrawLineV(v1_orth, v1_orth_t, VS_COLOR_RED);
DrawCircleV(v1_orth, 3.0f, VS_COLOR_RED);
dragNode->position = v1_orth_t;
} else if(!dragNode->neighbors.empty()){
float pol_r = steps;
float pol_theta = Vector2Angle(Vec2Df{1,0},(SCREEN_MOUSE - dragNode->neighbors.front()->position));
Vec2Df polar = VISEQ::VMATH::polarToCartesian(pol_r, pol_theta);
dragNode->position = dragNode->neighbors.front()->position + polar;
}
}
void doInteraction(){
bool exit = false;
bool once = false;
state->mouse_z = canvas->z_index;
while(APP::event_queue.size() > 0 && !exit){
auto e = APP::event_queue.front();
std::cout << e.item->getType() << " " << e.action << std::endl;
if(e.action == APP::Interaction::CONNECT){
auto connector = std::dynamic_pointer_cast<Connector>(e.item);
auto connector_to = std::dynamic_pointer_cast<Connector>(connector->partner);
gm->addConnection(std::dynamic_pointer_cast<Node>(connector->parent), std::dynamic_pointer_cast<Node>(connector_to->parent));
}
if(e.action == APP::Interaction::HOVER){
state->mouse_z = e.item->z_index;
std::cout << state->mouse_z << std::endl;
}
if(e.item->getType() == GraphItemType::CANVAS) {
if(e.action == APP::Interaction::SELECT) {
gm->select();
std::cout << "app canvas select" << std::endl;
canvas->clearSelectionRect();
}
if(e.action == APP::Interaction::DESELECT) {
std::cout << "app canvas deselect" << std::endl;
gm->deselect();
}
}
if(!once && e.item->getType() == GraphItemType::NODE){
auto node = std::dynamic_pointer_cast<Node>(e.item);
if(e.action == APP::Interaction::PICKUP) {
node->pickUp();
if(node->selected){
for(auto s : gm->selected_nodes){
s->pickUp(node->position);
}
}
once = true;
}
if(e.action == APP::Interaction::DRAG) {
if(KEYS_DOWN.ctrl) node->drag(MOD_MOUSE);
else if(KEYS_DOWN.shift) {
snapPolar(node);
}
else node->drag(MOD_MOUSE + node->drag_offset);
if(node->selected){
for(auto s : gm->selected_nodes){
s->drag(MOD_MOUSE + s->drag_offset);
}
}
once = true;
}
if(e.action == APP::Interaction::PUTDOWN) {
node->putDown();
if(node->selected){
for(auto s : gm->selected_nodes){
s->putDown();
}
}
}
}
if(exit) break;
if(!once && (e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS || e.item->getType() == GraphItemType::HANDLE)) {
switch(e.action){
case VISEQ::APP::Interaction::PICKUP:
{
e.item->pickUp();
once = true;
break;
}
case VISEQ::APP::Interaction::DRAG:
{
e.item->drag(MOD_MOUSE);
once = true;
break;
}
case VISEQ::APP::Interaction::PUTDOWN:
{
e.item->putDown();
break;
}
default:
{}
}
}
APP::event_queue.pop_front();
}
APP::event_queue.clear();
}
void draw(){
if(!gm->selected_nodes.empty()){
DrawRectangleRoundedLines(state->bounding_box, 0.1f, 3, VS_COLOR_LIGHTGREY);
scale_handle->draw();
}
}
};
}
-280
View File
@@ -61,104 +61,7 @@ int main(){
app.update();
app.draw();
/*else if(IsKeyDown(KEY_LEFT_SHIFT)){*/
/* float steps = round((dragNode->neighbors.front()->position.dist(mouse_pos)) / state->settings.grid) * state->settings.grid;*/
/* if(dragNode->neighbors.size() > 1){*/
/* Vec2Df dn1 = dragNode->neighbors[0]->position;*/
/* Vec2Df dn2 = dragNode->neighbors[1]->position;*/
/* Vec2Df v1_orth = dn1.center(dn2);*/
/**/
/* if(dn1.x < dn2.x) std::swap(dn1,dn2);*/
/**/
/* float dist = dn1.dist(dn2);*/
/* float dist_orth = std::sqrt(std::pow(steps,2) - std::pow(dist/2,2));*/
/**/
/* if(mouse_pos.y < v1_orth.y) dist_orth *= -1;*/
/**/
/* Vec2Df v1_orth_t = v1_orth + (dn1-dn2).norm().orth() * dist_orth;*/
/* DrawLineV(dn1, dn2, VS_COLOR_RED);*/
/* DrawLineV(v1_orth, v1_orth_t, VS_COLOR_RED);*/
/* DrawCircleV(v1_orth, 3.0f, VS_COLOR_RED);*/
/* dragNode->position = v1_orth_t;*/
/* } else if(!dragNode->neighbors.empty()){*/
/* float pol_r = steps;*/
/* float pol_theta = Vector2Angle(Vec2Df{1,0},(mouse_pos - dragNode->neighbors.front()->position));*/
/* Vec2Df polar = VISEQ::VMATH::polarToCartesian(pol_r, pol_theta); */
/* dragNode->position = dragNode->neighbors.front()->position + polar;*/
/* }*/
// auto dragging_nodes = app.gm.nodes | RANGE_FILTER([](SPTR_Node n) { return n->dragging;});
/*auto connecting_nodes = app.gm.nodes | RANGE_FILTER([](SPTR_Node n) { return n->connecting;});*/
/*auto selected_nodes = app.gm.nodes | RANGE_FILTER([](SPTR_Node n) { return n->selected && !n->picked_up;}) | std::ranges::to<VEC_SPTR_Node>();*/
/*auto hovering_nodes = app.gm.nodes | RANGE_FILTER([](SPTR_Node n) { return n->hovering();});*/
/*auto hovering_connectors = app.gm.nodes | RANGE_FILTER([&mouse_pos](SPTR_Node n) { return CheckCollisionPointCircle(mouse_pos, (n->position - ((n->position - mouse_pos)).norm() * (n->radius + 14.0f)), 8.0f);});*/
/**/
/*for(auto &n : app.gm.nodes ){*/
/* if(hovering_connectors.empty()) n->hover_connect = false;*/
/*}*/
/**/
/*if(istate != InteractionState::ADD_NODES_MENU && !mouse_down && !mouse_right_down && dragging_nodes.empty() && connecting_nodes.empty() && hovering_nodes.empty() && hovering_connectors.empty()) istate = InteractionState::HOVER_CANVAS;*/
/*if((mouse_clicked || mouse_down || mouse_released) && !mouse_right_down && dragging_nodes.empty() && connecting_nodes.empty() && hovering_nodes.empty() && hovering_connectors.empty() && istate != InteractionState::SCALE_SELECTION) istate = InteractionState::DRAW_SELECTION;*/
/**/
/*if(!hovering_nodes.empty() && !mouse_down && !mouse_right_down) istate = InteractionState::HOVER_NODE;*/
/*if(!dragging_nodes.empty()) istate = InteractionState::DRAG_NODE; */
/*if(!hovering_connectors.empty() && !mouse_right_down && istate == InteractionState::HOVER_CANVAS) istate = InteractionState::HOVER_CONNECTOR;*/
/*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;*/
/**/
/*if(IsKeyPressed(KEY_TAB)) {*/
/* state->settings.mode = (state->settings.mode + 1) % 3;*/
/* app.gm.setNodeMode(state->settings.mode);*/
/*}*/
/*if(!selected_nodes.empty()){*/
/* float offset = 30;*/
/* Vec2Df corner_tl = {50000, 50000};*/
/* Vec2Df corner_br = {-50000, -50000};*/
/* std::shared_ptr<Node> node_tl;*/
/* std::shared_ptr<Node> node_br;*/
/**/
/* for(auto n : selected_nodes){*/
/* float x = n->position.x;*/
/* float y = n->position.y;*/
/**/
/* if(x < corner_tl.x && y < corner_tl.y) node_tl = n;*/
/* if(x > corner_br.x && y > corner_br.y) node_br = n;*/
/**/
/* if(x <= corner_tl.x) corner_tl.x = x;*/
/* if(x >= corner_br.x) corner_br.x = x;*/
/* if(y <= corner_tl.y) corner_tl.y = y;*/
/* if(y >= corner_br.y) corner_br.y = y;*/
/* }*/
/* corner_tl -= Vec2Df(offset, offset);*/
/* corner_br += Vec2Df(offset, offset);*/
/**/
/* DrawRectangleLines(corner_tl.x, corner_tl.y, (corner_br.x - corner_tl.x), (corner_br.y - corner_tl.y), VS_COLOR_LIGHTGREY);*/
/* DrawCircleV(corner_br, 5, YELLOW);*/
/**/
/* if(istate == InteractionState::SCALE_SELECTION && mouse_released){*/
/* istate = InteractionState::HOVER_CANVAS;*/
/* }*/
/* if(mouse_clicked && corner_br.dist(mouse_pos) < 10){*/
/* scale_start = (corner_br - corner_tl);*/
/* for(auto n : selected_nodes){*/
/* n->drag_offset = n->position - node_tl->position;*/
/* }*/
/* istate = InteractionState::SCALE_SELECTION;*/
/* }*/
/* if(istate == InteractionState::SCALE_SELECTION && mouse_down){*/
/* Vec2Df scale = (mouse_pos - corner_tl) / scale_start;*/
/* if(IsKeyDown(KEY_LEFT_SHIFT)) scale.y = scale.x;*/
/* DrawText(std::format("{:.2f} {:.2f}", scale.x, scale.y).c_str(), corner_br.x+5, corner_br.y+5, 10, RED);*/
/* for(auto n : selected_nodes){*/
/* n->position = node_tl->position + (n->drag_offset * scale);*/
/* }*/
/* istate = InteractionState::SCALE_SELECTION;*/
/* }*/
/*}*/
/*switch(istate){*/
/* case InteractionState::SCALE_SELECTION:*/
@@ -186,189 +89,6 @@ int main(){
/* DrawCircleLines(node_menu_position.x, node_menu_position.y, 32, VS_COLOR_DARKGREY);*/
/**/
/* }*/
/* case InteractionState::DRAW_SELECTION:*/
/* {*/
/* if(mouse_clicked){*/
/* select_start = mouse_pos;*/
/* }*/
/* if(mouse_down){*/
/* Vec2Df 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};*/
/* Vec2Df 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 : app.gm.nodes){*/
/* if(CheckCollisionPointRec(n->position, selection)) {*/
/* n->in_rect = true;*/
/* } else {*/
/* n->in_rect = false;*/
/* }*/
/* }*/
/* }*/
/**/
/* if(mouse_released){ */
/* int n_selected = 0;*/
/* for(auto& n : app.gm.nodes){*/
/* if(CheckCollisionPointRec(n->position, selection)) {*/
/* n->selected = true;*/
/* n->in_rect = false;*/
/* n_selected++;*/
/* } else {*/
/* if(!IsKeyDown(KEY_LEFT_SHIFT)) n->selected = false;*/
/* }*/
/* }*/
/* if(n_selected > 0) copied_nodes.clear();*/
/* selection = (Rectangle){0,0,0,0};*/
/* }*/
/* break;*/
/* }*/
/* case InteractionState::HOVER_NODE:*/
/* {*/
/* if(mouse_clicked) {*/
/* if(IsKeyDown(KEY_LEFT_SHIFT)) {*/
/* hovering_nodes.front()->selected = true;*/
/* } else {*/
/* hovering_nodes.front()->dragging = true;*/
/* hovering_nodes.front()->drag_offset = hovering_nodes.front()->position - mouse_pos;*/
/* }*/
/* }*/
/* if(mouse_right_clicked) hovering_nodes.front()->config = true;*/
/* break;*/
/* }*/
/* case InteractionState::DRAG_NODE:*/
/* {*/
/* if(!dragging_nodes.empty()){*/
/* SPTR_Node dragNode = dragging_nodes.front();*/
/**/
/* for(auto &n : selected_nodes){*/
/* if(!n->picked_up) n->drag_offset = n->position - dragNode->position;*/
/* n->picked_up = true;*/
/* }*/
/**/
/* if(IsKeyDown(KEY_LEFT_CONTROL)) {*/
/* dragNode->position.x = round((mouse_pos.x + dragNode->drag_offset.x) / state->settings.grid) * state->settings.grid;*/
/* dragNode->position.y = round((mouse_pos.y + dragNode->drag_offset.y) / state->settings.grid) * state->settings.grid;*/
/* } else if(IsKeyDown(KEY_LEFT_SHIFT)){*/
/* float steps = round((dragNode->neighbors.front()->position.dist(mouse_pos)) / state->settings.grid) * state->settings.grid;*/
/* if(dragNode->neighbors.size() > 1){*/
/* Vec2Df dn1 = dragNode->neighbors[0]->position;*/
/* Vec2Df dn2 = dragNode->neighbors[1]->position;*/
/* Vec2Df v1_orth = dn1.center(dn2);*/
/**/
/* if(dn1.x < dn2.x) std::swap(dn1,dn2);*/
/**/
/* float dist = dn1.dist(dn2);*/
/* float dist_orth = std::sqrt(std::pow(steps,2) - std::pow(dist/2,2));*/
/**/
/* if(mouse_pos.y < v1_orth.y) dist_orth *= -1;*/
/**/
/* Vec2Df v1_orth_t = v1_orth + (dn1-dn2).norm().orth() * dist_orth;*/
/* DrawLineV(dn1, dn2, VS_COLOR_RED);*/
/* DrawLineV(v1_orth, v1_orth_t, VS_COLOR_RED);*/
/* DrawCircleV(v1_orth, 3.0f, VS_COLOR_RED);*/
/* dragNode->position = v1_orth_t;*/
/* } else if(!dragNode->neighbors.empty()){*/
/* float pol_r = steps;*/
/* float pol_theta = Vector2Angle(Vec2Df{1,0},(mouse_pos - dragNode->neighbors.front()->position));*/
/* Vec2Df polar = VISEQ::VMATH::polarToCartesian(pol_r, pol_theta); */
/* dragNode->position = dragNode->neighbors.front()->position + polar;*/
/* }*/
/* } else {*/
/* dragNode->position = mouse_pos + dragNode->drag_offset;*/
/* }*/
/**/
/* for(auto &n : selected_nodes){*/
/* n->position = dragNode->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;*/
/* }*/
/* case InteractionState::HOVER_CONNECTOR:*/
/* {*/
/* if(!hovering_connectors.empty()){*/
/* hovering_connectors.front()->hover_connect = true;*/
/* if(mouse_clicked) hovering_connectors.front()->connecting = true;*/
/* }*/
/* break;*/
/* }*/
/* case InteractionState::CONNECT_NODE:*/
/* {*/
/* Vec2Df connector_position = connecting_nodes.front()->position - ((connecting_nodes.front()->position - mouse_pos)).norm() * (connecting_nodes.front()->radius + 14.0f);*/
/* Vec2Df target_position = mouse_pos;*/
/**/
/* if(IsKeyDown(KEY_LEFT_CONTROL)) {*/
/* target_position.x = round((mouse_pos.x) / state->settings.grid) * state->settings.grid;*/
/* target_position.y = round((mouse_pos.y) / state->settings.grid) * state->settings.grid;*/
/* } else if(IsKeyDown(KEY_LEFT_SHIFT)){*/
/* std::shared_ptr<Node> closest = app.gm.getClosestNode(mouse_pos);*/
/* float steps = round((closest->position.dist(mouse_pos)) / state->settings.grid) * state->settings.grid;*/
/* float pol_r = steps;*/
/* float pol_theta = Vector2Angle(Vec2Df{1,0},(mouse_pos - closest->position));*/
/**/
/* Vec2Df polar = VISEQ::VMATH::polarToCartesian(pol_r, pol_theta); */
/* target_position = closest->position + polar;*/
/* } else {*/
/* target_position = mouse_pos;*/
/* }*/
/**/
/* if(connecting_nodes.front()->connecting && mouse_down){*/
/* DrawLine(connector_position.x, connector_position.y, target_position.x, target_position.y, (Color){229, 181, 103, 255});*/
/* connecting_nodes.front()->hover_connect = true;*/
/* }*/
/**/
/* if(!hovering_connectors.empty()) {*/
/* hovering_connectors.front()->hover_connect = true;*/
/* }*/
/**/
/* if(mouse_released) {*/
/* if(&hovering_nodes.front() != &connecting_nodes.front() && &connecting_nodes.front() != &hovering_connectors.front()){*/
/* if(!hovering_nodes.empty()){*/
/* app.gm.addConnection(connecting_nodes.front(), hovering_nodes.front());*/
/* } else if(!hovering_connectors.empty()){*/
/* app.gm.addConnection(connecting_nodes.front(), hovering_connectors.front());*/
/* } else {*/
/* SPTR_Node new_node = app.gm.copyNode(std::dynamic_pointer_cast<MidiNode>(connecting_nodes.front()), target_position);*/
/* new_node->connecting = false;*/
/* app.gm.addConnection(connecting_nodes.front(), new_node);*/
/* }*/
/* }*/
/* connecting_nodes.front()->connecting = false;*/
/* istate = InteractionState::HOVER_CANVAS;*/
/* }*/
/* break;*/
/* }*/
/* case InteractionState::DELETE_SELECTED_NODES:*/
/* {*/
/* app.removeNodes(selected_nodes | std::ranges::to<VEC_SPTR_Node>());*/
/* break;*/
/* }*/
/* 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:*/
/* {*/
/* for(auto n: copied_nodes){*/
/* n->drag_offset = (n->position - copied_nodes.front()->position);*/
/* }*/
/* app.copyNodesAndConnections(copied_nodes, mouse_pos);*/
/* //copied_nodes.clear();*/
/* break;*/
/* }*/
/*};*/
}
+4
View File
@@ -82,6 +82,10 @@ namespace VISEQ::GRAPH::NODES {
int GGate(){
return midi_gate;
}
void update() override {
Node::update();
mode = state->node_mode;
}
void interact(){
float wheel = GetMouseWheelMove();
+5 -1
View File
@@ -18,12 +18,16 @@ namespace VISEQ::SIGNAL {
typedef std::shared_ptr<Signal> SPTR_Signal;
typedef std::vector<SPTR_Signal> VEC_SPTR_Signal;
class SignalManager{
class SignalManager : public std::enable_shared_from_this<SignalManager>{
public:
SignalManager() {}
SignalManager(GraphManager *gm, std::mutex *mutex) : mutex(mutex), gm(gm) {}
std::shared_ptr<SignalManager> getPtr(){
return shared_from_this();
}
VISEQ::MIDI::Midi midi;
std::mutex *mutex;
+1
View File
@@ -78,6 +78,7 @@ namespace VISEQ::APP{
ModifierKeys keys_released;
Rectangle selection;
Rectangle bounding_box;
Vec2Df mouse_delta;