Vector UI on its way!
This commit is contained in:
+4
-4
@@ -94,10 +94,10 @@ namespace VISEQ::MIDI{
|
|||||||
|
|
||||||
inline MidiNote operator+(const MidiNote left, const MidiNote right){
|
inline MidiNote operator+(const MidiNote left, const MidiNote right){
|
||||||
MidiNote added;
|
MidiNote added;
|
||||||
added.note = left.note + right.note;
|
added.note = std::clamp(left.note + right.note, 0, 127);
|
||||||
added.channel = left.channel + right.channel;
|
added.channel = std::clamp(left.channel + right.channel, 0, 15);
|
||||||
added.gate = left.gate + right.gate;
|
added.gate = std::max(left.gate + right.gate, 0);
|
||||||
added.velocity = left.velocity + right.velocity;
|
added.velocity = std::clamp(left.velocity + right.velocity, 0, 127);
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <execution>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace VISEQ::INTERACTION{
|
namespace VISEQ::INTERACTION{
|
||||||
@@ -82,11 +81,11 @@ namespace VISEQ::INTERACTION{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
if(!KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
||||||
state->node_mode = (state->node_mode + 1) % 6;
|
state->node_mode = (state->node_mode + 1) % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
if(KEYS_DOWN.shift && IsKeyPressed(KEY_TAB)) {
|
||||||
state->node_mode -= state->node_mode > 0 ? 1 : -5;
|
state->node_mode -= state->node_mode > 0 ? 1 : -6;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+79
-33
@@ -1,17 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "button.h"
|
|
||||||
#include "config-node.h"
|
#include "config-node.h"
|
||||||
#include "control-node.h"
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "edge.h"
|
#include "edge.h"
|
||||||
|
#include "node-handle.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
namespace VISEQ::APP::UI{
|
namespace VISEQ::APP::UI{
|
||||||
class AppUI;
|
class AppUI;
|
||||||
@@ -29,8 +27,13 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
MIDI::MidiPitchBend midiPitchBend;
|
MIDI::MidiPitchBend midiPitchBend;
|
||||||
MIDI::MidiAftertouch midiAftertouch;
|
MIDI::MidiAftertouch midiAftertouch;
|
||||||
MIDI::MidiPolyPressure midiPolyPressure;
|
MIDI::MidiPolyPressure midiPolyPressure;
|
||||||
|
|
||||||
std::vector<APP::UI::ButtonRound> channelButtons;
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiNoteHandles;
|
||||||
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiCCHandles;
|
||||||
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiPCHandles;
|
||||||
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiPitchBendHandles;
|
||||||
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiAftertouchHandles;
|
||||||
|
std::vector<std::shared_ptr<NodeHandle<int>>> midiPolyPressureHandles;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -67,11 +70,29 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
float last = 0;
|
float last = 0;
|
||||||
|
|
||||||
void init(){
|
void init(){
|
||||||
channelButtons.clear();
|
midiNoteHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiNote.note, position, VS_COLOR_GREEN, "NOTE"));
|
||||||
for(int i = 0; i < 16; ++i){
|
midiNoteHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiNote.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
channelButtons.emplace_back(position, 4.0f, VS_COLOR_YELLOW);
|
midiNoteHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiNote.gate, position, VS_COLOR_RED, "GATE", 0, 30000, 40, 300));
|
||||||
channelButtons.back().hover_color = VS_COLOR_PINK;
|
midiNoteHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiNote.velocity, position, VS_COLOR_PURPLE, "VELOCITY"));
|
||||||
}
|
|
||||||
|
|
||||||
|
midiCCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiCC.control, position, VS_COLOR_SUN, "CONTROL"));
|
||||||
|
midiCCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiCC.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
|
midiCCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiCC.value, position, VS_COLOR_GREEN, "VALUE"));
|
||||||
|
|
||||||
|
midiPCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPC.program, position, VS_COLOR_SUN, "PROGRAM"));
|
||||||
|
midiPCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPC.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
|
midiPCHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPC.value, position, VS_COLOR_GREEN, "VALUE"));
|
||||||
|
|
||||||
|
midiPitchBendHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPitchBend.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
|
midiPitchBendHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPitchBend.value, position, VS_COLOR_GREEN, "VALUE", -8192, 8192, 40, 300));
|
||||||
|
|
||||||
|
midiAftertouchHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiAftertouch.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
|
midiAftertouchHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiAftertouch.value, position, VS_COLOR_GREEN, "VALUE"));
|
||||||
|
|
||||||
|
midiPolyPressureHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.channel, position, VS_COLOR_PINK, "CHANNEL", 0, 15, 40, 150));
|
||||||
|
midiPolyPressureHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.value, position, VS_COLOR_GREEN, "VALUE"));
|
||||||
|
midiPolyPressureHandles.emplace_back(std::make_shared<NodeHandle<int>>(midiPolyPressure.note, position, VS_COLOR_SUN, "NOTE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MidiNode> getPtr(){
|
std::shared_ptr<MidiNode> getPtr(){
|
||||||
@@ -156,6 +177,24 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
void update() override {
|
void update() override {
|
||||||
Node::update();
|
Node::update();
|
||||||
mode = state->node_mode;
|
mode = state->node_mode;
|
||||||
|
for(auto mh : midiNoteHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
|
for(auto mh : midiCCHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
|
for(auto mh : midiPCHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
|
for(auto mh : midiPitchBendHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
|
for(auto mh : midiAftertouchHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
|
for(auto mh : midiPolyPressureHandles){
|
||||||
|
mh->update(position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void modMidiNote(int incr){
|
void modMidiNote(int incr){
|
||||||
@@ -263,11 +302,36 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
|
|
||||||
void draw(Vec2Df mouse, Camera2D cam) override {
|
void draw(Vec2Df mouse, Camera2D cam) override {
|
||||||
Node::draw();
|
Node::draw();
|
||||||
/*if(hovering()) {*/
|
for(auto mh : midiNoteHandles){
|
||||||
/* radius += radius < hover_radius ? 2 : 0;*/
|
if(mode == 0) mh->unlock();
|
||||||
/*} else {*/
|
else mh->lock();
|
||||||
/* radius -= radius > node_radius ? 2 : 0;*/
|
mh->draw();
|
||||||
/*}*/
|
}
|
||||||
|
for(auto mh : midiCCHandles){
|
||||||
|
if(mode == 1) mh->unlock();
|
||||||
|
else mh->lock();
|
||||||
|
mh->draw();
|
||||||
|
}
|
||||||
|
for(auto mh : midiPCHandles){
|
||||||
|
if(mode == 2) mh->unlock();
|
||||||
|
else mh->lock();
|
||||||
|
mh->draw();
|
||||||
|
}
|
||||||
|
for(auto mh : midiPitchBendHandles){
|
||||||
|
if(mode == 3) mh->unlock();
|
||||||
|
else mh->lock();
|
||||||
|
mh->draw();
|
||||||
|
}
|
||||||
|
for(auto mh : midiAftertouchHandles){
|
||||||
|
if(mode == 4) mh->unlock();
|
||||||
|
else mh->lock();
|
||||||
|
mh->draw();
|
||||||
|
}
|
||||||
|
for(auto mh : midiPolyPressureHandles){
|
||||||
|
if(mode == 5) mh->unlock();
|
||||||
|
else mh->lock();
|
||||||
|
mh->draw();
|
||||||
|
}
|
||||||
|
|
||||||
if(hovering() || selected) interact();
|
if(hovering() || selected) interact();
|
||||||
|
|
||||||
@@ -308,24 +372,6 @@ 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(radius - 6.0f, 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;
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "datatypes.h"
|
||||||
|
#include "draggable.h"
|
||||||
|
#include "graph-item.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace VISEQ::GRAPH::NODES{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class NodeHandle : public BASE::Draggable, public GraphItem, public std::enable_shared_from_this<NodeHandle<T>>{
|
||||||
|
public:
|
||||||
|
NodeHandle() {}
|
||||||
|
NodeHandle(T &_assignedValue, Vec2Df parentPos, Color _col, std::string name) : assignedValueRef(_assignedValue), parentPosition(parentPos), col(_col), name(name) {init();}
|
||||||
|
NodeHandle(T &_assignedValue, Vec2Df parentPos, Color _col, std::string name, float min, float max, float minDist, float maxDist) : assignedValueRef(_assignedValue), parentPosition(parentPos), col(_col), name(name), minValue(min), maxValue(max), minDistance(minDist), maxDistance(maxDist) {init();}
|
||||||
|
|
||||||
|
virtual GRAPH::GraphItemType getType() override {
|
||||||
|
return GraphItemType::HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NodeHandle<T>> getPtr(){
|
||||||
|
return this->shared_from_this();
|
||||||
|
}
|
||||||
|
|
||||||
|
T &assignedValueRef;
|
||||||
|
Vec2Df parentPosition = {0,0};
|
||||||
|
Color col;
|
||||||
|
std::string name = "";
|
||||||
|
|
||||||
|
float minValue = 0;
|
||||||
|
float maxValue = 127;
|
||||||
|
float minDistance = 40;
|
||||||
|
float maxDistance = 40 + 2*127;
|
||||||
|
bool stopAtMax = true;
|
||||||
|
|
||||||
|
float radius = 10.0f;
|
||||||
|
float orbit = 0.0f;
|
||||||
|
|
||||||
|
Vec2Df minP;
|
||||||
|
Vec2Df maxP;
|
||||||
|
|
||||||
|
bool locked = true;
|
||||||
|
bool visible = false;
|
||||||
|
|
||||||
|
void init(){
|
||||||
|
position = parentPosition.orbitAtAngle(minDistance, DEG2RAD * GetRandomValue(0, 360)) - parentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assignValue(T &value){
|
||||||
|
assignedValueRef = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance(){
|
||||||
|
return (parentPosition + position).dist(parentPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void drag(Vec2Df mouse_pos) override {
|
||||||
|
if(KEYS_DOWN.shift) {
|
||||||
|
orbit = (parentPosition + position).dist(parentPosition);
|
||||||
|
position = parentPosition.orbitAlongVector(SCREEN_MOUSE, orbit) - parentPosition;
|
||||||
|
} else {
|
||||||
|
orbit = parentPosition.dist(SCREEN_MOUSE);
|
||||||
|
position = parentPosition.orbitAlongVector(maxP, orbit) - parentPosition;
|
||||||
|
}
|
||||||
|
if(distance() >= maxDistance) position = parentPosition.orbitAlongVector(maxP, maxDistance) - parentPosition;
|
||||||
|
if(distance() <= minDistance) position = parentPosition.orbitAlongVector(maxP, minDistance) - parentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock(){
|
||||||
|
visible = false;
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock(){
|
||||||
|
visible = true;
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assignValue(T &value, float min, float max, float minDistance, float maxDistance){
|
||||||
|
assignedValueRef = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateAssignedValue(){
|
||||||
|
assignedValueRef = (T)Remap((float)(parentPosition + position).dist(parentPosition), minDistance, maxDistance, minValue, maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool hovering() override {
|
||||||
|
return CheckCollisionPointCircle(SCREEN_MOUSE, position + parentPosition, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(Vec2Df pos) override {
|
||||||
|
if(!locked && visible){
|
||||||
|
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
|
||||||
|
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
|
||||||
|
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
|
||||||
|
}
|
||||||
|
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
|
||||||
|
|
||||||
|
parentPosition = pos;
|
||||||
|
if(!locked && visible) updateAssignedValue();
|
||||||
|
|
||||||
|
minP = parentPosition.orbitAlongVector((parentPosition + position), minDistance);
|
||||||
|
maxP = parentPosition.orbitAlongVector((parentPosition + position), maxDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void draw() override {
|
||||||
|
if(!locked && visible){
|
||||||
|
Color dcol = ColorBrightness(col, -0.5f);
|
||||||
|
|
||||||
|
DrawLineV(minP, maxP, dcol);
|
||||||
|
DrawLineV(parentPosition, minP, VS_COLOR_LIGHTGREY);
|
||||||
|
DrawCircleV(minP, 3.0f, dcol);
|
||||||
|
DrawCircleV(maxP, 3.0f, dcol);
|
||||||
|
DrawCircleV(position + parentPosition, radius, hovering() ? col : dcol);
|
||||||
|
Vec2Df text_position = maxP.center(minP) + (minP - maxP).norm().orth() * 6.0f;
|
||||||
|
float rotation = Vector2Angle((Vector2){1,0}, (minP - maxP)) * RAD2DEG;
|
||||||
|
DrawTextPro(GetFontDefault(), name.c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, hovering() ? col : dcol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool select() override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user