From 5779c93339209d7fbeffda3e12e822dfe8a08e85 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 19 Nov 2024 01:04:06 +0100 Subject: [PATCH] Clipboard introduced, but not incorporated yet. Some defines for convenience and better readability. --- src/app-manager.h | 2 ++ src/canvas.h | 38 +++++++++++++++++++------------------- src/clipboard.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/connectable.h | 4 ++-- src/connector.h | 4 ++-- src/draggable.h | 28 +++++++++++++++++----------- src/graph-manager.h | 3 +++ src/main.cpp | 4 ++-- src/midi-node.h | 12 ++++++------ src/node.h | 3 ++- src/state.h | 20 +++++++++++++++++++- 11 files changed, 118 insertions(+), 44 deletions(-) create mode 100644 src/clipboard.h diff --git a/src/app-manager.h b/src/app-manager.h index 4fd6646..cc0c96f 100644 --- a/src/app-manager.h +++ b/src/app-manager.h @@ -1,5 +1,6 @@ #pragma once +#include "clipboard.h" #include "datatypes.h" #include "graph-manager.h" #include "midi-node.h" @@ -23,6 +24,7 @@ namespace VISEQ::APP { VISEQ::GRAPH::GraphManager gm; VISEQ::SIGNAL::SignalManager sm; + VISEQ::APP::Clipboard cb; UI::AppUI ui; diff --git a/src/canvas.h b/src/canvas.h index d823989..f8a173c 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -1,9 +1,11 @@ #pragma once + +#include "state.h" #include "draggable.h" #include "raylib.h" #include "raymath.h" -#include "state.h" + namespace VISEQ::APP::CANVAS { class Canvas : public BASE::Draggable { public: @@ -25,42 +27,41 @@ namespace VISEQ::APP::CANVAS { virtual void drawStart(){ BeginMode2D(camera); - /*state->hovering = false;*/ - /*if(hovering()) state->istate = InteractionState::HOVER_CANVAS;*/ } virtual void drawEnd(){ EndMode2D(); } - void selectNodes(){ - if(state->mouse_left.clicked){ + void makeSelection(){ + if(MOUSE_LEFT.clicked){ state->selection = (Rectangle){0,0,0,0}; - select_start = state->screen_mouse; - state->istate = InteractionState::DRAW_SELECTION; + select_start = SCREEN_MOUSE; + STATE = IState::DRAW_SELECTION; } - if(state->mouse_left.down){ - Vec2Df select1 = {state->screen_mouse.x > select_start.x ? select_start.x : state->screen_mouse.x, state->screen_mouse.y > select_start.y ? select_start.y : state->screen_mouse.y}; - Vec2Df select2 = {state->screen_mouse.x > select_start.x ? state->screen_mouse.x - select_start.x : select_start.x - state->screen_mouse.x, state->screen_mouse.y > select_start.y ? state->screen_mouse.y - select_start.y : select_start.y - state->screen_mouse.y}; + if(MOUSE_LEFT.down){ + Vec2Df select1 = {SCREEN_MOUSE.x > select_start.x ? select_start.x : SCREEN_MOUSE.x, SCREEN_MOUSE.y > select_start.y ? select_start.y : SCREEN_MOUSE.y}; + Vec2Df select2 = {SCREEN_MOUSE.x > select_start.x ? SCREEN_MOUSE.x - select_start.x : select_start.x - SCREEN_MOUSE.x, SCREEN_MOUSE.y > select_start.y ? SCREEN_MOUSE.y - select_start.y : select_start.y - SCREEN_MOUSE.y}; state->selection = (Rectangle){select1.x, select1.y, select2.x, select2.y}; } - if(state->mouse_left.released){ - state->istate = InteractionState::HOVER_CANVAS; + if(MOUSE_LEFT.released){ + STATE = IState::HOVER_CANVAS; + state->selection = (Rectangle){0,0,0,0}; } } virtual void update() override { camera_delta = state->mouse_delta * (-1.0f/camera.zoom); if(hovering()) drag(); - if(state->istate == InteractionState::HOVER_CANVAS || state->istate == InteractionState::DRAW_SELECTION) selectNodes(); + if(STATE == IState::HOVER_CANVAS || STATE == IState::DRAW_SELECTION) makeSelection(); float wheel = GetMouseWheelMove(); if(wheel != 0){ - if(!IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){ + if(!KEYS_DOWN.shift && !KEYS_DOWN.ctrl && !KEYS_DOWN.alt){ camera.offset = state->raw_mouse; - camera.target = state->screen_mouse; + camera.target = SCREEN_MOUSE; float scaleFactor = 1.0f + (0.25f*fabsf(wheel)); if (wheel < 0) scaleFactor = 1.0f/scaleFactor; camera.zoom = Clamp(camera.zoom*scaleFactor, 0.125f, 64.0f); @@ -69,10 +70,9 @@ namespace VISEQ::APP::CANVAS { } virtual void draw(){ - if(state->istate == InteractionState::DRAW_SELECTION) DrawRectangleLines(state->selection.x, state->selection.y, state->selection.width, state->selection.height, (Color){150,150,150,150}); - - for(int x = -state->settings.grid*100; x < state->settings.grid*100; x+=state->settings.grid){ - for(int y = -state->settings.grid*100; y < state->settings.grid*100; y+=state->settings.grid){ + if(STATE == IState::DRAW_SELECTION) DrawRectangleLines(state->selection.x, state->selection.y, state->selection.width, state->selection.height, (Color){150,150,150,150}); + for(int x = -SETTINGS.grid*100; x < SETTINGS.grid*100; x+=SETTINGS.grid){ + for(int y = -SETTINGS.grid*100; y < SETTINGS.grid*100; y+=SETTINGS.grid){ DrawPixel(x, y, (Color){130,130,130,200}); } } diff --git a/src/clipboard.h b/src/clipboard.h new file mode 100644 index 0000000..8fdcce6 --- /dev/null +++ b/src/clipboard.h @@ -0,0 +1,44 @@ +#pragma once + +#include "midi-node.h" +#include "node.h" + +namespace VISEQ::APP { + class Clipboard { + public: + Clipboard() {} + + GRAPH::NODES::VEC_SPTR_Node clipboard; + + GRAPH::NODES::VEC_SPTR_Node pasteNodes(){ + return clipboard; + } + + void copyNodes(GRAPH::NODES::VEC_SPTR_Node _nodes, Vec2Df position){ + for(auto n: _nodes){ + copyNode(n, position + n->drag_offset); + } + } + + void copyNodes(std::vector> _nodes, Vec2Df position){ + for(auto n: _nodes){ + copyNode(n, position + n->drag_offset); + } + } + + GRAPH::NODES::SPTR_Node copyNode(GRAPH::NODES::SPTR_Node n, Vec2Df position){ + std::cout << "copy basenode" << std::endl; + clipboard.insert(clipboard.end(), std::make_shared(*n)); + clipboard.back()->setPosition(position); + return clipboard.back(); + } + + GRAPH::NODES::SPTR_Node copyNode(std::shared_ptr n, Vec2Df position){ + std::cout << "copy midinode" << std::endl; + clipboard.insert(clipboard.end(), std::make_shared(*n)); + clipboard.back()->setPosition(position); + return clipboard.back(); + } + + }; +} diff --git a/src/connectable.h b/src/connectable.h index 50d6b57..2ede5b1 100644 --- a/src/connectable.h +++ b/src/connectable.h @@ -19,11 +19,11 @@ namespace VISEQ::BASE { } virtual bool hovering() override { - return CheckCollisionPointCircle(state->screen_mouse, position, 5); + return CheckCollisionPointCircle(SCREEN_MOUSE, position, 5); } virtual void drag() override { - DrawLineV(position, state->mod_mouse, (Color){229, 181, 103, 255}); + DrawLineV(position, MOD_MOUSE, (Color){229, 181, 103, 255}); } void update() override{ diff --git a/src/connector.h b/src/connector.h index 050ae20..fa6b2cb 100644 --- a/src/connector.h +++ b/src/connector.h @@ -30,12 +30,12 @@ namespace VISEQ::GRAPH { void setPosition(Vec2Df pos) override { center_position = pos; - if(!partner) position = center_position - ((center_position - state->screen_mouse)).norm() * (radius + orbit); + if(!partner) position = center_position - ((center_position - SCREEN_MOUSE)).norm() * (radius + orbit); if(partner) position = center_position - ((center_position - partner->position)).norm() * (radius + orbit); } void draw() override { - float opacity = 150.0f - Clamp(position.dist(state->screen_mouse), 0.0f, 150.0f); + float opacity = 150.0f - Clamp(position.dist(SCREEN_MOUSE), 0.0f, 150.0f); if(partner){ DrawLineV(position, partner->position, VS_COLOR_RED); diff --git a/src/draggable.h b/src/draggable.h index c4146b1..4c66f73 100644 --- a/src/draggable.h +++ b/src/draggable.h @@ -19,18 +19,21 @@ namespace VISEQ::BASE { bool picked_up = false; virtual bool pickedUp() { - if(clicked() && held() && (state->istate == APP::InteractionState::HOVER_NODE || state->istate == APP::InteractionState::DRAG_NODE)) { + if(clicked() && held() && (STATE == IState::HOVER_NODE || STATE == IState::DRAG_NODE)) { picked_up = true; - drag_offset = position - state->screen_mouse; + drag_offset = position - SCREEN_MOUSE; } return picked_up; } virtual void drag() { - if(state->keys_down.ctrl){ - position = state->mod_mouse; + if(KEYS_PRESSED.ctrl){ + selection_offset = position - state->hover_position; + } + if(KEYS_DOWN.ctrl){ + position = MOD_MOUSE + selection_offset; } else { - position = state->mod_mouse + drag_offset; + position = MOD_MOUSE + drag_offset; } } @@ -39,20 +42,23 @@ namespace VISEQ::BASE { } virtual void select() override { - selected = (state->keys_down.shift && selected) || CheckCollisionPointRec(position, state->selection); + if(STATE == IState::DRAW_SELECTION) in_selection_rect = CheckCollisionPointRec(position, state->selection); + if(MOUSE_LEFT.released) selected = (KEYS_DOWN.shift && selected) || in_selection_rect; } virtual void update() override { - if((held() && !picked_up) || (clicked() && !state->keys_down.shift)) select(); - if(entered()) state->istate = APP::InteractionState::HOVER_NODE; - if(exited()) state->istate = APP::InteractionState::HOVER_CANVAS; + if(STATE != IState::HOVER_NODE) select(); + if(entered()){ + STATE = IState::HOVER_NODE; + } + if(exited()) STATE = IState::HOVER_CANVAS; if(pickedUp()){ drag(); - state->istate = APP::InteractionState::DRAG_NODE; + STATE = IState::DRAG_NODE; } if(released() && picked_up){ putDown(); - state->istate = APP::InteractionState::HOVER_CANVAS; + STATE = IState::HOVER_CANVAS; } } }; diff --git a/src/graph-manager.h b/src/graph-manager.h index 2aef888..39eec14 100644 --- a/src/graph-manager.h +++ b/src/graph-manager.h @@ -304,6 +304,9 @@ namespace VISEQ::GRAPH { } void drawNodes(Vec2Df mouse_pos, Camera2D camera){ + for(auto n : nodes){ + if(KEYS_PRESSED.ctrl && n->hovering()) state->hover_position = n->position; + } for(auto n : nodes){ n->update(); if(n->picked_up) drawNeighborLines(n, mouse_pos, camera); diff --git a/src/main.cpp b/src/main.cpp index 19982f5..af20659 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -494,10 +494,10 @@ int main(){ app.update(); canvas.draw(); - app.draw(state->screen_mouse, canvas.camera); + app.draw(SCREEN_MOUSE, canvas.camera); canvas.drawEnd(); - app.drawUI(state->screen_mouse, canvas.camera); + app.drawUI(SCREEN_MOUSE, canvas.camera); EndDrawing(); } diff --git a/src/midi-node.h b/src/midi-node.h index afebd6f..6f1c5c1 100644 --- a/src/midi-node.h +++ b/src/midi-node.h @@ -87,7 +87,7 @@ namespace VISEQ::GRAPH::NODES { void interact(){ float wheel = GetMouseWheelMove(); - if(state->keys_down.ctrl && !state->keys_down.alt){ + if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){ switch(GraphItem::state->node_mode){ case 0:{ midi_note += wheel; @@ -108,14 +108,14 @@ namespace VISEQ::GRAPH::NODES { if(midi_pitch_bend < 0 ) midi_pitch_bend = 0; if(midi_pitch_bend > 16383 ) midi_pitch_bend = 16383; - } else if(state->keys_down.shift && !state->keys_down.alt) { + } else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) { midi_velocity += wheel; if(midi_velocity < 0 ) midi_velocity = 127; if(midi_velocity > 127 ) midi_velocity = 0; - } else if(state->keys_down.alt) { + } else if(KEYS_DOWN.alt) { switch(GraphItem::state->node_mode){ case 0:{ - float incr = (float)wheel * (state->keys_down.shift ? 100.0f : state->keys_down.ctrl ? 1000.0f : 10.0f); + float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f); midi_gate += incr; if(midi_gate < 0 ) midi_gate = 0; break;} @@ -125,7 +125,7 @@ namespace VISEQ::GRAPH::NODES { if(midi_cc_value > 127 ) midi_cc_value = 127; break;} case 2:{ - float incr = (float)wheel * (state->keys_down.shift ? 100.0f : state->keys_down.ctrl ? 1000.0f : 10.0f); + float incr = (float)wheel * (KEYS_DOWN.shift ? 100.0f : KEYS_DOWN.ctrl ? 1000.0f : 10.0f); midi_pitch_bend += incr; if(midi_pitch_bend < 0 ) midi_pitch_bend = 0; if(midi_pitch_bend > 16383 ) midi_pitch_bend = 16383; @@ -175,7 +175,7 @@ namespace VISEQ::GRAPH::NODES { if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255}); - if(state->keys_down.alt){ + if(KEYS_DOWN.alt){ float value = 0; int offset_gate = 0; switch(mode){ diff --git a/src/node.h b/src/node.h index 7f83d68..6772ddd 100644 --- a/src/node.h +++ b/src/node.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -57,7 +58,7 @@ namespace VISEQ::GRAPH::NODES { virtual void trigger() {}; virtual bool hovering() override { - return state->istate != APP::InteractionState::DRAW_SELECTION && CheckCollisionPointCircle(state->screen_mouse, position, radius); + return STATE != APP::InteractionState::DRAW_SELECTION && CheckCollisionPointCircle(SCREEN_MOUSE, position, radius); } virtual bool entered() override { diff --git a/src/state.h b/src/state.h index 9eb1d2f..af2e4d8 100644 --- a/src/state.h +++ b/src/state.h @@ -4,6 +4,18 @@ #include "vmath.h" #include +#define STATE state->istate +#define SETTINGS state->settings +#define SCREEN_MOUSE state->screen_mouse +#define RAW_MOUSE state->raw_mouse +#define MOD_MOUSE state->mod_mouse +#define MOUSE_LEFT state->mouse_left +#define MOUSE_RIGHT state->mouse_right +#define MOUSE_MIDDLE state->mouse_middle +#define KEYS_DOWN state->keys_down +#define KEYS_PRESSED state->keys_pressed +#define KEYS_RELEASED state->keys_released + namespace VISEQ::APP{ struct AppSettings{ @@ -63,7 +75,9 @@ namespace VISEQ::APP{ Rectangle selection; Vec2Df mouse_delta; - + + Vec2Df hover_position; + void update(Camera2D camera){ if(istate != old_istate) std::cout << state_string[istate] << std::endl; @@ -114,3 +128,7 @@ namespace VISEQ::APP{ } }; } + +namespace VISEQ{ + using IState = VISEQ::APP::InteractionState; +}