Good working protoype with config nodes and a experimental channel setting ui.
This commit is contained in:
@@ -1,15 +1,76 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "datatypes.h"
|
||||||
|
#include "interactable.h"
|
||||||
#include "vmath.h"
|
#include "vmath.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
inline bool ViButton(Vec2Df mp, float x, float y, float radius, Color color){
|
inline bool ViButton(Vec2Df mp, float x, float y, float radius, Color color){
|
||||||
DrawCircle(x,y,radius, color);
|
DrawCircle(x,y,radius, color);
|
||||||
return (Vector2Distance(mp, (Vector2){x,y}) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT));
|
return (Vector2Distance(mp, (Vector2){x,y}) < 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ViButtonText(Vec2Df mp, Vec2Df position, float radius, Color color, std::string text, float text_size, Color text_color){
|
||||||
|
float offset = MeasureText(text.c_str(), text_size);
|
||||||
|
DrawCircle(position.x, position.y, radius, color);
|
||||||
|
DrawText(text.c_str(), position.x-offset/2.0f, position.y - text_size/2, text_size, text_color);
|
||||||
|
return (Vector2Distance(mp, position) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT));
|
||||||
|
}
|
||||||
|
|
||||||
inline bool ViSegButton(Vec2Df mp, float x, float y, float start_angle, float end_angle, float radius, Color color){
|
inline bool ViSegButton(Vec2Df mp, float x, float y, float start_angle, float end_angle, float radius, Color color){
|
||||||
DrawCircleSector((Vector2){x,y},radius, start_angle, end_angle, 5, color);
|
DrawCircleSector((Vector2){x,y},radius, start_angle, end_angle, 5, color);
|
||||||
return (Vector2Distance(mp, (Vector2){x,y}) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT));
|
return (Vector2Distance(mp, (Vector2){x,y}) < radius && IsMouseButtonPressed(MOUSE_BUTTON_LEFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void DrawCenteredText(std::string text, Vec2Df position, float text_size, Color color){
|
||||||
|
float offset = MeasureText(text.c_str(), text_size);
|
||||||
|
DrawText(text.c_str(), position.x-offset/2.0f, position.y-text_size/2.0f, text_size, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace VISEQ::APP::UI{
|
||||||
|
|
||||||
|
class Button : public BASE::Interactable{
|
||||||
|
public:
|
||||||
|
Button() {}
|
||||||
|
Button(Vec2Df position, Color color) : color(color), position(position) {}
|
||||||
|
Color color = VS_COLOR_YELLOW;
|
||||||
|
Color hover_color = VS_COLOR_SUN;
|
||||||
|
Vec2Df position = {0,0};
|
||||||
|
std::string text = "";
|
||||||
|
Color text_color = VS_COLOR_BROWN;
|
||||||
|
float text_size = 10;
|
||||||
|
virtual void draw() = 0;
|
||||||
|
virtual GRAPH::GraphItemType getType() override {return GRAPH::GraphItemType::VS_BUTTON;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ButtonRound : public Button{
|
||||||
|
public:
|
||||||
|
ButtonRound() {}
|
||||||
|
ButtonRound(Vec2Df position, float radius, Color color) : Button(position, color), radius(radius){}
|
||||||
|
|
||||||
|
std::shared_ptr<APP::State> state = APP::State::get();
|
||||||
|
|
||||||
|
float radius = 0.0f;
|
||||||
|
virtual bool hovering() override {
|
||||||
|
return CheckCollisionPointCircle(SCREEN_MOUSE, position, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pickUp() override {}
|
||||||
|
virtual void pickUp(Vec2Df position) override {}
|
||||||
|
virtual void drag(Vec2Df position) override {}
|
||||||
|
virtual void putDown() override {}
|
||||||
|
|
||||||
|
virtual void draw() override {
|
||||||
|
float offset = MeasureText(text.c_str(), text_size);
|
||||||
|
if(!hovering()) DrawCircle(position.x, position.y, radius, color);
|
||||||
|
else DrawCircle(position.x, position.y, radius, hover_color);
|
||||||
|
if(text != "") DrawText(text.c_str(), position.x-offset/2.0f, position.y - text_size/2, text_size, text_color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -181,7 +181,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
|
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);
|
//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){
|
friend void to_json(json& j, const ConfigNode& N){
|
||||||
|
|||||||
+7
-4
@@ -24,8 +24,8 @@ namespace VISEQ::GRAPH {
|
|||||||
|
|
||||||
bool passable = false;
|
bool passable = false;
|
||||||
|
|
||||||
float radius = 5.0f;
|
float radius = 8.0f;
|
||||||
float orbit = 14.0f;
|
float orbit = 20.0f;
|
||||||
Vec2Df center_position;
|
Vec2Df center_position;
|
||||||
|
|
||||||
GraphItemType getType() override{
|
GraphItemType getType() override{
|
||||||
@@ -47,6 +47,9 @@ namespace VISEQ::GRAPH {
|
|||||||
void setPosition(Vec2Df pos) override {
|
void setPosition(Vec2Df pos) override {
|
||||||
center_position = pos;
|
center_position = pos;
|
||||||
}
|
}
|
||||||
|
void setOrbit(float r) {
|
||||||
|
orbit = r;
|
||||||
|
}
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
|
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
|
||||||
@@ -58,8 +61,8 @@ namespace VISEQ::GRAPH {
|
|||||||
connected = false;
|
connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(partner.expired()) position = center_position - ((center_position - SCREEN_MOUSE)).norm() * (radius + orbit);
|
if(partner.expired()) position = center_position.orbitAlongVector(SCREEN_MOUSE, orbit);
|
||||||
if(!partner.expired()) position = center_position - ((center_position - partner.lock()->position)).norm() * (radius + orbit);
|
if(!partner.expired()) position = center_position .orbitAlongVector(partner.lock()->position, orbit);
|
||||||
if(new_partner) {
|
if(new_partner) {
|
||||||
new_partner = false;
|
new_partner = false;
|
||||||
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
state->pushEvent({getPtr(), APP::Interaction::CONNECT});
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
|
|
||||||
|
|
||||||
namespace VISEQ::GRAPH{
|
namespace VISEQ::GRAPH{
|
||||||
enum GraphItemType {NODE, EDGE, CONNECTOR, CANVAS, HANDLE};
|
enum GraphItemType {NODE, EDGE, CONNECTOR, CANVAS, HANDLE, VS_BUTTON};
|
||||||
enum NodeType {OSCNODE, MIDINODE, CONFIGNODE};
|
enum NodeType {OSCNODE, MIDINODE, CONFIGNODE};
|
||||||
enum EdgeType {MIDIEDGE, CONFIGEDGE};
|
enum EdgeType {MIDIEDGE, CONFIGEDGE};
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-7
@@ -1,13 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "button.h"
|
||||||
#include "config-node.h"
|
#include "config-node.h"
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "edge.h"
|
#include "edge.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
#include "state.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <random>
|
||||||
#define RADIUS 14.0f
|
|
||||||
|
|
||||||
namespace VISEQ::APP::UI{
|
namespace VISEQ::APP::UI{
|
||||||
class AppUI;
|
class AppUI;
|
||||||
@@ -26,6 +28,8 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
MIDI::MidiPolyPressure midiPolyPressure;
|
MIDI::MidiPolyPressure midiPolyPressure;
|
||||||
MIDI::MidiPC midiPC;
|
MIDI::MidiPC midiPC;
|
||||||
|
|
||||||
|
std::vector<APP::UI::ButtonRound> channelButtons;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct NodeMidiOut{
|
struct NodeMidiOut{
|
||||||
@@ -34,8 +38,8 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
MidiNode() {std::cout << "MidiNode Constructor std" << std::endl;}
|
MidiNode() {init();}
|
||||||
MidiNode(Vec2Df position) : Node(position) {}
|
MidiNode(Vec2Df position) : Node(position) {init();}
|
||||||
|
|
||||||
NodeType nodeType = NodeType::MIDINODE;
|
NodeType nodeType = NodeType::MIDINODE;
|
||||||
|
|
||||||
@@ -58,6 +62,14 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
float time = 0;
|
float time = 0;
|
||||||
float last = 0;
|
float last = 0;
|
||||||
|
|
||||||
|
void init(){
|
||||||
|
channelButtons.clear();
|
||||||
|
for(int i = 0; i < 16; ++i){
|
||||||
|
channelButtons.emplace_back(position, 4.0f, VS_COLOR_YELLOW);
|
||||||
|
channelButtons.back().hover_color = VS_COLOR_PINK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<MidiNode> getPtr(){
|
std::shared_ptr<MidiNode> getPtr(){
|
||||||
return std::static_pointer_cast<MidiNode>(shared_from_this());
|
return std::static_pointer_cast<MidiNode>(shared_from_this());
|
||||||
}
|
}
|
||||||
@@ -203,6 +215,12 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
|
|
||||||
void draw(Vec2Df mouse, Camera2D cam) override {
|
void draw(Vec2Df mouse, Camera2D cam) override {
|
||||||
Node::draw();
|
Node::draw();
|
||||||
|
if(hovering()) {
|
||||||
|
radius += radius < 25 ? 2 : 0;
|
||||||
|
} else {
|
||||||
|
radius -= radius > 15 ? 2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(hovering() || selected) interact();
|
if(hovering() || selected) interact();
|
||||||
|
|
||||||
last = time;
|
last = time;
|
||||||
@@ -214,8 +232,8 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
fade -= (time - last)*1000.0f;
|
fade -= (time - last)*1000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawRing(position, radius, radius+4, 0, 360, 24, (Color){60, 60, 60, 255});
|
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});
|
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});
|
DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255});
|
||||||
|
|
||||||
float midi_gate_map = round((255.f / getNotes().gate) * fade);
|
float midi_gate_map = round((255.f / getNotes().gate) * fade);
|
||||||
@@ -242,6 +260,24 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
|
|
||||||
if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255});
|
if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255});
|
||||||
|
|
||||||
|
if(hovering()){
|
||||||
|
for(int i = 0; i < 16; ++i){
|
||||||
|
channelButtons.at(i).position = position.orbitAtAngle(21.0, DEG2RAD * (360.0f/16.0f)*i);
|
||||||
|
Color col = VS_COLOR_YELLOW;
|
||||||
|
if(mode == 0 && midiNote.channel == i) col = VS_COLOR_PINK;
|
||||||
|
if(mode == 1 && midiCC.channel == i) col = VS_COLOR_PINK;
|
||||||
|
if(mode == 2 && midiPitchBend.channel == i) col = VS_COLOR_PINK;
|
||||||
|
channelButtons.at(i).color = col;
|
||||||
|
channelButtons.at(i).draw();
|
||||||
|
if(channelButtons.at(i).hovering()) DrawCenteredText(std::format("{}", i+1), position + (Vec2Df){0,10.0f}, 8, VS_COLOR_WHITE);
|
||||||
|
if(channelButtons.at(i).clicked()) {
|
||||||
|
if(mode == 0) midiNote.channel = i;
|
||||||
|
if(mode == 1) midiCC.channel = i;
|
||||||
|
if(mode == 2) midiPitchBend.channel = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(KEYS_DOWN.alt){
|
if(KEYS_DOWN.alt){
|
||||||
float value = 0;
|
float value = 0;
|
||||||
int offset_gate = 0;
|
int offset_gate = 0;
|
||||||
@@ -280,7 +316,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
|
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);
|
//DrawText(std::format("{}", id).c_str(), position.x + 20.0f, position.y + 20.0f, 10, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend void to_json(json& j, const MidiNode& N){
|
friend void to_json(json& j, const MidiNode& N){
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
for(auto c : connectors){
|
for(auto c : connectors){
|
||||||
if(c->partner.expired()) free_connectors++;
|
if(c->partner.expired()) free_connectors++;
|
||||||
c->setPosition(position);
|
c->setPosition(position);
|
||||||
|
c->setOrbit(radius + 8.0f);
|
||||||
c->update();
|
c->update();
|
||||||
}
|
}
|
||||||
if(free_connectors == 0) addConnector();
|
if(free_connectors == 0) addConnector();
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ namespace VISEQ::VMATH{
|
|||||||
return Vec2D<T>{x,y} - (Vec2D<T>{x,y} - v)*0.5f;
|
return Vec2D<T>{x,y} - (Vec2D<T>{x,y} - v)*0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2D orbitAlongVector(Vec2D d, float r){
|
||||||
|
return Vec2D<T>{x,y} - ((Vec2D<T>{x,y} - d)).norm() * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2D orbitAtAngle(float r, float angle){
|
||||||
|
return {x + sin(angle) * r, y + cos(angle) * r};
|
||||||
|
}
|
||||||
|
|
||||||
Vec2D& operator=(const Vec2D& vec){
|
Vec2D& operator=(const Vec2D& vec){
|
||||||
if (this == &vec){
|
if (this == &vec){
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
Reference in New Issue
Block a user