#pragma once #include "datatypes.h" #include "edge.h" #include "node.h" #include "raymath.h" #include "state.h" #include namespace VISEQ::GRAPH::NODES { class ConfigNode : public Node{ public: ConfigNode() {std::cout << "ConfigNode Constructor std" << std::endl;} ConfigNode(Vec2Df position) : Node(position) {} std::shared_ptr getPtr(){ return std::static_pointer_cast(shared_from_this()); } NodeType nodeType = NodeType::CONFIGNODE; MIDI::MidiNote midiNote; MIDI::MidiCC midiCC; MIDI::MidiPitchBend midiPitchBend; MIDI::MidiPolyPressure midiPolyPressure; MIDI::MidiPC midiPC; MIDI::MidiAftertouch midiAftertouch; int mode = 0; float radius = 20.0f; virtual NodeType getNodeType() const override {return nodeType;} virtual void trigger() override {} virtual void setMode(int _mode) override { mode = _mode; } MIDI::MidiNote getNotes(){ return midiNote; } MIDI::MidiCC getCC(){ return midiCC; } MIDI::MidiPC getPC(){ return midiPC; } MIDI::MidiPitchBend getPitchBend(){ return midiPitchBend; } MIDI::MidiPolyPressure getPolyPressure(){ return midiPolyPressure; } MIDI::MidiAftertouch getAftertouch(){ return midiAftertouch; } void update() override { Node::update(); mode = state->node_mode; } void interact(){ float wheel = GetMouseWheelMove(); if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){ switch(state->node_mode){ case 0:{ midiNote.note += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 12 : wheel; break;} case 1:{ midiCC.value += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 12 : wheel; break;} case 2:{ midiPitchBend.value += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 12 : wheel; break;} }; if(midiNote.note < -127 ) midiNote.note = -127; if(midiNote.note > 127 ) midiNote.note = 127; if(midiCC.value < -127 ) midiCC.value = -127; if(midiCC.value > 127 ) midiCC.value = 127; if(midiPitchBend.value < -16383 ) midiPitchBend.value = -16383; if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; } else if(KEYS_DOWN.alt) { switch(state->node_mode){ case 0:{ midiNote.channel += wheel; if(midiNote.channel < 0 ) midiNote.channel = 0; if(midiNote.channel > 15) midiNote.channel = 15; break;} case 1:{ midiCC.channel += wheel; if(midiCC.channel < 0 ) midiCC.channel = 0; if(midiCC.channel > 15 ) midiCC.channel = 15; break;} case 2:{ midiPitchBend.channel += KEYS_DOWN.shift ? ((wheel > 0) - (wheel < 0)) * 100 : wheel; if(midiPitchBend.channel < 0 ) midiPitchBend.channel = 0; if(midiPitchBend.channel > 15 ) midiPitchBend.channel = 15; break;} }; } } void draw(Vec2Df mouse, Camera2D cam) override { Node::draw(); if(hovering() || selected) interact(); DrawRing(position, radius, radius+4, 0, 360, 24, (Color){60, 60, 60, 255}); DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255}); Color gate_color = VS_COLOR_GREEN; switch(mode){ case 0:{ gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){180, 210, 115 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE); break;} case 1:{ gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){229, 181, 103 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE); break;} case 2:{ gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){232, 125, 62 + 70, (unsigned char)Clamp(255, 0, 255)}, WHITE); break;} } if(!picked_up && !selected && !in_selection_rect && !hovering()) DrawCircle(position.x, position.y, radius, gate_color); 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}); 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(KEYS_DOWN.alt){ float value = 0; int offset_gate = 0; switch(mode){ case 0: value = (float)midiNote.channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); break; case 1: value = (float)midiCC.channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); break; case 2: value = (float)midiPitchBend.channel; offset_gate = MeasureText(std::format("{}", value).c_str(), 12); DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE ); break; } } else { switch(mode){ case 0:{ int offset = MeasureText(std::format("{:+}", midiNote.note).c_str(), 12); DrawText(std::format("{:+}", midiNote.note).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} case 1:{ int offset = MeasureText(std::format("{:+}", midiCC.value).c_str(), 12); DrawText(std::format("{:+}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} case 2:{ int offset = MeasureText(std::format("{:+}", midiPitchBend.value).c_str(), 12); DrawText(std::format("{:+}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} } } if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200}); DrawText(std::format("{}", id).c_str(), position.x + 20.0f, position.y + 20.0f, 10, WHITE); } friend void to_json(json& j, const ConfigNode& N){ std::vector conns; std::ranges::transform(N.connections.begin(), N.connections.end(), std::back_inserter(conns), [](VISEQ::GRAPH::EDGES::SPTR_Edge e){ return e->id;}); j = json{ {"id", N.id}, {"position", N.position}, {"distributionMode", N.distributionMode}, {"nodeType", N.nodeType}, {"midi_note_channel",N.midiNote.channel}, {"midi_note_note",N.midiNote.note}, {"midi_note_velocity",N.midiNote.velocity}, {"midi_note_gate",N.midiNote.gate}, {"midi_cc_channel",N.midiCC.channel}, {"midi_cc_control",N.midiCC.control}, {"midi_cc_value",N.midiCC.value}, {"midi_pc_channel",N.midiPC.channel}, {"midi_pc_program",N.midiPC.program}, {"midi_pc_value",N.midiPC.value}, {"midi_pitch_bend_channel",N.midiPitchBend.channel}, {"midi_pitch_bend_value",N.midiPitchBend.value}, {"midi_aftertouch_channel",N.midiAftertouch.channel}, {"midi_aftertouch_value",N.midiAftertouch.value}, {"midi_polypressure_channel",N.midiPolyPressure.channel}, {"midi_polypressure_value",N.midiPolyPressure.value}, {"connections",conns}}; } friend void from_json(const json& j, ConfigNode& N){ std::cout << "configNode from_json" << std::endl; j.at("id").get_to(N.id); j.at("position").get_to(N.position); j.at("distributionMode").get_to(N.distributionMode); j.at("nodeType").get_to(N.nodeType); j.at("midi_note_channel").get_to(N.midiNote.channel); j.at("midi_note_note").get_to(N.midiNote.note); j.at("midi_note_velocity").get_to(N.midiNote.velocity); j.at("midi_note_gate").get_to(N.midiNote.gate); j.at("midi_cc_channel").get_to(N.midiCC.channel); j.at("midi_cc_control").get_to(N.midiCC.control); j.at("midi_cc_value").get_to(N.midiCC.value); j.at("midi_pc_channel").get_to(N.midiPC.channel); j.at("midi_pc_program").get_to(N.midiPC.program); j.at("midi_pc_value").get_to(N.midiPC.value); j.at("midi_pitch_bend_channel").get_to(N.midiPitchBend.channel); j.at("midi_pitch_bend_value").get_to(N.midiPitchBend.value); j.at("midi_aftertouch_channel").get_to(N.midiAftertouch.channel); j.at("midi_aftertouch_value").get_to(N.midiAftertouch.value); j.at("midi_polypressure_channel").get_to(N.midiPolyPressure.channel); j.at("midi_polypressure_value").get_to(N.midiPolyPressure.value); //j.at("connections").get_to(N.connections); } }; }