distance to closest node displayed, timing problems with midi notes being sent 1 to 3ms too early, or too late
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
## style: dark
|
||||
|
||||
Classical dark style with an extra high-def colour touch! Elegant and professional, perfect for the expensive tools!
|
||||
|
||||

|
||||
|
||||
## style: provided files
|
||||
|
||||
Several options are provided to add the style to a `raygui` application, choose the one that better fits the project.
|
||||
|
||||
| file name | description |
|
||||
| :-------- | :---------- |
|
||||
| `style_dark.rgs` | Binary style file (raygui 4.0), font data compressed (recs, glyphs) |
|
||||
| `style_dark.txt.rgs` | Text style file, no font data, requires external font provided |
|
||||
| `style_dark.old.rgs` | Binary style file (raygui 3.x), font data uncompressed (recs, glyphs) |
|
||||
| `style_dark.h` | Embeddable style as code file, self-contained, includes font data |
|
||||
| `style_dark.png` | Style table image, contains `rGSf` chunk with binary `rgs` file data |
|
||||
|
||||
## screenshot
|
||||
|
||||

|
||||
|
||||
## about font
|
||||
|
||||
"Pixel Operator" font by de Jayvee Enaguas.
|
||||
|
||||
CC0 1.0 Universal, downloaded from dafont.com: [pixel-operator](https://www.dafont.com/pixel-operator.font)
|
||||
@@ -7,7 +7,7 @@
|
||||
// more info and bugs-report: github.com/raysan5/raygui //
|
||||
// feedback and support: ray[at]raylibtech.com //
|
||||
// //
|
||||
// Copyright (c) 2020-2023 raylib technologies (@raylibtech) //
|
||||
// Copyright (c) 2020-2024 raylib technologies (@raylibtech) //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -15,29 +15,29 @@
|
||||
|
||||
// Custom style name: Dark
|
||||
static const GuiStyleProp darkStyleProps[DARK_STYLE_PROPS_COUNT] = {
|
||||
{ 0, 0, (long)0x878787ff }, // DEFAULT_BORDER_COLOR_NORMAL
|
||||
{ 0, 1, (long)0x2c2c2cff }, // DEFAULT_BASE_COLOR_NORMAL
|
||||
{ 0, 2, (long)0xc3c3c3ff }, // DEFAULT_TEXT_COLOR_NORMAL
|
||||
{ 0, 3, (long)0xe1e1e1ff }, // DEFAULT_BORDER_COLOR_FOCUSED
|
||||
{ 0, 4, (long)0x848484ff }, // DEFAULT_BASE_COLOR_FOCUSED
|
||||
{ 0, 5, (long)0x181818ff }, // DEFAULT_TEXT_COLOR_FOCUSED
|
||||
{ 0, 6, (long)0x000000ff }, // DEFAULT_BORDER_COLOR_PRESSED
|
||||
{ 0, 7, (long)0xefefefff }, // DEFAULT_BASE_COLOR_PRESSED
|
||||
{ 0, 8, (long)0x202020ff }, // DEFAULT_TEXT_COLOR_PRESSED
|
||||
{ 0, 9, (long)0x6a6a6aff }, // DEFAULT_BORDER_COLOR_DISABLED
|
||||
{ 0, 10, (long)0x818181ff }, // DEFAULT_BASE_COLOR_DISABLED
|
||||
{ 0, 11, (long)0x606060ff }, // DEFAULT_TEXT_COLOR_DISABLED
|
||||
{ 0, 16, (long)0x00000010 }, // DEFAULT_TEXT_SIZE
|
||||
{ 0, 17, (long)0x00000000 }, // DEFAULT_TEXT_SPACING
|
||||
{ 0, 18, (long)0x9d9d9dff }, // DEFAULT_LINE_COLOR
|
||||
{ 0, 19, (long)0x3c3c3cff }, // DEFAULT_BACKGROUND_COLOR
|
||||
{ 0, 20, (long)0x00000018 }, // DEFAULT_TEXT_LINE_SPACING
|
||||
{ 1, 5, (long)0xf7f7f7ff }, // LABEL_TEXT_COLOR_FOCUSED
|
||||
{ 1, 8, (long)0x898989ff }, // LABEL_TEXT_COLOR_PRESSED
|
||||
{ 4, 5, (long)0xb0b0b0ff }, // SLIDER_TEXT_COLOR_FOCUSED
|
||||
{ 5, 5, (long)0x848484ff }, // PROGRESSBAR_TEXT_COLOR_FOCUSED
|
||||
{ 9, 5, (long)0xf5f5f5ff }, // TEXTBOX_TEXT_COLOR_FOCUSED
|
||||
{ 10, 5, (long)0xf6f6f6ff }, // VALUEBOX_TEXT_COLOR_FOCUSED
|
||||
{ 0, 0, 0x878787ff }, // DEFAULT_BORDER_COLOR_NORMAL
|
||||
{ 0, 1, 0x2c2c2cff }, // DEFAULT_BASE_COLOR_NORMAL
|
||||
{ 0, 2, 0xc3c3c3ff }, // DEFAULT_TEXT_COLOR_NORMAL
|
||||
{ 0, 3, 0xe1e1e1ff }, // DEFAULT_BORDER_COLOR_FOCUSED
|
||||
{ 0, 4, 0x848484ff }, // DEFAULT_BASE_COLOR_FOCUSED
|
||||
{ 0, 5, 0x181818ff }, // DEFAULT_TEXT_COLOR_FOCUSED
|
||||
{ 0, 6, 0x000000ff }, // DEFAULT_BORDER_COLOR_PRESSED
|
||||
{ 0, 7, 0xefefefff }, // DEFAULT_BASE_COLOR_PRESSED
|
||||
{ 0, 8, 0x202020ff }, // DEFAULT_TEXT_COLOR_PRESSED
|
||||
{ 0, 9, 0x6a6a6aff }, // DEFAULT_BORDER_COLOR_DISABLED
|
||||
{ 0, 10, 0x818181ff }, // DEFAULT_BASE_COLOR_DISABLED
|
||||
{ 0, 11, 0x606060ff }, // DEFAULT_TEXT_COLOR_DISABLED
|
||||
{ 0, 16, 0x00000010 }, // DEFAULT_TEXT_SIZE
|
||||
{ 0, 17, 0x00000000 }, // DEFAULT_TEXT_SPACING
|
||||
{ 0, 18, 0x9d9d9dff }, // DEFAULT_LINE_COLOR
|
||||
{ 0, 19, 0x3c3c3cff }, // DEFAULT_BACKGROUND_COLOR
|
||||
{ 0, 20, 0x00000018 }, // DEFAULT_TEXT_LINE_SPACING
|
||||
{ 1, 5, 0xf7f7f7ff }, // LABEL_TEXT_COLOR_FOCUSED
|
||||
{ 1, 8, 0x898989ff }, // LABEL_TEXT_COLOR_PRESSED
|
||||
{ 4, 5, 0xb0b0b0ff }, // SLIDER_TEXT_COLOR_FOCUSED
|
||||
{ 5, 5, 0x848484ff }, // PROGRESSBAR_TEXT_COLOR_FOCUSED
|
||||
{ 9, 5, 0xf5f5f5ff }, // TEXTBOX_TEXT_COLOR_FOCUSED
|
||||
{ 10, 5, 0xf6f6f6ff }, // VALUEBOX_TEXT_COLOR_FOCUSED
|
||||
};
|
||||
|
||||
// WARNING: This style uses a custom font: "PixelOperator.ttf" (size: 16, spacing: 0)
|
||||
|
||||
@@ -38,6 +38,7 @@ class Vec2D{
|
||||
T x = 0;
|
||||
T y = 0;
|
||||
T dist(Vec2D* v) { return sqrt(pow((v->x - x), 2) + pow((v->y - y), 2));};
|
||||
T dist(Vec2D v) { return sqrt(pow((v.x - x), 2) + pow((v.y - y), 2));};
|
||||
|
||||
T length() { return (T)sqrt(pow(x, 2) + pow(y, 2));};
|
||||
|
||||
|
||||
+2
-2
@@ -66,8 +66,8 @@ int main(){
|
||||
|
||||
app.settings.speed = (app.settings.grid * 8.0f) * (app.settings.bpm / 120.f);
|
||||
|
||||
app.settings.width = monitor_width;
|
||||
app.settings.height = monitor_height;
|
||||
app.settings.width = monitor_width - 300;
|
||||
app.settings.height = monitor_height - 300;
|
||||
|
||||
SetTargetFPS(app.settings.fps);
|
||||
|
||||
|
||||
+2
-2
@@ -76,7 +76,7 @@ class Midi {
|
||||
}
|
||||
|
||||
void note(int midi_out, int channel, int note, int velocity, int gate){
|
||||
if(!midi_outs.empty()){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::note_on(channel, note, velocity));
|
||||
notes.emplace_back(midi_out, channel, note, velocity, GetTime(), gate);
|
||||
@@ -88,7 +88,7 @@ class Midi {
|
||||
float time = GetTime();
|
||||
for(auto &n : notes){
|
||||
if(time - n.start >= (float)n.gate / 1000.0f){
|
||||
midi_outs[n.midi_out]->send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
||||
if(midi_outs.contains(n.midi_out) && midi_outs[n.midi_out]->is_port_open()) midi_outs[n.midi_out]->send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
||||
n.erase = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ class Movable{
|
||||
Vec2D<float> direction;
|
||||
|
||||
virtual void update(int fps) {};
|
||||
virtual void update(double frametime) {};
|
||||
virtual void update() {};
|
||||
virtual void draw(Vec2D<float> *mouse, Camera2D *cam) {};
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "node.h"
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
@@ -57,7 +60,20 @@ class NodeManager{
|
||||
}
|
||||
|
||||
void drawNodes(Vec2D<float> *mouse_pos, Camera2D *camera){
|
||||
auto flat_nodes = nodes | std::ranges::views::values | std::ranges::to<std::vector<Node>>();
|
||||
for(auto& n : nodes | std::ranges::views::values ){
|
||||
if(n.dragging){
|
||||
std::sort(flat_nodes.begin(), flat_nodes.end(), [n](Node na, Node nb){ return na.position.dist(n.position) < nb.position.dist(n.position);});
|
||||
float d = flat_nodes.at(1).position.dist(n.position);
|
||||
if(d > 0 && d < 240) {
|
||||
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
|
||||
Vec2D<float> middle_handle = flat_nodes.at(1).position + (n.position - flat_nodes.at(1).position) * ((d - text_length.x)*0.5f)/d;
|
||||
Vec2D<float> text_position = middle_handle + (flat_nodes.at(1).position - n.position).norm().orth() * 12.0f;
|
||||
float rotation = Vector2Angle((Vector2){1,0}, (n.position - flat_nodes.at(1).position)) * RAD2DEG;
|
||||
DrawTextPro(GetFontDefault(), std::format("{:.1f}",d).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
DrawLineV(n.position, flat_nodes.at(1).position, VS_COLOR_PINK);
|
||||
}
|
||||
}
|
||||
n.draw(mouse_pos, camera);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-6
@@ -71,22 +71,24 @@ class SignalManager{
|
||||
}
|
||||
|
||||
void updateSignals(){
|
||||
auto last = std::chrono::steady_clock::now();
|
||||
auto last = std::chrono::high_resolution_clock::now();
|
||||
while(loop){
|
||||
std::chrono::duration<double, std::micro> diff = std::chrono::steady_clock::now() - last;
|
||||
if(diff.count() > 500){
|
||||
std::chrono::duration<double, std::micro> diff = std::chrono::high_resolution_clock::now() - last;
|
||||
if((int)diff.count() >= 250){
|
||||
mutex->lock();
|
||||
if(play){
|
||||
for(auto& s : signals){
|
||||
s.direction = (nm->nodes[s.next].position - s.position).norm();
|
||||
s.update(diff.count());
|
||||
if(s.position.dist(&nm->nodes[s.next].position) < 1.0f) {
|
||||
if(s.position.dist(&nm->nodes[s.next].position) < 0.6f) {
|
||||
int n = cm->next(s.next, s.last);
|
||||
nm->nodes[s.next].trigger();
|
||||
|
||||
if(n != s.next && n != -1) {
|
||||
for(auto &m : nm->nodes[s.next].midi_outs){
|
||||
if(m.second.enabled) midi.note(m.second.i, nm->nodes[s.next].midi_channel, nm->nodes[s.next].midi_note, nm->nodes[s.next].midi_velocity, nm->nodes[s.next].midi_gate);
|
||||
if(m.second.enabled) {
|
||||
midi.note(m.second.i, nm->nodes[s.next].midi_channel, nm->nodes[s.next].midi_note, nm->nodes[s.next].midi_velocity, nm->nodes[s.next].midi_gate);
|
||||
}
|
||||
}
|
||||
s.last = s.next;
|
||||
s.next = n;
|
||||
@@ -96,14 +98,16 @@ class SignalManager{
|
||||
}
|
||||
midi.update();
|
||||
mutex->unlock();
|
||||
last = std::chrono::steady_clock::now();
|
||||
last = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSignals(Vec2D<float> *mouse_pos, Camera2D *camera){
|
||||
for(auto& s : signals){
|
||||
mutex->lock();
|
||||
s.draw(mouse_pos, camera);
|
||||
mutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class Signal : public Movable{
|
||||
|
||||
Color color;
|
||||
|
||||
void update(int t_delta){
|
||||
void update(double t_delta){
|
||||
// 120px / 16th = 1920px / whole note
|
||||
// whole note = 2s at 120bpm
|
||||
// 960px / s
|
||||
|
||||
+3
-1
@@ -53,6 +53,8 @@ class AppState{
|
||||
for(auto &n : copy_nodes_ids){
|
||||
int old_id = n;
|
||||
int new_id = nm.copyNode(n, position + nm.nodes[n].drag_offset);
|
||||
nm.nodes[new_id].copied = false;
|
||||
nm.nodes[new_id].selected = true;
|
||||
|
||||
for(auto &c : copy_connections){
|
||||
if(c.v1 == old_id) c.v1 = new_id;
|
||||
@@ -121,10 +123,10 @@ class AppState{
|
||||
void draw(Vec2D<float> *mouse_pos, Camera2D *camera){
|
||||
mutex.lock();
|
||||
updateMidiPorts();
|
||||
mutex.unlock();
|
||||
nm.drawNodes(mouse_pos, camera);
|
||||
cm.drawConnections(mouse_pos, camera);
|
||||
sm.drawSignals(mouse_pos, camera);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void drawUI(Vec2D<float> *mouse_pos, Camera2D *camera){
|
||||
|
||||
@@ -27,12 +27,13 @@ class AppUI{
|
||||
|
||||
void drawSideBar(){
|
||||
|
||||
GuiWindowBox((Rectangle){0,0,280,(float)settings->height}, "config");
|
||||
GuiPanel((Rectangle){-1,-30,280,(float)settings->height + 31}, "");
|
||||
{
|
||||
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_controls = 20;
|
||||
//GuiSetStyle(BUTTON, STATE_FOCUSED, 0xFF0000FF);
|
||||
if(GuiButton((Rectangle){20, (float)s_controls, 80, 30}, "PLAY")) sm->play ? sm->pause() : sm->start();
|
||||
if(GuiButton((Rectangle){120, (float)s_controls, 60, 30}, "STOP")) sm->stop();
|
||||
if(GuiButton((Rectangle){200, (float)s_controls, 60, 30}, "RESET")) sm->reset();
|
||||
|
||||
const int s_bpm = s_controls + 35;
|
||||
GuiLabel((Rectangle){20, (float)s_bpm, 120, 20}, "TIMING");
|
||||
@@ -83,7 +84,7 @@ class AppUI{
|
||||
if(GuiButton((Rectangle){20, (float)s_nodes + 60, 240, 20}, "ADD RANDOM NODE")){
|
||||
nm->addNode(200.0f, 200.0f);
|
||||
}
|
||||
|
||||
DrawText(std::format("{}", nm->nodes.size()).c_str(), 20, settings->height - 70, 15, VS_COLOR_WHITE);
|
||||
DrawFPS(20, settings->height - 30);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user