v0.9.5 beta — full feature build ready for distribution
Core additions since initial commit: - Platform-split MIDI (midi_linux.c / midi_windows.c) - Patch system: save/load/scan, subdirectory navigation, favourites - Config system: last MIDI device and CC mappings persisted to disk - Custom embedded pixel font and sprite sheet (no loose asset files at runtime) - Window icon embedded at runtime (SetWindowIcon) and in Windows .exe (windres) - chdirToExeDir() in platform.c so double-click launch finds patches/ correctly - About screen accessible from Master panel UI polish: - TITLE_BAR_H constant (20 px) — sprite buttons now fit inside title bars - All title bar text, button overlay text, and close/active labels vertically centred - Full-screen dim overlay computed from camera transform (no more partial coverage) - Patch browser: folder navigation, breadcrumb title, 256-slot limit lifted Build: - Makefile auto-discovers sources; embeds sprites/font/icon via xxd rules - Windows cross-compile: make PLATFORM=windows (mingw-w64 + windres) - windows.h isolated in platform.c to avoid Rectangle/CloseWindow conflicts with raylib.h - WIN_RES uses lazy = assignment so OBJ_DIR expands correctly for windres output path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
110
include/ui.h
Normal file
110
include/ui.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef UI_H
|
||||
#define UI_H
|
||||
|
||||
#include "raylib.h"
|
||||
#include "synth.h"
|
||||
#include "midi.h"
|
||||
#include "patch.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
float *valuePtr;
|
||||
float min;
|
||||
float max;
|
||||
} UIControlEntry;
|
||||
|
||||
// Sprite indices
|
||||
typedef enum {
|
||||
SPRITE_WAVE_SINE = 0,
|
||||
SPRITE_WAVE_TRIANGLE,
|
||||
SPRITE_WAVE_SAW,
|
||||
SPRITE_WAVE_RAMP,
|
||||
SPRITE_WAVE_PULSE,
|
||||
SPRITE_WAVE_NOISE,
|
||||
SPRITE_BTN_RED,
|
||||
SPRITE_BTN_GREEN,
|
||||
SPRITE_SLIDER,
|
||||
SPRITE_KNOB
|
||||
} SpriteIndex;
|
||||
|
||||
// UI state that needs to persist between frames
|
||||
typedef struct {
|
||||
Texture2D sprites;
|
||||
Font font;
|
||||
MidiState *midi;
|
||||
Camera2D *camera;
|
||||
// About menu state
|
||||
int aboutMenuOpen;
|
||||
|
||||
// MIDI menu state
|
||||
int midiMenuOpen;
|
||||
int midiMenuSelected; // -1 if none
|
||||
|
||||
// Knob drag state
|
||||
int draggingKnob; // -1 if none
|
||||
Vector2 dragStart;
|
||||
float dragStartValue;
|
||||
|
||||
// Slider drag state
|
||||
int draggingSlider; // -1 if none
|
||||
|
||||
// MIDI learn state
|
||||
int midiLearnActive; // 0=off 1=click a control 2=wiggle CC
|
||||
int midiLearnTargetId; // id of selected control (-1 if none)
|
||||
float *midiLearnValuePtr;
|
||||
float midiLearnMin;
|
||||
float midiLearnMax;
|
||||
|
||||
// Patch browser state
|
||||
int patchMenuOpen;
|
||||
int focusedTextInput; // -1 if none
|
||||
int patchConfirmOverwrite;
|
||||
int patchConfirmClear;
|
||||
char patchSaveName[PATCH_NAME_LEN];
|
||||
char patchCurrentName[PATCH_NAME_LEN];
|
||||
int patchFileCount;
|
||||
char patchFiles[PATCH_MAX_FILES][PATCH_NAME_LEN];
|
||||
int patchScrollOffset;
|
||||
int patchShowFavsOnly;
|
||||
char patchFavs[PATCH_MAX_FILES][PATCH_NAME_LEN];
|
||||
int patchFavCount;
|
||||
char patchCurrentDir[256];
|
||||
char patchSubDirs[PATCH_MAX_DIRS][PATCH_NAME_LEN];
|
||||
int patchSubDirCount;
|
||||
|
||||
// Control registry — built lazily by uiKnob/uiSlider for CC mapping persistence
|
||||
UIControlEntry controlRegistry[128];
|
||||
int controlRegistryCount;
|
||||
// CC mappings loaded from file but not yet resolved (registry not yet populated)
|
||||
ConfigCcEntry pendingMappings[128];
|
||||
int pendingCount;
|
||||
} UIState;
|
||||
|
||||
// Lifecycle
|
||||
void uiInit(UIState *ui, MidiState *midi, Camera2D *camera);
|
||||
void uiClose(UIState *ui);
|
||||
|
||||
// Primitives
|
||||
float uiKnob(UIState *ui, int id, float x, float y, float *ptr, float min, float max, const char *label);
|
||||
float uiSlider(UIState *ui, int id, float x, float y, float width, float *ptr, float min, float max, const char *label);
|
||||
int uiWaveformSelector(UIState *ui, float x, float y, int currentWaveform);
|
||||
void uiADSRShape(float x, float y, float width, float height, float attack, float decay, float sustain, float release, Color color);
|
||||
void uiVoiceMeter(UIState *ui, float x, float y, Voice *voices, int voiceCount);
|
||||
|
||||
// Panels
|
||||
void uiOscillatorPanel(UIState *ui, int baseId, float x, float y, float width, float height, Oscillator *osc, const char *title);
|
||||
void uiEnvelopePanel(UIState *ui, int baseId, float x, float y, float width, float height, Envelope *env, const char *title);
|
||||
void uiLfoPanel(UIState *ui, int baseId, float x, float y, float width, float height, LFO *lfo, const char *title);
|
||||
void uiFilterPanel(UIState *ui, float x, float y, float width, float height, Filter *filter, const char *title);
|
||||
void uiMasterPanel(UIState *ui, float x, float y, float width, float height, Synth *s);
|
||||
void uiMidiMenu(UIState *ui, float x, float y, float width, MidiState *midi);
|
||||
void uiPatchMenu(UIState *ui, float x, float y, float width, Synth *s);
|
||||
void uiAboutMenu(UIState *ui, float x, float y, float width);
|
||||
void uiLoadCcMappingsForDevice(UIState *ui, const char *deviceName);
|
||||
|
||||
// Window helpers
|
||||
|
||||
void recomputeViewPort(Camera2D* camera, int x_logical_resolution, int y_logical_resolution, int border_width);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user