2024-10-09 02:01:23 +02:00
/*
*
* VISEQ - Visual Sequencer
*
*
*/
2024-10-13 04:22:09 +02:00
/*Background: (46, 46, 46); #2e2e2e*/
/*Comments: (121, 121, 121); #797979*/
/*White: (214, 214, 214); #d6d6d6*/
/*Yellow: (229, 181, 103); #e5b567*/
/*Green: (180, 210, 115); #b4d273*/
/*Orange: (232, 125, 62); #e87d3e*/
/*Purple: (158, 134, 200); #9e86c8*/
/*Pink: (176, 82, 121); #b05279*/
/*Blue: (108, 153, 187); #6c99bb*/
2024-10-25 16:41:37 +02:00
# define RAYGUI_IMPLEMENTATION
2024-10-16 02:26:02 +02:00
# include "datatypes.h"
2024-10-23 03:25:57 +02:00
# include <ranges>
2024-10-13 04:22:09 +02:00
# include <raylib.h>
# include <raymath.h>
2024-10-09 02:01:23 +02:00
# include <cstdlib>
# include <stdio.h>
# include <cmath>
2024-10-25 16:41:37 +02:00
# include "state-manager.h"
2024-10-22 01:55:31 +02:00
AppState app ;
2024-10-09 02:01:23 +02:00
Vec2D < float > mouse_pos ;
Vec2D < float > drag_start ;
2024-10-25 16:41:37 +02:00
Camera2D camera = { { 0 } } ;
2024-10-09 02:01:23 +02:00
bool mouse_clicked = false ;
bool mouse_touched = false ;
2024-10-13 04:22:09 +02:00
bool mouse_dragging = false ;
2024-10-09 02:01:23 +02:00
2024-10-25 16:41:37 +02:00
//#include "ui.h"
2024-10-09 02:01:23 +02:00
int main ( ) {
srand ( time ( NULL ) ) ;
2024-10-13 04:22:09 +02:00
InitWindow ( 2560 , 1440 , " VISEQ " ) ;
2024-10-25 16:41:37 +02:00
app . ui . init ( ) ;
2024-10-13 04:22:09 +02:00
int monitor = 0 ; //GetCurrentMonitor();
SetWindowMonitor ( monitor ) ;
2024-10-25 16:41:37 +02:00
app . settings . fps = 1.0f ;
app . settings . bpm = 120.0f ;
app . settings . grid = 120.0f ; //round(((app.settings.fps / (app.settings.bpm / 60.0f)) * app.settings.speed) / 4.0f); // from quarter notes to 16th notes = div by 4
// app.settings.speed = round((((app.settings.fps / (app.settings.bpm / 60.0f)) / app.settings.grid) / 4.0f) / 10.0f) * 10.0f;
2024-10-23 03:25:57 +02:00
2024-10-25 02:43:41 +02:00
// 16th note = 120px (festgelegt)
// ganze note = 1920px
// ganze note bei 120bpm = 2s
// 120bpm = 960px/s
2024-10-25 16:41:37 +02:00
app . settings . speed = ( app . settings . grid * 8.0f ) * ( app . settings . bpm / 120.f ) ;
app . settings . width = GetMonitorWidth ( monitor ) ;
app . settings . height = GetMonitorHeight ( monitor ) ;
2024-10-25 02:43:41 +02:00
SetTargetFPS ( 60.0f ) ;
2024-10-13 04:22:09 +02:00
2024-10-25 16:41:37 +02:00
camera . target = ( Vector2 ) { app . settings . width / 2.0f , app . settings . height / 2.0f } ;
camera . offset = ( Vector2 ) { app . settings . width / 2.0f , app . settings . height / 2.0f } ;
2024-10-13 04:22:09 +02:00
camera . rotation = 0.0f ;
2024-10-25 16:41:37 +02:00
camera . zoom = 1.0f ;
2024-10-09 02:01:23 +02:00
2024-10-23 00:23:24 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
2024-10-25 16:41:37 +02:00
app . nm . addNode ( ( float ) i * app . settings . grid + 10 * app . settings . grid , 5 * app . settings . grid ) ;
2024-10-23 00:23:24 +02:00
}
for ( int i = 3 ; i > = 0 ; - - i ) {
2024-10-25 16:41:37 +02:00
app . nm . addNode ( ( float ) i * app . settings . grid + 10 * app . settings . grid , 6 * app . settings . grid ) ;
2024-10-09 02:01:23 +02:00
}
2024-10-22 01:55:31 +02:00
2024-10-23 00:23:24 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
2024-10-25 16:41:37 +02:00
app . cm . addConnection ( & app . nm . nodes [ i ] , & app . nm . nodes [ ( i + 1 ) % 8 ] ) ;
2024-10-23 00:23:24 +02:00
}
2024-10-25 16:41:37 +02:00
app . sm . addSignalAtNode ( & app . nm . nodes . front ( ) ) ;
2024-10-18 01:27:14 +02:00
2024-10-25 16:41:37 +02:00
app . sm . startSignalThread ( ) ;
2024-10-22 01:55:31 +02:00
2024-10-13 15:07:19 +02:00
Vec2D < float > drag_offset ;
2024-10-09 02:01:23 +02:00
2024-10-20 23:42:38 +02:00
Vec2D < float > cam_drag_offset ;
Vec2D < float > cam_mouse_drag_offset ;
2024-10-16 02:26:02 +02:00
double drag_timer = GetTime ( ) ;
2024-10-25 02:43:41 +02:00
enum InteractionState { HOVER_CANVAS , HOVER_NODE , HOVER_CONNECTOR , DRAG_NODE , CONNECT_NODE , DRAW_SELECTION } ;
InteractionState istate = HOVER_CANVAS ;
2024-10-24 21:05:05 +02:00
2024-10-23 00:23:24 +02:00
Vec2D < float > select_start ;
Rectangle selection ;
2024-10-24 00:39:39 +02:00
ToggleFullscreen ( ) ;
2024-10-13 04:22:09 +02:00
while ( ! WindowShouldClose ( ) ) {
2024-10-09 02:01:23 +02:00
2024-10-25 02:43:41 +02:00
BeginDrawing ( ) ;
ClearBackground ( ( Color ) { 46 , 46 , 46 } ) ;
BeginMode2D ( camera ) ;
2024-10-25 16:41:37 +02:00
//app.settings.mutex.lock();
app . settings . speed = ( app . settings . grid * 8.0f ) * ( app . settings . bpm / 120.f ) ;
2024-10-23 03:25:57 +02:00
2024-10-13 04:22:09 +02:00
Vector2 mp = GetScreenToWorld2D ( GetMousePosition ( ) , camera ) ;
2024-10-10 02:59:27 +02:00
Vec2D < float > mouse_pos = { ( float ) mp . x , ( float ) mp . y } ;
2024-10-20 23:42:38 +02:00
Vec2D < float > cam_pos = { camera . offset . x , camera . offset . y } ;
2024-10-13 04:22:09 +02:00
bool mouse_down = IsMouseButtonDown ( MOUSE_BUTTON_LEFT ) ;
bool mouse_clicked = IsMouseButtonPressed ( MOUSE_BUTTON_LEFT ) ;
bool mouse_released = IsMouseButtonReleased ( MOUSE_BUTTON_LEFT ) ;
2024-10-24 21:05:05 +02:00
bool mouse_right_down = IsMouseButtonDown ( MOUSE_BUTTON_RIGHT ) ;
bool mouse_right_clicked = IsMouseButtonPressed ( MOUSE_BUTTON_RIGHT ) ;
bool mouse_right_released = IsMouseButtonReleased ( MOUSE_BUTTON_RIGHT ) ;
2024-10-10 02:59:27 +02:00
2024-10-25 02:43:41 +02:00
Vec2D < float > mouse_delta = { GetMouseDelta ( ) . x , GetMouseDelta ( ) . y } ;
Vec2D < float > delta = mouse_delta * ( - 1.0f / camera . zoom ) ;
2024-10-24 00:39:39 +02:00
2024-10-25 16:41:37 +02:00
auto dragging_nodes = app . nm . nodes | std : : ranges : : views : : filter ( [ ] ( Node n ) { return n . dragging ; } ) ;
auto connecting_nodes = app . nm . nodes | std : : ranges : : views : : filter ( [ ] ( Node n ) { return n . connecting ; } ) ;
auto selected_nodes = app . nm . nodes | std : : ranges : : views : : filter ( [ ] ( Node n ) { return n . selected & & ! n . dragging ; } ) ;
auto hovering_nodes = app . nm . nodes | std : : ranges : : views : : filter ( [ & mouse_pos ] ( Node n ) { return CheckCollisionPointCircle ( mouse_pos , n . position , n . radius ) ; } ) ;
auto hovering_connectors = app . nm . nodes | std : : ranges : : views : : filter ( [ & mouse_pos ] ( Node n ) { return CheckCollisionPointCircle ( mouse_pos , ( n . position - ( ( n . position - mouse_pos ) ) . norm ( ) * ( n . radius + 14.0f ) ) , 8.0f ) ; } ) ;
2024-10-24 00:39:39 +02:00
2024-10-25 02:43:41 +02:00
if ( ! 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 : : DRAW_SELECTION ;
2024-10-24 21:05:05 +02:00
2024-10-25 02:43:41 +02:00
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 ( ) & & istate = = InteractionState : : HOVER_CANVAS ) istate = InteractionState : : HOVER_CONNECTOR ;
if ( ! connecting_nodes . empty ( ) ) istate = InteractionState : : CONNECT_NODE ;
2024-10-24 21:05:05 +02:00
2024-10-25 02:43:41 +02:00
switch ( istate ) {
case InteractionState : : HOVER_CANVAS :
if ( mouse_right_down ) {
camera . target = Vector2Add ( camera . target , delta ) ;
}
break ;
case InteractionState : : DRAW_SELECTION :
if ( mouse_clicked ) {
select_start = mouse_pos ;
}
if ( mouse_down ) {
Vec2D < float > 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 } ;
Vec2D < float > 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 } ;
2024-10-25 16:41:37 +02:00
for ( auto & n : app . nm . nodes ) {
2024-10-25 02:43:41 +02:00
if ( CheckCollisionPointRec ( n . position , selection ) ) {
n . in_rect = true ;
} else {
n . in_rect = false ;
}
}
}
2024-10-24 21:05:05 +02:00
2024-10-25 02:43:41 +02:00
if ( mouse_released ) {
2024-10-25 16:41:37 +02:00
for ( auto & n : app . nm . nodes ) {
2024-10-25 02:43:41 +02:00
if ( CheckCollisionPointRec ( n . position , selection ) ) {
n . selected = true ;
n . in_rect = false ;
} else {
if ( ! IsKeyDown ( KEY_LEFT_SHIFT ) ) n . selected = false ;
}
}
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 ( IsKeyDown ( KEY_LEFT_CONTROL ) ) {
2024-10-25 16:41:37 +02:00
dragging_nodes . front ( ) . position = ( Vec2D < float > ) { round ( ( mouse_pos . x + dragging_nodes . front ( ) . drag_offset . x ) / app . settings . grid ) * app . settings . grid , round ( ( mouse_pos . y + dragging_nodes . front ( ) . drag_offset . y ) / app . settings . grid ) * app . settings . grid } ;
2024-10-25 02:43:41 +02:00
} else {
dragging_nodes . front ( ) . position = mouse_pos + dragging_nodes . front ( ) . drag_offset ;
}
for ( auto & n : selected_nodes ) {
if ( ! n . picked_up ) n . drag_offset = n . position - dragging_nodes . front ( ) . position ;
n . picked_up = true ;
n . position = dragging_nodes . front ( ) . position + n . drag_offset ;
}
2024-10-24 21:05:05 +02:00
2024-10-25 02:43:41 +02:00
if ( mouse_released ) {
dragging_nodes . front ( ) . dragging = false ;
for ( auto & n : selected_nodes ) {
n . picked_up = false ;
}
}
break ;
case InteractionState : : HOVER_CONNECTOR :
if ( mouse_clicked ) hovering_connectors . front ( ) . connecting = true ;
break ;
case InteractionState : : CONNECT_NODE :
Vec2D < float > connector_position = connecting_nodes . front ( ) . position - ( ( connecting_nodes . front ( ) . position - mouse_pos ) ) . norm ( ) * ( connecting_nodes . front ( ) . radius + 14.0f ) ;
if ( connecting_nodes . front ( ) . connecting & & mouse_down ) {
DrawLine ( connector_position . x , connector_position . y , mouse_pos . x , mouse_pos . y , ( Color ) { 229 , 181 , 103 , 255 } ) ;
}
if ( mouse_released ) {
2024-10-25 16:41:37 +02:00
if ( & hovering_nodes . front ( ) ! = & connecting_nodes . front ( ) & & & connecting_nodes . front ( ) ! = & hovering_connectors . front ( ) ) {
if ( ! hovering_nodes . empty ( ) ) {
app . cm . addConnection ( & connecting_nodes . front ( ) , & hovering_nodes . front ( ) ) ;
} else if ( ! hovering_connectors . empty ( ) ) {
app . cm . addConnection ( & connecting_nodes . front ( ) , & hovering_connectors . front ( ) ) ;
} else {
app . nm . addNode ( mouse_pos . x , mouse_pos . y ) ;
app . cm . addConnection ( & connecting_nodes . front ( ) , & app . nm . nodes . back ( ) ) ;
}
2024-10-25 02:43:41 +02:00
}
connecting_nodes . front ( ) . connecting = false ;
}
break ;
} ;
2024-10-20 23:42:38 +02:00
float wheel = GetMouseWheelMove ( ) ;
2024-10-23 00:23:24 +02:00
if ( wheel ! = 0 ) {
2024-10-24 00:39:39 +02:00
if ( ! hovering_nodes . empty ( ) & & IsKeyDown ( KEY_LEFT_CONTROL ) ) {
2024-10-24 21:05:05 +02:00
hovering_nodes . front ( ) . midi_note + = wheel ;
2024-10-25 16:41:37 +02:00
if ( hovering_nodes . front ( ) . midi_note < 0 ) hovering_nodes . front ( ) . midi_note = app . sm . midi . midiNotes . size ( ) - 1 ;
if ( hovering_nodes . front ( ) . midi_note > = app . sm . midi . midiNotes . size ( ) ) hovering_nodes . front ( ) . midi_note = 0 ;
2024-10-24 00:39:39 +02:00
} else {
Vector2 mouseWorldPos = GetScreenToWorld2D ( GetMousePosition ( ) , camera ) ;
camera . offset = GetMousePosition ( ) ;
camera . target = mouseWorldPos ;
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 ) ;
}
2024-10-20 23:42:38 +02:00
}
2024-10-25 16:41:37 +02:00
for ( int x = - app . settings . grid * 100 ; x < app . settings . grid * 100 ; x + = app . settings . grid ) {
for ( int y = - app . settings . grid * 100 ; y < app . settings . grid * 100 ; y + = app . settings . grid ) {
2024-10-25 02:43:41 +02:00
DrawPixel ( x , y , ( Color ) { 130 , 130 , 130 , 200 } ) ;
}
2024-10-10 02:59:27 +02:00
}
2024-10-25 16:41:37 +02:00
app . draw ( & mouse_pos , & camera ) ;
2024-10-23 03:25:57 +02:00
2024-10-25 02:43:41 +02:00
EndMode2D ( ) ;
2024-10-24 00:39:39 +02:00
2024-10-25 16:41:37 +02:00
app . drawUI ( & mouse_pos , & camera ) ;
2024-10-13 04:22:09 +02:00
EndDrawing ( ) ;
2024-10-09 02:01:23 +02:00
}
2024-10-13 04:22:09 +02:00
CloseWindow ( ) ;
return 0 ;
2024-10-09 02:01:23 +02:00
}
2024-10-25 16:41:37 +02:00
/*void drawGUI(){*/
/**/
/* // Main Config Window*/
/* GuiWindowBox((Rectangle){0,0,280,(float)app.settings.height}, "config");*/
/* {*/
/* const int s_controls = 55;*/
/* if(GuiButton((Rectangle){20, (float)s_controls, 60, 30}, "PLAY")) sm.play ? sm.pause() : sm.start();*/
/* if(GuiButton((Rectangle){100, (float)s_controls, 60, 30}, "STOP")) sm.stop();*/
/* if(GuiButton((Rectangle){180, (float)s_controls, 60, 30}, "RESET")) sm.reset();*/
/**/
/* const int s_bpm = s_controls + 35;*/
/* GuiLabel((Rectangle){20, (float)s_bpm, 120, 20}, "TIMING");*/
/* GuiLabel((Rectangle){200, (float)s_bpm, 40, 20}, std::format("{}",app.settings.bpm).c_str());*/
/* float _bpm = (float)app.settings.bpm;*/
/* GuiSlider((Rectangle){20, (float)s_bpm + 25, 240, 20}, "", "", &_bpm, 1, 300);*/
/* app.settings.bpm = _bpm;*/
/**/
/* int s_midi = s_bpm + 55;*/
/* GuiLabel((Rectangle){20, (float)s_midi, 240, 20}, "MIDI OUT");*/
/* int i = 0;*/
/* for(auto& mo : midi.midi_out_ports){*/
/* GuiCheckBox((Rectangle){20, (float)s_midi + 25 + i*20.0f, 20, 20}, mo.port.port_name.c_str(), &mo.enabled);*/
/* i++;*/
/* }*/
/**/
/* if(GuiButton((Rectangle){20, (float)s_midi + 45 + i*20.0f, 240, 20}, "ENABLE FOR ALL")) {*/
/* for(auto &midis : midi.midi_out_ports){*/
/* if(midis.enabled){*/
/* for(auto &n : nodes){*/
/* n.midi_outs[midis.number].enabled = true;*/
/* }*/
/* }*/
/* }*/
/* }*/
/**/
/* int s_signal = s_midi + 90 + i*20;*/
/* GuiLabel((Rectangle){20, (float)s_signal, 240, 20}, "SIGNALS");*/
/* if(GuiButton((Rectangle){20, (float)s_signal + 35, 240, 20}, "ADD RANDOM SIGNAL")){*/
/* int ni = rand() % nodes.size();*/
/* sm.addSignalAtNode(&nodes[ni]);*/
/* }*/
/**/
/* int signal_configs = 0;*/
/* for(auto &s : sm.signals){*/
/* if(GuiButton((Rectangle){20,(float)s_signal+70 + signal_configs*20, 20, 20},"X")) sm.removeSignal(signal_configs);*/
/* DrawCircle(55, s_signal+80 + signal_configs*20, 6.0F, s.color);*/
/* float s_multiplier = round(s.multiplier*10.0f)/10.0f;*/
/* float signal_bpm = app.settings.bpm * s.multiplier;*/
/* GuiSlider((Rectangle){70, (float)s_signal+70 + signal_configs*20, 160, 20}, "", std::format("{:.1f}",signal_bpm).c_str(), &s_multiplier, 0.1, 2);*/
/* s.multiplier = s_multiplier;*/
/* s.speed = app.settings.speed;*/
/* signal_configs++;*/
/* }*/
/**/
/* int s_nodes = s_signal + 60 + signal_configs*20;*/
/* GuiLabel((Rectangle){20, (float)s_nodes + 30, 240, 20}, "NODES");*/
/* if(GuiButton((Rectangle){20, (float)s_nodes + 60, 240, 20}, "ADD RANDOM NODE")){*/
/* nodes.emplace_back(200.0f, 200.0f, 15.0f);*/
/* }*/
/**/
/* DrawFPS(20, app.settings.height - 30);*/
/* }*/
/**/
/* // Per Node Config Windows*/
/* for(auto& n : nodes){*/
/* Vector2 np = GetWorldToScreen2D((Vector2){n.position.x, n.position.y}, camera);*/
/**/
/* for(auto& mo : midi.midi_out_ports){*/
/* if(!n.midi_outs.contains(mo.number) && mo.enabled){*/
/* n.midi_outs[mo.number] = {mo.number, mo.port.port_name, false}; */
/* }*/
/* if(n.midi_outs.contains(mo.number) && !mo.enabled){*/
/* n.midi_outs.erase(mo.number);*/
/* }*/
/* }*/
/**/
/* if(n.config){*/
/* n.config = !GuiWindowBox((Rectangle){np.x + 10, np.y + 10, 240, 440}, "config");*/
/**/
/* int option = n.mode;*/
/* GuiToggleGroup((Rectangle){ np.x + 20, np.y + 40, 110, 20 }, "Round Robin;Random", &option);*/
/* n.mode = (Distribution)option;*/
/**/
/* GuiLabel((Rectangle){np.x + 20, np.y + 65, 220, 20}, "SIGNALS");*/
/* if(GuiButton((Rectangle){np.x + 20, np.y + 90, 220, 20}, "ADD SIGNAL")){*/
/* sm.addSignalAtNode(&n);*/
/* }*/
/**/
/* int y_midi = 120;*/
/* GuiLabel((Rectangle){np.x + 20, np.y + y_midi, 220, 20}, "MIDI OUT");*/
/**/
/* int i = 0;*/
/* for(auto& mo : n.midi_outs){*/
/* GuiCheckBox((Rectangle){np.x + 20, np.y + y_midi + 20 + i*20.0f, 20, 20}, mo.second.name.c_str(), &mo.second.enabled);*/
/* i++;*/
/* }*/
/**/
/* int y_channel = y_midi + 30 + i*20;*/
/* GuiLabel((Rectangle){np.x + 20, np.y + y_channel, 220, 20}, "CHANNEL");*/
/* GuiToggleGroup((Rectangle){np.x + 20, np.y + y_channel + 30, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_channel);*/
/**/
/* GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 90, 100, 20}, "NOTE");*/
/* float v = n.midi_note;*/
/* GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 90, 20, 20}, midi.midiNotes[(int)round(v)].c_str());*/
/* GuiLabel((Rectangle){np.x + 160, np.y + y_channel + 90, 40, 20}, std::format("{}",n.midi_note).c_str());*/
/* GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 120, 220, 20}, "", "", &v, 0, 127);*/
/* n.midi_note = round(v);*/
/**/
/* GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 150, 100, 20}, "VELOCITY");*/
/* v = n.midi_velocity;*/
/* GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 150, 20, 20}, std::format("{}",n.midi_velocity).c_str());*/
/* GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 180, 220, 20}, "", "", &v, 0, 127);*/
/* n.midi_velocity = round(v);*/
/**/
/* GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 210, 100, 20}, "GATE");*/
/* v = n.midi_gate;*/
/* GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 210, 20, 20}, std::format("{}",(float)n.midi_gate/1000.0f).c_str());*/
/* GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 240, 220, 20}, "", "", &v, 0, 5000);*/
/* n.midi_gate = round(v);*/
/**/
/* //if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel + 40, 140, 20}, "VELOCITY", &n.midi_velocity, 0, 127, n.gui_midi_velocity_edit)) n.gui_midi_velocity_edit = !n.gui_midi_velocity_edit;*/
/* //if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel + 60, 140, 20}, "GATE", &n.midi_gate, 0, 5000, n.gui_midi_gate_edit)) n.gui_midi_gate_edit = !n.gui_midi_gate_edit;*/
/* }*/
/* }*/
/**/
/* for(auto& c : cm.connections){*/
/* if(c.config){*/
/* Vec2D<float> config_handle = c.v2->position - ((c.v2->position - c.v1->position))*0.75f;*/
/* c.config = !GuiWindowBox((Rectangle){config_handle.x + 10, config_handle.y + 10, 200, 300}, "connection");*/
/* GuiToggle((Rectangle){config_handle.x + 10, config_handle.y + 50, 80, 20}, "v1v2", &c.v1_v2);*/
/* GuiToggle((Rectangle){config_handle.x + 100, config_handle.y + 50, 80, 20}, "v2v1", &c.v2_v1);*/
/**/
/* }*/
/* }*/
/**/
/**/
/*}*/