Drag selection and snap to grid ok. Deselect not working though...

This commit is contained in:
Sebastian
2024-11-26 01:58:09 +01:00
parent 9c0aac8618
commit 813958002b
9 changed files with 231 additions and 180 deletions
+173 -16
View File
@@ -1,12 +1,15 @@
#pragma once
#include <filesystem>
#include <fstream>
#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 "moveable.h"
#include "node.h"
#include "raylib.h"
#include "signal-manager.h"
@@ -16,15 +19,21 @@
#include <memory>
#include <ranges>
using json = nlohmann::json;
namespace VISEQ::APP {
class AppManager;
void to_json(json& j, const AppManager& A);
void from_json(const json& j, AppManager& A);
class AppManager{
public:
AppManager() : sm(&gm, &mutex), mouse(&gm), ui(&sm, &gm) {}
std::mutex mutex;
std::shared_ptr<CANVAS::Canvas> canvas = std::make_shared<CANVAS::Canvas>();
VISEQ::GRAPH::GraphManager gm;
VISEQ::SIGNAL::SignalManager sm;
VISEQ::APP::Clipboard cb;
@@ -34,6 +43,100 @@ namespace VISEQ::APP {
UI::AppUI ui;
void init(){
canvas->camera.target = (Vector2){ state->settings.width/2.0f, state->settings.height/2.0f };
canvas->camera.offset = (Vector2){ state->settings.width/2.0f, state->settings.height/2.0f };
canvas->camera.rotation = 0.0f;
canvas->camera.zoom = 1.0f;
}
void close(){
std::ofstream file("state.json");
file << json(*this);
std::cout << std::setw(4) << json(*this) << std::endl;
}
void startSignals(){
sm.startSignalThread();
}
void loadState(){
if(std::filesystem::exists("state.json")){
std::ifstream f("state.json");
json graph = json::parse(f);
int highest_id = 0;
std::shared_ptr<Node> hid;
for(auto n : graph.at("graphmanager").at("nodes")){
std::shared_ptr<MidiNode> mn = n;
if(mn->id > highest_id) {
highest_id = mn->id;
hid = mn;
}
}
for(auto e : graph.at("graphmanager").at("edges")){
if(e.at("id") > highest_id){
highest_id = e.at("id");
}
}
for(auto n : graph.at("graphmanager").at("nodes")){
std::shared_ptr<MidiNode> mn = n;
gm.addNode(mn);
//app.gm.nodes.push_back(mn);
std::cout << std::format("adding node {}", mn->id) << std::endl;
}
for(auto e : graph.at("graphmanager").at("edges")){
int start_id = e.at("start").get<int>();
int end_id = e.at("end").get<int>();
VEC_SPTR_Node start = gm.nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
VEC_SPTR_Node end = gm.nodes | RANGE_FILTER([end_id](SPTR_Node n){return n->id == end_id;}) | std::ranges::to<VEC_SPTR_Node>();
if(!start.empty() && !end.empty()) {
std::cout << std::format("connection {} to {}", start_id, end_id) << std::endl;
gm.addConnection(start.front(), end.front());
}
}
gm.edges.back()->newId(highest_id); // set static id counter in base class to highest value from json file
for(auto s : graph.at("signalmanager").at("signals")){
int start_id = s.at("start").get<int>();
int next_id = s.at("next").get<int>();
int last_id = s.at("last").get<int>();
std::shared_ptr<VISEQ::SIGNAL::Signal> ms = s;
VEC_SPTR_Node start = gm.nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
VEC_SPTR_Node last = gm.nodes | RANGE_FILTER([last_id](SPTR_Node n){return n->id == last_id;}) | std::ranges::to<VEC_SPTR_Node>();
VEC_SPTR_Node next = gm.nodes | RANGE_FILTER([next_id](SPTR_Node n){return n->id == next_id;}) | std::ranges::to<VEC_SPTR_Node>();
ms->start = start.front();
ms->next = next.front();
ms->last = last.front();
sm.signals.push_back(ms);
std::cout << std::format("adding signal with start node {}", start_id) << std::endl;
}
} else {
for(int i = 0; i < 4; ++i){
gm.addMidiNode(Vec2Df{(float)i * state->settings.grid*4 + 7 * state->settings.grid, 2 * state->settings.grid*4});
}
for(int i = 3; i >= 0; --i){
gm.addMidiNode(Vec2Df{(float)i * state->settings.grid*4 + 7 * state->settings.grid, 3 * state->settings.grid*4});
}
for(int i = 0; i < 8; ++i){
gm.addConnection(gm.nodes[i], gm.nodes[(i+1) % 8]);
}
sm.addSignalAtNode(gm.nodes.front());
}
}
void updateMidiPorts(){
for(auto&n : gm.nodes | RANGE_FILTER([](VISEQ::GRAPH::NODES::SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;})){
auto nc = std::dynamic_pointer_cast<MidiNode>(n);
@@ -58,23 +161,63 @@ namespace VISEQ::APP {
gm.removeNodesAndEdges(nodes);
}
void doInteraction(){
while(event_queue.size() > 0){
void doInteraction(){
bool exit = false;
while(event_queue.size() > 0 && !exit){
auto e = event_queue.front();
std::cout << e.action << " " << e.item->z_index << std::endl;
if(e.item->getType() == GraphItemType::NODE || e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS) {
std::cout << e.item->getType() << " " << e.action << std::endl;
if(e.item->getType() == GraphItemType::CANVAS) {
if(e.action == Interaction::SELECT) {
gm.select();
std::cout << gm.selected_nodes.size() << std::endl;
canvas->clearSelectionRect();
}
if(e.action == Interaction::DESELECT) gm.deselect();
}
if(e.item->getType() == GraphItemType::NODE){
if(e.action == Interaction::PICKUP) {
e.item->pickUp();
if(std::dynamic_pointer_cast<Node>(e.item)->selected){
for(auto s : gm.selected_nodes){
s->pickUp(std::dynamic_pointer_cast<Node>(e.item)->position);
}
}
exit = true;
}
if(e.action == Interaction::DRAG) {
e.item->drag();
if(std::dynamic_pointer_cast<Node>(e.item)->selected){
for(auto s : gm.selected_nodes){
s->drag();
}
}
exit = true;
}
if(e.action == Interaction::PUTDOWN) {
e.item->putDown();
if(std::dynamic_pointer_cast<Node>(e.item)->selected){
for(auto s : gm.selected_nodes){
s->putDown();
}
}
}
}
if(exit) break;
if(e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS) {
switch(e.action){
case VISEQ::APP::Interaction::PICKUP:
{
e.item->pickUp();
goto exit_loop;
exit = true;
break;
}
case VISEQ::APP::Interaction::DRAG:
{
e.item->drag();
goto exit_loop;
exit = true;
break;
}
case VISEQ::APP::Interaction::PUTDOWN:
@@ -83,18 +226,23 @@ namespace VISEQ::APP {
break;
}
default:
{}
}
}
event_queue.pop_front();
}
exit_loop:
event_queue.clear();
}
void update(){
state->update(canvas->camera);
canvas->update();
mutex.lock();
updateMidiPorts();
mutex.unlock();
doInteraction();
mouse.update();
@@ -109,15 +257,24 @@ namespace VISEQ::APP {
}
}
void draw(Vec2Df mouse_pos, Camera2D camera){
gm.drawNodes(mouse_pos, camera);
gm.drawEdges(mouse_pos, camera);
sm.drawSignals(mouse_pos, camera);
void draw(){
BeginDrawing();
ClearBackground((Color){46,46,46});
canvas->drawStart();
canvas->draw();
gm.drawNodes(SCREEN_MOUSE, canvas->camera);
gm.drawEdges(SCREEN_MOUSE, canvas->camera);
sm.drawSignals(SCREEN_MOUSE, canvas->camera);
canvas->drawEnd();
drawUI();
EndDrawing();
}
void drawUI(Vec2Df mouse_pos, Camera2D camera){
void drawUI(){
mutex.lock();
ui.draw(mouse_pos, camera);
ui.draw(SCREEN_MOUSE, canvas->camera);
mutex.unlock();
}
};