diff --git a/Makefile b/Makefile index 84f779b..95fd776 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ LDLIBS := -lraylib -lasound -llibremidi -pthread LDFLAGS := -Llib -L/usr/lib -L/usr/local/lib SRCS := $(wildcard src/*.cpp) +HDRS := $(wildcard src/*.h) OBJECTS := $(patsubst src/%.cpp,build/%.o, $(SRCS)) viseq: $(OBJECTS) @@ -17,6 +18,9 @@ $(OBJECTS): build/%.o : src/%.cpp @mkdir -p build $(CXX) -c $< -o $@ $(CXXFLAGS) $(CXXINC) +src/%.cpp: $HDRS + touch $@ + clean: rm -f build/* rm -f viseq diff --git a/resources/textures/round-delete.png b/resources/textures/round-delete.png new file mode 100644 index 0000000..53298e6 Binary files /dev/null and b/resources/textures/round-delete.png differ diff --git a/src/button.h b/src/button.h index 8e5c702..2201441 100644 --- a/src/button.h +++ b/src/button.h @@ -12,6 +12,13 @@ inline bool ViButton(Vec2Df mp, float x, float y, float radius, Color color){ return (Vector2Distance(mp, (Vector2){x,y}) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)); } +inline bool ViTexButton(Vec2Df mp, Vec2Df position, float rotation, float radius, Texture2D tex, Color color){ + float scale = (radius*2.0f) / (float)tex.width; + Vec2Df center_pos = position - Vec2Df((tex.width*scale)/1.0f * sin(rotation), (tex.height*scale)/1.0f * cos(rotation)); + DrawTextureEx(tex, center_pos, rotation, scale, color); + return (Vector2Distance(mp, position) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)); +} + inline bool ViButton(Vec2Df mp, Vec2Df position, float radius, Color color){ return ViButton(mp, position.x, position.y, radius, color); } diff --git a/src/canvas.cpp b/src/canvas.cpp index c0f08b5..635e3ef 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -21,14 +21,14 @@ namespace VISEQ::APP::CANVAS { } void Canvas::pickUp() { - std::cout << "canvas pickUp" << std::endl; + //std::cout << "canvas pickUp" << std::endl; BASE::Draggable::pickUp(); select_start = SCREEN_MOUSE; state->pushEvent({getPtr(), Interaction::DESELECT}); } void Canvas::putDown() { - std::cout << "canvas putDown" << std::endl; + //std::cout << "canvas putDown" << std::endl; BASE::Draggable::putDown(); state->pushEvent({getPtr(), Interaction::SELECT}); } diff --git a/src/datatypes.h b/src/datatypes.h index 29cad7c..116eb0f 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -15,6 +15,7 @@ #define VS_COLOR_PURPLE (Color){158, 134, 200, 255} #define VS_COLOR_PINK (Color){176, 82, 121, 255} #define VS_COLOR_BLUE (Color){108, 153, 187, 255} +#define VS_COLOR_LIGHTBLUE (Color){143, 206, 255, 255} #define VS_COLOR_RED (Color){195, 83, 85, 255} #define VS_COLOR_BROWN (Color){84, 75, 61, 255} diff --git a/src/graph-manager.cpp b/src/graph-manager.cpp index 68d1b49..15b28d6 100644 --- a/src/graph-manager.cpp +++ b/src/graph-manager.cpp @@ -2,6 +2,7 @@ #include "config-node.h" #include "datatypes.h" +#include "helper.h" #include "state.h" #include "vmath.h" #include "raylib.h" @@ -29,6 +30,10 @@ namespace VISEQ::GRAPH{ return shared_from_this(); } + void GraphManager::loadTextures(){ + tex_delete = LoadTexture("resources/textures/round-delete.png"); + } + int GraphManager::getNodesSize(){ return nodes.size(); } @@ -344,6 +349,7 @@ namespace VISEQ::GRAPH{ void GraphManager::update(){ if(!remove_edges.empty()) removeEdges(); if(!split_edges.empty()) splitEdges(); + if(tex_delete.width == 0 && IsWindowReady()) loadTextures(); } void GraphManager::drawEdges(Vec2Df mouse_pos, Camera2D cam){ @@ -365,6 +371,8 @@ namespace VISEQ::GRAPH{ unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f); unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f); + float opacity_normalized = Clamp((float)opacity / 255.0f, .0f, 1.0f); + float midi_gate_v1 = 0.0f; float midi_gate_v2 = 0.0f; @@ -426,7 +434,7 @@ namespace VISEQ::GRAPH{ DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, VS_COLOR_BLUE); } - if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) removeEdge(c); + if(IsWindowReady() && ViTexButton(mouse_pos, flip_handle, HELPER::GetRotation(from_to_handle, to_from_handle), 8.0f, tex_delete, ColorLerp(Fade(VS_COLOR_WHITE, .0f), Fade(VS_COLOR_WHITE, 1.0f), opacity_normalized) )) removeEdge(c); } } diff --git a/src/graph-manager.h b/src/graph-manager.h index 1292080..42a185c 100644 --- a/src/graph-manager.h +++ b/src/graph-manager.h @@ -40,6 +40,7 @@ namespace VISEQ::GRAPH { GraphManager() {} std::shared_ptr getPtr(); + void loadTextures(); int getNodesSize(); void createMidiNode(Vec2Df position); void createConfigNode(Vec2Df position); @@ -84,6 +85,8 @@ namespace VISEQ::GRAPH { friend void from_json(const json& j, std::shared_ptr& G); friend void to_json(json& j, const std::shared_ptr& G); + + Texture2D tex_delete; }; } diff --git a/src/helper.h b/src/helper.h index 9fc3858..2c17e95 100644 --- a/src/helper.h +++ b/src/helper.h @@ -15,4 +15,8 @@ namespace VISEQ::HELPER{ float rotation = Vector2Angle((Vector2){1,0}, (end - start)) * RAD2DEG; DrawTextPro(GetFontDefault(), text.c_str(), text_position, (Vector2){0,0}, rotation, size, 2.0f, col); } + + inline float GetRotation(Vec2Df start, Vec2Df end){ + return Vector2Angle((Vector2){1,0}, (end - start)) * RAD2DEG; + } } diff --git a/src/interactable.h b/src/interactable.h index 4a75844..09878a2 100644 --- a/src/interactable.h +++ b/src/interactable.h @@ -14,7 +14,7 @@ namespace VISEQ::BASE { } virtual ~Interactable() {} - + bool is_hovering = false; int z_index = 0; diff --git a/src/midi-node.cpp b/src/midi-node.cpp index 093b263..0f35dcf 100644 --- a/src/midi-node.cpp +++ b/src/midi-node.cpp @@ -198,21 +198,24 @@ namespace VISEQ::GRAPH::NODES { if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPCProgram(wheel); break;} case PB:{ - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*100); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*1000); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*10); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*64); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*2048); + if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel*256); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPitchBend(wheel); break;} case AT:{ - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*100); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*1000); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*10); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*10); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel*100); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiAftertouch(wheel); break;} case PP:{ if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPolyPressureNote(wheel); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) modMidiPolyPressureNote(wheel*10); - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*100); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*1000); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*10); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*64); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*2048); + if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel*256); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) modMidiPolyPressureValue(wheel); break;} }; } @@ -252,23 +255,22 @@ namespace VISEQ::GRAPH::NODES { break;} } - DrawRing(position, radius, radius + 4, 0, 360, 24, (Color){60, 60, 60, 255}); - DrawRing(position, radius, radius + 4, 0.0f - 90.0f, (360.0f/127.0f) * getNotes().velocity - 90.0f, 24, (Color){158, 134, 200, 255}); - DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255}); + DrawRing(position, radius, radius + 4, 0, 360, 24, VS_COLOR_DARKGREY); + //DrawRing(position, radius, radius + 4, 0.0f - 90.0f, (360.0f/127.0f) * getNotes().velocity - 90.0f, 24, (Color){158, 134, 200, 255}); + if(!selected) DrawCircleLinesV(position, radius + 4, VS_COLOR_GREY); float trigger_alpha = (1.f / getNotes().gate) * fade; - if(!picked_up && !selected && !in_selection_rect && !hovering()) DrawCircle(position.x, position.y, radius, ColorLerp(state->mode_color, VS_COLOR_RED, trigger_alpha)); - if(picked_up || in_selection_rect || hovering()) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255}); - if(selected) DrawCircle(position.x, position.y, radius, (Color){255, 153, 187, 255}); + DrawCircle(position.x, position.y, radius, ColorLerp(state->settings.mode_colors[mode], VS_COLOR_RED, trigger_alpha)); + if(hovering()) DrawCircleLinesV(position, radius + 4, VS_COLOR_PINK); + if(picked_up || (in_selection_rect && MOUSE_LEFT.down) || selected) DrawCircleLinesV(position, radius + 4, VS_COLOR_LIGHTBLUE); + //if(selected) DrawCircle(position.x, position.y, radius, (Color){255, 153, 187, 255}); if(distributionMode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK); if(distributionMode == Distribution::ROUNDROBIN) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_YELLOW); - if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255}); + //if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255}); - // TODO draw values of corresponding attribute when modifiers are pressed - //VMATH::Vec2D title_position = position + VMATH::Vec2D(radius + 7.0f, -(radius + 7.0f)); VMATH::Vec2D desc_position = position + VMATH::Vec2D(radius + 7.0f, radius + 7.0f); switch(mode){ case NOTE:{ @@ -285,10 +287,10 @@ namespace VISEQ::GRAPH::NODES { if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("VALUE", desc_position, 8, WHITE); if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("VELOCITY", desc_position, 8, WHITE); - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE +.1", desc_position, 8, WHITE); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE +1.0", desc_position, 8, WHITE); - if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE +.01", desc_position, 8, WHITE); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE +.001", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE 0.1s", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE 1.0s", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE 0.01s", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("GATE 0.001s", desc_position, 8, WHITE); } break;} case CC:{ @@ -310,14 +312,23 @@ namespace VISEQ::GRAPH::NODES { } break;} case PB:{ - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPitchBend().value), position, 12, WHITE); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPitchBend().value), position, 12, WHITE); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPitchBend().value), position, 12, WHITE); + DrawCenteredText(std::format("{}", getPitchBend().value), position, 10, WHITE); + if(selected){ + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("PITCHBEND", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("64", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("2048", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("256", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, WHITE); + } break;} case AT:{ - if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, WHITE); - if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, WHITE); - if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, WHITE); + DrawCenteredText(std::format("{}", getAftertouch().value), position, 12, WHITE); + if(selected){ + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("AFTERTOUCH", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("10", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("100", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, WHITE); + } break;} case PP:{ if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawCenteredText(MIDI::Notes[getPolyPressure().note], position, 12, WHITE); @@ -325,6 +336,13 @@ namespace VISEQ::GRAPH::NODES { if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, WHITE); if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, WHITE); if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawCenteredText(std::format("{}", getPolyPressure().value), position, 12, WHITE); + if(selected){ + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && !KEYS_DOWN.alt) DrawText("POLYPRESSURE", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("64", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && !KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("2048", desc_position, 8, WHITE); + if(!KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("256", desc_position, 8, WHITE); + if(KEYS_DOWN.ctrl && KEYS_DOWN.shift && KEYS_DOWN.alt) DrawText("1", desc_position, 8, WHITE); + } break;} }; diff --git a/src/node.cpp b/src/node.cpp index e01cae4..4dc25bf 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -63,6 +63,7 @@ namespace VISEQ::GRAPH::NODES { c->update(); } if(free_connectors == 0) addConnector(); + in_selection_rect = CheckCollisionPointRec(position, state->selection); } void Node::draw(Vec2Df mp, Camera2D cam) {} diff --git a/src/selectable.h b/src/selectable.h index 9213a48..f142e88 100644 --- a/src/selectable.h +++ b/src/selectable.h @@ -9,13 +9,14 @@ namespace VISEQ::BASE { Selectable() {} bool in_selection_rect = false; - bool selected = false; + bool selected = false; bool copied = false; bool highlighted = false; bool erase = false; Vec2Df selection_offset; + void update(); virtual bool clicked() override; virtual bool select() = 0; diff --git a/src/ui.cpp b/src/ui.cpp index 2ac3be7..17422ee 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -93,14 +93,14 @@ namespace VISEQ::APP::UI{ DrawText(std::format("{}", gm->getNodesSize()).c_str(), 20, state->settings.height - 70, 15, VS_COLOR_WHITE); DrawFPS(20, state->settings.height - 30); - std::string shorts[6] = {"NT","CC","PC","PB","AT","PP"}; - for(int i = 0; i < 6; ++i){ - Color col = state->settings.mode_colors[i]; - Vec2Df pos = {state->settings.width - (6.0f*75.0f) + i*75.0f, state->settings.height - 75.0f}; - DrawRing(pos, 30.0f, 34.0f, 0.0f, 360.0f, 24, state->node_mode == i ? VS_COLOR_WHITE : (Color){0,0,0,0}); - DrawCircleV(pos, 30.0f, col); - DrawCenteredText(shorts[i], pos, 20, WHITE); - } + // std::string shorts[6] = {"NT","CC","PC","PB","AT","PP"}; + // for(int i = 0; i < 6; ++i){ + // Color col = state->settings.mode_colors[i]; + // Vec2Df pos = {state->settings.width - (6.0f*75.0f) + i*75.0f, state->settings.height - 75.0f}; + // DrawRing(pos, 30.0f, 34.0f, 0.0f, 360.0f, 24, state->node_mode == i ? VS_COLOR_WHITE : (Color){0,0,0,0}); + // DrawCircleV(pos, 30.0f, col); + // DrawCenteredText(shorts[i], pos, 20, WHITE); + // } } void AppUI::DrawCenteredText(std::string text, Vec2Df position, int size, Color color){ diff --git a/src/vmath.h b/src/vmath.h index e4ad3d5..bad5018 100644 --- a/src/vmath.h +++ b/src/vmath.h @@ -166,7 +166,7 @@ namespace VISEQ::VMATH{ template Vec2D polarToCartesian(T r, T q) { - return Vec2D{r * cos(q), r * sin(q)}; + return Vec2D{r * (T)cos(q), r * (T)sin(q)}; } }