Revert "Format all"

This reverts commit c7bb89fd6d.
This commit is contained in:
2026-03-12 16:30:04 -04:00
parent 48f2c51d92
commit d5d2f6db8e
31 changed files with 3191 additions and 3280 deletions

View File

@@ -1,31 +0,0 @@
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
AlignConsecutiveDeclarations: true
AlignConsecutiveAssignments: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AlignConsecutiveMacros: true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
Cpp11BracedListStyle: false
ColumnLimit: 0

View File

@@ -1,8 +1,8 @@
#include "audio/audio.h" #include "audio/audio.h"
#include <math.h> #include <windows.h>
#include <objbase.h> #include <objbase.h>
#include <string.h> #include <string.h>
#include <windows.h> #include <math.h>
#define AUDIO_MAX_DEVICES 32 #define AUDIO_MAX_DEVICES 32
#define AUDIO_MAX_CHANNELS 32 #define AUDIO_MAX_CHANNELS 32

View File

@@ -1,9 +1,9 @@
#include "audio/audio.h" #include "audio/audio.h"
#include <AudioToolbox/AudioToolbox.h> #include <AudioToolbox/AudioToolbox.h>
#include <CoreAudio/CoreAudio.h> #include <CoreAudio/CoreAudio.h>
#include <string.h>
#include <math.h> #include <math.h>
#include <stdatomic.h> #include <stdatomic.h>
#include <string.h>
#pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -44,11 +44,9 @@ static OSStatus audio_render_callback(void *inRefCon,
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inBusNumber,
UInt32 inNumberFrames, UInt32 inNumberFrames,
AudioBufferList *ioData) { AudioBufferList *ioData)
(void)inRefCon; {
(void)ioActionFlags; (void)inRefCon; (void)ioActionFlags; (void)inTimeStamp; (void)inBusNumber;
(void)inTimeStamp;
(void)inBusNumber;
AudioEngine *engine = g_audio_engine; AudioEngine *engine = g_audio_engine;
if (!engine) { if (!engine) {
@@ -87,8 +85,7 @@ static OSStatus audio_render_callback(void *inRefCon,
// Advance phase using first channel's traversal // Advance phase using first channel's traversal
phase += phase_inc * samples_to_gen; phase += phase_inc * samples_to_gen;
while (phase >= 2.0 * AUDIO_PI) while (phase >= 2.0 * AUDIO_PI) phase -= 2.0 * AUDIO_PI;
phase -= 2.0 * AUDIO_PI;
engine->test_tone_phase = phase; engine->test_tone_phase = phase;
S32 new_remaining = atomic_fetch_sub(&engine->test_tone_samples_remaining, samples_to_gen); S32 new_remaining = atomic_fetch_sub(&engine->test_tone_samples_remaining, samples_to_gen);

View File

@@ -2,11 +2,11 @@
// base_core.h - Fundamental types, macros, and linked list helpers // base_core.h - Fundamental types, macros, and linked list helpers
// Inspired by raddebugger's base_core.h // Inspired by raddebugger's base_core.h
#include <math.h>
#include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <math.h>
//////////////////////////////// ////////////////////////////////
// Codebase keywords // Codebase keywords
@@ -60,8 +60,7 @@ typedef double F64;
#define Max(A, B) (((A) > (B)) ? (A) : (B)) #define Max(A, B) (((A) > (B)) ? (A) : (B))
#define ClampTop(A, X) Min(A, X) #define ClampTop(A, X) Min(A, X)
#define ClampBot(X, B) Max(X, B) #define ClampBot(X, B) Max(X, B)
#define Clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) \ #define Clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) : (X))
: (X))
//////////////////////////////// ////////////////////////////////
// Alignment / Sizing // Alignment / Sizing
@@ -110,12 +109,7 @@ typedef double F64;
#define Glue_(A, B) A##B #define Glue_(A, B) A##B
#define Glue(A, B) Glue_(A, B) #define Glue(A, B) Glue_(A, B)
#define Swap(T, a, b) \ #define Swap(T, a, b) do { T t__ = a; a = b; b = t__; } while (0)
do { \
T t__ = a; \
a = b; \
b = t__; \
} while (0)
//////////////////////////////// ////////////////////////////////
// Assert // Assert
@@ -128,10 +122,7 @@ typedef double F64;
# define Trap() (*(volatile int *)0 = 0) # define Trap() (*(volatile int *)0 = 0)
#endif #endif
#define AssertAlways(x) \ #define AssertAlways(x) do { if (!(x)) { Trap(); } } while (0)
do { \
if (!(x)) { Trap(); } \
} while (0)
#ifdef _DEBUG #ifdef _DEBUG
# define Assert(x) AssertAlways(x) # define Assert(x) AssertAlways(x)
@@ -151,9 +142,14 @@ typedef double F64;
// Doubly-linked-list (with nil support) // Doubly-linked-list (with nil support)
#define DLLInsert_NPZ(nil, f, l, p, n, next, prev) \ #define DLLInsert_NPZ(nil, f, l, p, n, next, prev) \
(CheckNil(nil, f) ? ((f) = (l) = (n), SetNil(nil, (n)->next), SetNil(nil, (n)->prev)) : CheckNil(nil, p) ? ((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil, (n)->prev)) \ (CheckNil(nil, f) ? \
: ((p) == (l)) ? ((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) \ ((f) = (l) = (n), SetNil(nil, (n)->next), SetNil(nil, (n)->prev)) : \
: (((!CheckNil(nil, p) && CheckNil(nil, (p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) CheckNil(nil, p) ? \
((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil, (n)->prev)) : \
((p) == (l)) ? \
((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) : \
(((!CheckNil(nil, p) && CheckNil(nil, (p)->next)) ? (0) : ((p)->next->prev = (n))), \
((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p))))
#define DLLPushBack_NPZ(nil, f, l, n, next, prev) DLLInsert_NPZ(nil, f, l, l, n, next, prev) #define DLLPushBack_NPZ(nil, f, l, n, next, prev) DLLInsert_NPZ(nil, f, l, l, n, next, prev)
#define DLLPushFront_NPZ(nil, f, l, n, next, prev) DLLInsert_NPZ(nil, l, f, f, n, prev, next) #define DLLPushFront_NPZ(nil, f, l, n, next, prev) DLLInsert_NPZ(nil, l, f, f, n, prev, next)
@@ -171,7 +167,9 @@ typedef double F64;
// Singly-linked queue (doubly-headed) // Singly-linked queue (doubly-headed)
#define SLLQueuePush_NZ(nil, f, l, n, next) \ #define SLLQueuePush_NZ(nil, f, l, n, next) \
(CheckNil(nil, f) ? ((f) = (l) = (n), SetNil(nil, (n)->next)) : ((l)->next = (n), (l) = (n), SetNil(nil, (n)->next))) (CheckNil(nil, f) ? \
((f) = (l) = (n), SetNil(nil, (n)->next)) : \
((l)->next = (n), (l) = (n), SetNil(nil, (n)->next)))
#define SLLQueuePush(f, l, n) SLLQueuePush_NZ(0, f, l, n, next) #define SLLQueuePush(f, l, n) SLLQueuePush_NZ(0, f, l, n, next)
#define SLLQueuePushFront(f, l, n) (((n)->next = (f)), ((f) = (n))) #define SLLQueuePushFront(f, l, n) (((n)->next = (f)), ((f) = (n)))

View File

@@ -2,7 +2,7 @@
// base_inc.h - Umbrella include for the base layer // base_inc.h - Umbrella include for the base layer
// Include this one header to get all base types. // Include this one header to get all base types.
#include "base/base_arena.h"
#include "base/base_core.h" #include "base/base_core.h"
#include "base/base_arena.h"
#include "base/base_math.h" #include "base/base_math.h"
#include "base/base_strings.h" #include "base/base_strings.h"

View File

@@ -30,31 +30,17 @@ enum Corner {
//////////////////////////////// ////////////////////////////////
// Vector types // Vector types
struct Vec2F32 { struct Vec2F32 { F32 x, y; };
F32 x, y; struct Vec2S32 { S32 x, y; };
}; struct Vec3F32 { F32 x, y, z; };
struct Vec2S32 { struct Vec4F32 { F32 x, y, z, w; };
S32 x, y;
};
struct Vec3F32 {
F32 x, y, z;
};
struct Vec4F32 {
F32 x, y, z, w;
};
//////////////////////////////// ////////////////////////////////
// Range types // Range types
struct Rng1F32 { struct Rng1F32 { F32 min, max; };
F32 min, max; struct Rng1S64 { S64 min, max; };
}; struct Rng2F32 { Vec2F32 p0, p1; };
struct Rng1S64 {
S64 min, max;
};
struct Rng2F32 {
Vec2F32 p0, p1;
};
//////////////////////////////// ////////////////////////////////
// Constructors // Constructors
@@ -79,8 +65,7 @@ static inline Vec2F32 scale_2f32(Vec2F32 v, F32 s) { return { v.x * s, v.y * s }
// Axis-indexed access // Axis-indexed access
static inline F32 v2f32_axis(Vec2F32 v, Axis2 a) { return a == Axis2_X ? v.x : v.y; } static inline F32 v2f32_axis(Vec2F32 v, Axis2 a) { return a == Axis2_X ? v.x : v.y; }
static inline void v2f32_set_axis(Vec2F32 *v, Axis2 a, F32 val) { static inline void v2f32_set_axis(Vec2F32 *v, Axis2 a, F32 val) {
if (a == Axis2_X) v->x = val; if (a == Axis2_X) v->x = val; else v->y = val;
else v->y = val;
} }
//////////////////////////////// ////////////////////////////////

View File

@@ -4,34 +4,34 @@
#include <mach/mach_time.h> #include <mach/mach_time.h>
#endif #endif
// [h] // [h]
#include "audio/audio.h"
#include "base/base_inc.h" #include "base/base_inc.h"
#include "midi/midi.h"
#include "platform/platform.h" #include "platform/platform.h"
#include "renderer/renderer.h" #include "renderer/renderer.h"
#include "midi/midi.h"
#include "audio/audio.h"
#include "ui/ui_core.h" #include "ui/ui_core.h"
#include "ui/ui_icons.h" #include "ui/ui_icons.h"
#include "ui/ui_piano.h"
#include "ui/ui_popups.h"
#include "ui/ui_widgets.h" #include "ui/ui_widgets.h"
#include "ui/ui_popups.h"
#include "ui/ui_piano.h"
// [cpp] // [cpp]
#include "base/base_inc.cpp" #include "base/base_inc.cpp"
#include "ui/ui_core.cpp" #include "ui/ui_core.cpp"
#include "ui/ui_icons.cpp" #include "ui/ui_icons.cpp"
#include "ui/ui_piano.cpp"
#include "ui/ui_popups.cpp"
#include "ui/ui_widgets.cpp" #include "ui/ui_widgets.cpp"
#include "ui/ui_popups.cpp"
#include "ui/ui_piano.cpp"
#ifdef __APPLE__ #ifdef __APPLE__
#include "audio/audio_coreaudio.cpp"
#include "midi/midi_coremidi.cpp"
#include "platform/platform_macos.mm" #include "platform/platform_macos.mm"
#include "renderer/renderer_metal.mm" #include "renderer/renderer_metal.mm"
#include "midi/midi_coremidi.cpp"
#include "audio/audio_coreaudio.cpp"
#else #else
#include "audio/audio_asio.cpp"
#include "midi/midi_win32.cpp"
#include "platform/platform_win32.cpp" #include "platform/platform_win32.cpp"
#include "renderer/renderer_vulkan.cpp" #include "renderer/renderer_vulkan.cpp"
#include "midi/midi_win32.cpp"
#include "audio/audio_asio.cpp"
#endif #endif
#include "menus.cpp" #include "menus.cpp"
@@ -182,7 +182,9 @@ static void build_browser_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(app->browser_width)), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_FIXED(uis(app->browser_width)), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = bp_top, .custom = { .customData = bp_grad }, ) { .backgroundColor = bp_top,
.custom = { .customData = bp_grad },
) {
{ {
S32 sel = 0; S32 sel = 0;
static const char *browser_tabs[] = { "Browser" }; static const char *browser_tabs[] = { "Browser" };
@@ -195,11 +197,13 @@ static void build_browser_panel(AppState *app) {
.padding = { uip(8), uip(8), uip(6), uip(6) }, .padding = { uip(8), uip(8), uip(6), uip(6) },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Top highlight (beveled edge) // Top highlight (beveled edge)
CLAY(CLAY_ID("BrowserHighlight"), CLAY(CLAY_ID("BrowserHighlight"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.bg_lighter) {} .backgroundColor = g_theme.bg_lighter
) {}
CLAY_TEXT(CLAY_STRING("Instruments"), &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Instruments"), &g_text_config_normal);
} }
} }
@@ -215,7 +219,9 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = mp_top, .custom = { .customData = mp_grad }) { .backgroundColor = mp_top,
.custom = { .customData = mp_grad }
) {
{ {
S32 sel = 0; S32 sel = 0;
static const char *main_tabs[] = { "Main" }; static const char *main_tabs[] = { "Main" };
@@ -226,7 +232,8 @@ static void build_main_panel(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_ID("MainContent"), CLAY(CLAY_ID("MainContent"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
@@ -234,11 +241,13 @@ static void build_main_panel(AppState *app) {
.childGap = uip(12), .childGap = uip(12),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }, ) { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
) {
// Top highlight (beveled edge) // Top highlight (beveled edge)
CLAY(CLAY_ID("MainHighlight"), CLAY(CLAY_ID("MainHighlight"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.bg_lighter) {} .backgroundColor = g_theme.bg_lighter
) {}
// Section: Buttons // Section: Buttons
ui_label("LblButtons", "Buttons"); ui_label("LblButtons", "Buttons");
CLAY(CLAY_ID("ButtonRow"), CLAY(CLAY_ID("ButtonRow"),
@@ -246,7 +255,8 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(8), .childGap = uip(8),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
if (ui_button("BtnHello", "Click Me")) { if (ui_button("BtnHello", "Click Me")) {
app->demo_button_count++; app->demo_button_count++;
} }
@@ -262,7 +272,8 @@ static void build_main_panel(AppState *app) {
// Separator // Separator
CLAY(CLAY_ID("Sep1"), CLAY(CLAY_ID("Sep1"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Checkboxes // Section: Checkboxes
ui_label("LblCheckboxes", "Checkboxes"); ui_label("LblCheckboxes", "Checkboxes");
@@ -271,7 +282,8 @@ static void build_main_panel(AppState *app) {
CLAY(CLAY_ID("Sep2"), CLAY(CLAY_ID("Sep2"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Radio buttons // Section: Radio buttons
ui_label("LblRadio", "Output Format"); ui_label("LblRadio", "Output Format");
@@ -280,7 +292,8 @@ static void build_main_panel(AppState *app) {
CLAY(CLAY_ID("Sep3"), CLAY(CLAY_ID("Sep3"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Text inputs // Section: Text inputs
ui_label("LblText", "Text Inputs"); ui_label("LblText", "Text Inputs");
@@ -289,13 +302,15 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
.childGap = uip(8), .childGap = uip(8),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_ID("TextCol1"), CLAY(CLAY_ID("TextCol1"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
ui_label("LblName", "Name:"); ui_label("LblName", "Name:");
ui_text_input("TxtName", app->demo_text_a, sizeof(app->demo_text_a)); ui_text_input("TxtName", app->demo_text_a, sizeof(app->demo_text_a));
} }
@@ -304,7 +319,8 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
ui_label("LblPath", "Output Path:"); ui_label("LblPath", "Output Path:");
ui_text_input("TxtPath", app->demo_text_b, sizeof(app->demo_text_b)); ui_text_input("TxtPath", app->demo_text_b, sizeof(app->demo_text_b));
} }
@@ -312,21 +328,24 @@ static void build_main_panel(AppState *app) {
CLAY(CLAY_ID("Sep4"), CLAY(CLAY_ID("Sep4"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Dropdown // Section: Dropdown
ui_label("LblDropdown", "Sample Rate"); ui_label("LblDropdown", "Sample Rate");
CLAY(CLAY_ID("DropdownWrapper"), CLAY(CLAY_ID("DropdownWrapper"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIT() },
}) { }
) {
static const char *rate_options[] = { "44100 Hz", "48000 Hz", "88200 Hz", "96000 Hz", "192000 Hz" }; static const char *rate_options[] = { "44100 Hz", "48000 Hz", "88200 Hz", "96000 Hz", "192000 Hz" };
ui_dropdown("DropRate", rate_options, 5, &app->demo_dropdown_sel); ui_dropdown("DropRate", rate_options, 5, &app->demo_dropdown_sel);
} }
CLAY(CLAY_ID("Sep5"), CLAY(CLAY_ID("Sep5"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Knobs // Section: Knobs
ui_label("LblKnobs", "Knobs"); ui_label("LblKnobs", "Knobs");
@@ -335,14 +354,16 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(16), .childGap = uip(16),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
ui_knob("KnobVolume", "Volume", &app->demo_knob_unsigned, 100.0f, 0, 75.0f, 1); ui_knob("KnobVolume", "Volume", &app->demo_knob_unsigned, 100.0f, 0, 75.0f, 1);
ui_knob("KnobPan", "Pan", &app->demo_knob_signed, 50.0f, 1, 0.0f, 1); ui_knob("KnobPan", "Pan", &app->demo_knob_signed, 50.0f, 1, 0.0f, 1);
} }
CLAY(CLAY_ID("Sep6"), CLAY(CLAY_ID("Sep6"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Sliders // Section: Sliders
ui_label("LblSliders", "Sliders"); ui_label("LblSliders", "Sliders");
@@ -351,7 +372,8 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(16), .childGap = uip(16),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
ui_slider_h("SliderH", "Horizontal", &app->demo_slider_h, 100.0f, 0, 50.0f, 1); ui_slider_h("SliderH", "Horizontal", &app->demo_slider_h, 100.0f, 0, 50.0f, 1);
} }
CLAY(CLAY_ID("SliderVRow"), CLAY(CLAY_ID("SliderVRow"),
@@ -360,14 +382,16 @@ static void build_main_panel(AppState *app) {
.childGap = uip(24), .childGap = uip(24),
.childAlignment = { .y = CLAY_ALIGN_Y_TOP }, .childAlignment = { .y = CLAY_ALIGN_Y_TOP },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
ui_slider_v("SliderV", "Vertical", &app->demo_slider_v, 100.0f, 0, 75.0f, 1); ui_slider_v("SliderV", "Vertical", &app->demo_slider_v, 100.0f, 0, 75.0f, 1);
ui_fader("Fader1", "Fader", &app->demo_fader, 50.0f, 1, 0.0f, 1); ui_fader("Fader1", "Fader", &app->demo_fader, 50.0f, 1, 0.0f, 1);
} }
CLAY(CLAY_ID("Sep7"), CLAY(CLAY_ID("Sep7"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
// Section: Windows & Modals // Section: Windows & Modals
ui_label("LblWindows", "Windows & Modals"); ui_label("LblWindows", "Windows & Modals");
@@ -376,7 +400,8 @@ static void build_main_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(8), .childGap = uip(8),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
if (ui_button("BtnAbout", "About")) { if (ui_button("BtnAbout", "About")) {
app->show_about_window = 1; app->show_about_window = 1;
} }
@@ -453,19 +478,23 @@ static void build_main_panel(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(bar_w), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_FIXED(bar_w), .height = CLAY_SIZING_GROW() },
}, },
.backgroundColor = g_theme.scrollbar_bg) { .backgroundColor = g_theme.scrollbar_bg
) {
CLAY(thumb_id, CLAY(thumb_id,
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(thumb_h) }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(thumb_h) },
}, },
.backgroundColor = thumb_color, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .floating = { .backgroundColor = thumb_color,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.floating = {
.offset = { 0, thumb_y }, .offset = { 0, thumb_y },
.attachPoints = { .attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP, .element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP, .parent = CLAY_ATTACH_POINT_LEFT_TOP,
}, },
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
}, ) {} },
) {}
} }
} else { } else {
app->scrollbar_dragging = false; app->scrollbar_dragging = false;
@@ -487,7 +516,9 @@ static void build_right_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = rp_top, .custom = { .customData = rp_grad }) { .backgroundColor = rp_top,
.custom = { .customData = rp_grad }
) {
ui_tab_bar("RightTabs", right_tabs, 2, &app->right_panel_tab); ui_tab_bar("RightTabs", right_tabs, 2, &app->right_panel_tab);
if (app->right_panel_tab == 0) { if (app->right_panel_tab == 0) {
@@ -498,11 +529,13 @@ static void build_right_panel(AppState *app) {
.padding = { uip(8), uip(8), uip(6), uip(6) }, .padding = { uip(8), uip(8), uip(6), uip(6) },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Top highlight (beveled edge) // Top highlight (beveled edge)
CLAY(CLAY_ID("PropsHighlight"), CLAY(CLAY_ID("PropsHighlight"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.bg_lighter) {} .backgroundColor = g_theme.bg_lighter
) {}
CLAY_TEXT(CLAY_STRING("Details"), &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Details"), &g_text_config_normal);
} }
} else { } else {
@@ -514,11 +547,13 @@ static void build_right_panel(AppState *app) {
.padding = { uip(8), uip(8), uip(6), uip(6) }, .padding = { uip(8), uip(8), uip(6), uip(6) },
.childGap = uip(6), .childGap = uip(6),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Top highlight (beveled edge) // Top highlight (beveled edge)
CLAY(CLAY_ID("MidiHighlight"), CLAY(CLAY_ID("MidiHighlight"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.bg_lighter) {} .backgroundColor = g_theme.bg_lighter
) {}
// Refresh button // Refresh button
Clay_ElementId refresh_eid = CLAY_ID("MidiRefreshBtn"); Clay_ElementId refresh_eid = CLAY_ID("MidiRefreshBtn");
B32 refresh_hovered = Clay_PointerOver(refresh_eid); B32 refresh_hovered = Clay_PointerOver(refresh_eid);
@@ -528,7 +563,9 @@ static void build_right_panel(AppState *app) {
.padding = { uip(12), uip(12), 0, 0 }, .padding = { uip(12), uip(12), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = refresh_hovered ? g_theme.accent_hover : g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)) { .backgroundColor = refresh_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
) {
CLAY_TEXT(CLAY_STRING("Refresh"), &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Refresh"), &g_text_config_normal);
} }
if (refresh_hovered && g_wstate.mouse_clicked) { if (refresh_hovered && g_wstate.mouse_clicked) {
@@ -605,14 +642,17 @@ static void build_right_panel(AppState *app) {
.childGap = uip(6), .childGap = uip(6),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Note name box (colored by velocity) // Note name box (colored by velocity)
CLAY(CLAY_IDI("MidiInNote", i), CLAY(CLAY_IDI("MidiInNote", i),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(uis(36)), .height = CLAY_SIZING_FIXED(uis(18)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(36)), .height = CLAY_SIZING_FIXED(uis(18)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = box_color, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)) { .backgroundColor = box_color,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
) {
CLAY_TEXT(note_str, box_txt); CLAY_TEXT(note_str, box_txt);
} }
// Velocity number // Velocity number
@@ -641,7 +681,8 @@ static void build_right_panel(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
.padding = { uip(4), uip(4), uip(2), uip(2) }, .padding = { uip(4), uip(4), uip(2), uip(2) },
}) { }
) {
CLAY_TEXT(device_str, &g_text_config_normal); CLAY_TEXT(device_str, &g_text_config_normal);
} }
} }
@@ -665,7 +706,9 @@ static void build_log_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(app->log_height)) }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(app->log_height)) },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = lp_top, .custom = { .customData = lp_grad }, ) { .backgroundColor = lp_top,
.custom = { .customData = lp_grad },
) {
static const char *bottom_tabs[] = { "Item Editor", "Sample Mapper" }; static const char *bottom_tabs[] = { "Item Editor", "Sample Mapper" };
ui_tab_bar("BottomTabRow", bottom_tabs, 2, &app->bottom_panel_tab); ui_tab_bar("BottomTabRow", bottom_tabs, 2, &app->bottom_panel_tab);
@@ -677,10 +720,12 @@ static void build_log_panel(AppState *app) {
.padding = { uip(8), uip(8), uip(6), uip(6) }, .padding = { uip(8), uip(8), uip(6), uip(6) },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
CLAY(CLAY_ID("ItemEditorHighlight"), CLAY(CLAY_ID("ItemEditorHighlight"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.bg_lighter) {} .backgroundColor = g_theme.bg_lighter
) {}
CLAY_TEXT(CLAY_STRING("Item Editor"), &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Item Editor"), &g_text_config_normal);
} }
} else { } else {
@@ -690,7 +735,8 @@ static void build_log_panel(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.padding = { uip(4), uip(4), uip(4), uip(4) }, .padding = { uip(4), uip(4), uip(4), uip(4) },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
F32 piano_avail_h = uis(app->log_height) - TAB_HEIGHT - uip(8); F32 piano_avail_h = uis(app->log_height) - TAB_HEIGHT - uip(8);
F32 piano_avail_w = (F32)app->last_w - uip(8); F32 piano_avail_w = (F32)app->last_w - uip(8);
ui_piano(&app->piano_state, app->midi, piano_avail_w, piano_avail_h); ui_piano(&app->piano_state, app->midi, piano_avail_w, piano_avail_h);
@@ -718,7 +764,8 @@ static void settings_window_content(void *user_data) {
.padding = { 0, 0, uip(8), 0 }, .padding = { 0, 0, uip(8), 0 },
.childGap = uip(6), .childGap = uip(6),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
if (app->settings_tab == 0) { if (app->settings_tab == 0) {
// === Audio tab === // === Audio tab ===
ui_label("SettingsLblAudio", "Audio Device"); ui_label("SettingsLblAudio", "Audio Device");
@@ -732,7 +779,8 @@ static void settings_window_content(void *user_data) {
} }
CLAY(CLAY_ID("SettingsAudioWrap"), CLAY(CLAY_ID("SettingsAudioWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(260)), .height = CLAY_SIZING_FIT() } }) { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(260)), .height = CLAY_SIZING_FIT() } }
) {
ui_dropdown("SettingsAudio", audio_options, audio_count + 1, &app->audio_device_sel); ui_dropdown("SettingsAudio", audio_options, audio_count + 1, &app->audio_device_sel);
} }
@@ -750,7 +798,8 @@ static void settings_window_content(void *user_data) {
.childGap = uip(8), .childGap = uip(8),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
B32 device_open = (app->audio_device_sel > 0); B32 device_open = (app->audio_device_sel > 0);
B32 tone_playing = audio_is_test_tone_playing(app->audio); B32 tone_playing = audio_is_test_tone_playing(app->audio);
@@ -766,7 +815,9 @@ static void settings_window_content(void *user_data) {
.padding = { uip(12), uip(12), 0, 0 }, .padding = { uip(12), uip(12), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.disabled_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)) { .backgroundColor = g_theme.disabled_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
) {
static Clay_TextElementConfig disabled_text = {}; static Clay_TextElementConfig disabled_text = {};
disabled_text.textColor = g_theme.disabled_text; disabled_text.textColor = g_theme.disabled_text;
disabled_text.fontSize = FONT_SIZE_NORMAL; disabled_text.fontSize = FONT_SIZE_NORMAL;
@@ -795,21 +846,24 @@ static void settings_window_content(void *user_data) {
ui_label("SettingsLblTheme", "Theme"); ui_label("SettingsLblTheme", "Theme");
static const char *theme_options[] = { "Dark", "Light" }; static const char *theme_options[] = { "Dark", "Light" };
CLAY(CLAY_ID("SettingsThemeWrap"), CLAY(CLAY_ID("SettingsThemeWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }) { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
) {
ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel); ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel);
} }
ui_label("SettingsLblAccent", "Accent Color"); ui_label("SettingsLblAccent", "Accent Color");
static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" }; static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" };
CLAY(CLAY_ID("SettingsAccentWrap"), CLAY(CLAY_ID("SettingsAccentWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }) { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
) {
ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel); ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel);
} }
ui_label("SettingsLblRadius", "Corner Radius"); ui_label("SettingsLblRadius", "Corner Radius");
static const char *radius_options[] = { "None", "Small", "Medium", "Large" }; static const char *radius_options[] = { "None", "Small", "Medium", "Large" };
CLAY(CLAY_ID("SettingsRadiusWrap"), CLAY(CLAY_ID("SettingsRadiusWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }) { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
) {
if (ui_dropdown("SettingsRadius", radius_options, 4, &app->radius_sel)) { if (ui_dropdown("SettingsRadius", radius_options, 4, &app->radius_sel)) {
g_theme.corner_radius = radius_values[app->radius_sel]; g_theme.corner_radius = radius_values[app->radius_sel];
} }
@@ -831,10 +885,7 @@ static void about_window_content(void *user_data) {
// Panel splitter drag logic (called each frame before build_ui) // Panel splitter drag logic (called each frame before build_ui)
static void update_panel_splitters(AppState *app) { static void update_panel_splitters(AppState *app) {
if (app->master_layout != 0) { if (app->master_layout != 0) { platform_set_cursor(PLATFORM_CURSOR_ARROW); return; }
platform_set_cursor(PLATFORM_CURSOR_ARROW);
return;
}
PlatformInput input = g_wstate.input; PlatformInput input = g_wstate.input;
B32 mouse_clicked = input.mouse_down && !input.was_mouse_down; B32 mouse_clicked = input.mouse_down && !input.was_mouse_down;
B32 mouse_released = !input.mouse_down && input.was_mouse_down; B32 mouse_released = !input.mouse_down && input.was_mouse_down;
@@ -955,7 +1006,9 @@ static void build_header_bar(AppState *app) {
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = bar_bg, .border = { .color = border_bot, .width = { .bottom = 2 } }, ) { .backgroundColor = bar_bg,
.border = { .color = border_bot, .width = { .bottom = 2 } },
) {
// === LEFT: toolbar buttons === // === LEFT: toolbar buttons ===
CLAY(CLAY_ID("ToolbarGroup"), CLAY(CLAY_ID("ToolbarGroup"),
.layout = { .layout = {
@@ -963,14 +1016,17 @@ static void build_header_bar(AppState *app) {
.childGap = uip(4), .childGap = uip(4),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Rewind // Rewind
CLAY(CLAY_ID("TbRewind"), CLAY(CLAY_ID("TbRewind"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { ui_icon(UI_ICON_TRANSPORT_REWIND, uis(16), g_theme.text_dim); } .backgroundColor = g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) { ui_icon(UI_ICON_TRANSPORT_REWIND, uis(16), g_theme.text_dim); }
// Stop // Stop
CLAY(CLAY_ID("TbStop"), CLAY(CLAY_ID("TbStop"),
@@ -978,7 +1034,9 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { ui_icon(UI_ICON_TRANSPORT_STOP, uis(14), g_theme.text_dim); } .backgroundColor = g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) { ui_icon(UI_ICON_TRANSPORT_STOP, uis(14), g_theme.text_dim); }
// Play // Play
CLAY(CLAY_ID("TbPlay"), CLAY(CLAY_ID("TbPlay"),
@@ -986,7 +1044,9 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { ui_icon(UI_ICON_TRANSPORT_PLAY, uis(16), g_theme.text_dim); } .backgroundColor = g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) { ui_icon(UI_ICON_TRANSPORT_PLAY, uis(16), g_theme.text_dim); }
// Record // Record
CLAY(CLAY_ID("TbRecord"), CLAY(CLAY_ID("TbRecord"),
@@ -994,12 +1054,15 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { ui_icon(UI_ICON_TRANSPORT_RECORD, uis(14), Clay_Color{ 200, 60, 60, 255 }); } .backgroundColor = g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) { ui_icon(UI_ICON_TRANSPORT_RECORD, uis(14), Clay_Color{200, 60, 60, 255}); }
} }
// Spacer // Spacer
CLAY(CLAY_ID("HeaderSpacerL"), CLAY(CLAY_ID("HeaderSpacerL"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }) {} .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }
) {}
// === CENTER: time display (nearly full header height) === // === CENTER: time display (nearly full header height) ===
CLAY(CLAY_ID("TimeDisplay"), CLAY(CLAY_ID("TimeDisplay"),
@@ -1007,7 +1070,10 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIXED(uis(48)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIXED(uis(48)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = inset_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } }, ) { .backgroundColor = inset_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
) {
CLAY_TEXT(CLAY_STRING("00:00:00.000"), &header_clock_text); CLAY_TEXT(CLAY_STRING("00:00:00.000"), &header_clock_text);
} }
@@ -1018,7 +1084,8 @@ static void build_header_bar(AppState *app) {
.childGap = uip(10), .childGap = uip(10),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Tempo // Tempo
CLAY(CLAY_ID("TempoBox"), CLAY(CLAY_ID("TempoBox"),
.layout = { .layout = {
@@ -1028,7 +1095,10 @@ static void build_header_bar(AppState *app) {
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = inset_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } }, ) { .backgroundColor = inset_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
) {
CLAY_TEXT(CLAY_STRING("TEMPO"), &header_indicator_label); CLAY_TEXT(CLAY_STRING("TEMPO"), &header_indicator_label);
CLAY_TEXT(CLAY_STRING("120.00"), &header_indicator_text); CLAY_TEXT(CLAY_STRING("120.00"), &header_indicator_text);
} }
@@ -1042,7 +1112,10 @@ static void build_header_bar(AppState *app) {
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = inset_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } }, ) { .backgroundColor = inset_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
) {
CLAY_TEXT(CLAY_STRING("SIGNATURE"), &header_indicator_label); CLAY_TEXT(CLAY_STRING("SIGNATURE"), &header_indicator_label);
CLAY_TEXT(CLAY_STRING("4 / 4"), &header_indicator_text); CLAY_TEXT(CLAY_STRING("4 / 4"), &header_indicator_text);
} }
@@ -1050,7 +1123,8 @@ static void build_header_bar(AppState *app) {
// Spacer // Spacer
CLAY(CLAY_ID("HeaderSpacerR"), CLAY(CLAY_ID("HeaderSpacerR"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }) {} .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }
) {}
// === RIGHT: Edit / Mix buttons === // === RIGHT: Edit / Mix buttons ===
// Edit button // Edit button
@@ -1066,7 +1140,9 @@ static void build_header_bar(AppState *app) {
.padding = { uip(14), uip(14), 0, 0 }, .padding = { uip(14), uip(14), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = edit_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = edit_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
CLAY_TEXT(CLAY_STRING("Edit"), edit_active ? &header_btn_active_text : &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Edit"), edit_active ? &header_btn_active_text : &g_text_config_normal);
} }
if (edit_hovered && g_wstate.mouse_clicked) { if (edit_hovered && g_wstate.mouse_clicked) {
@@ -1087,7 +1163,9 @@ static void build_header_bar(AppState *app) {
.padding = { uip(14), uip(14), 0, 0 }, .padding = { uip(14), uip(14), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = mix_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = mix_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
CLAY_TEXT(CLAY_STRING("Mix"), mix_active ? &header_btn_active_text : &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Mix"), mix_active ? &header_btn_active_text : &g_text_config_normal);
} }
if (mix_hovered && g_wstate.mouse_clicked) { if (mix_hovered && g_wstate.mouse_clicked) {
@@ -1110,7 +1188,9 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(22)), .height = CLAY_SIZING_FIXED(uis(22)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(22)), .height = CLAY_SIZING_FIXED(uis(22)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = pop_hovered ? g_theme.accent_hover : g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = pop_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
ui_icon(mix_popped ? UI_ICON_POP_IN : UI_ICON_POP_OUT, uis(12), g_theme.text_dim); ui_icon(mix_popped ? UI_ICON_POP_IN : UI_ICON_POP_OUT, uis(12), g_theme.text_dim);
} }
if (pop_hovered && g_wstate.mouse_clicked) { if (pop_hovered && g_wstate.mouse_clicked) {
@@ -1138,7 +1218,9 @@ static void build_header_bar(AppState *app) {
.padding = { uip(14), uip(14), 0, 0 }, .padding = { uip(14), uip(14), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = patch_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = patch_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
CLAY_TEXT(CLAY_STRING("Patch"), patch_active ? &header_btn_active_text : &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Patch"), patch_active ? &header_btn_active_text : &g_text_config_normal);
} }
if (patch_hovered && g_wstate.mouse_clicked) { if (patch_hovered && g_wstate.mouse_clicked) {
@@ -1161,7 +1243,9 @@ static void build_header_bar(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(uis(22)), .height = CLAY_SIZING_FIXED(uis(22)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(22)), .height = CLAY_SIZING_FIXED(uis(22)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = pop_hovered ? g_theme.accent_hover : g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = pop_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
ui_icon(patch_popped ? UI_ICON_POP_IN : UI_ICON_POP_OUT, uis(12), g_theme.text_dim); ui_icon(patch_popped ? UI_ICON_POP_IN : UI_ICON_POP_OUT, uis(12), g_theme.text_dim);
} }
if (pop_hovered && g_wstate.mouse_clicked) { if (pop_hovered && g_wstate.mouse_clicked) {
@@ -1193,7 +1277,9 @@ static void build_mix_view(AppState *app) {
.childGap = 0, .childGap = 0,
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = mv_top, .custom = { .customData = mv_grad }, ) { .backgroundColor = mv_top,
.custom = { .customData = mv_grad },
) {
static char ch_label_bufs[8][8]; static char ch_label_bufs[8][8];
static char fader_id_bufs[8][16]; static char fader_id_bufs[8][16];
static char pan_id_bufs[8][16]; static char pan_id_bufs[8][16];
@@ -1213,7 +1299,9 @@ static void build_mix_view(AppState *app) {
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = strip_bg, .border = { .color = g_theme.border, .width = { .right = 1 } }, ) { .backgroundColor = strip_bg,
.border = { .color = g_theme.border, .width = { .right = 1 } },
) {
// Channel label // Channel label
S32 llen = snprintf(ch_label_bufs[i], sizeof(ch_label_bufs[i]), "Ch %d", i + 1); S32 llen = snprintf(ch_label_bufs[i], sizeof(ch_label_bufs[i]), "Ch %d", i + 1);
Clay_String ch_str = { .isStaticallyAllocated = false, .length = llen, .chars = ch_label_bufs[i] }; Clay_String ch_str = { .isStaticallyAllocated = false, .length = llen, .chars = ch_label_bufs[i] };
@@ -1227,13 +1315,16 @@ static void build_mix_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = sr_hovered ? g_theme.accent_hover : g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = sr_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim); CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim);
} }
// Spacer pushes pan + fader to bottom // Spacer pushes pan + fader to bottom
CLAY(CLAY_IDI("MixSpacer", i), CLAY(CLAY_IDI("MixSpacer", i),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }) {} .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }
) {}
// Pan knob // Pan knob
ui_knob(pan_id_bufs[i], "Pan", &app->mix_pans[i], 50.0f, 1, 0.0f, 1); ui_knob(pan_id_bufs[i], "Pan", &app->mix_pans[i], 50.0f, 1, 0.0f, 1);
@@ -1261,7 +1352,8 @@ static void build_mix_view(AppState *app) {
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = master_bg, ) { .backgroundColor = master_bg,
) {
CLAY_TEXT(CLAY_STRING("Master"), &g_text_config_normal); CLAY_TEXT(CLAY_STRING("Master"), &g_text_config_normal);
// SEND/RECV button // SEND/RECV button
@@ -1273,13 +1365,16 @@ static void build_mix_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = msr_hovered ? g_theme.accent_hover : g_theme.bg_lighter, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), ) { .backgroundColor = msr_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
) {
CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim); CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim);
} }
} }
CLAY(CLAY_ID("MixMasterSpacer"), CLAY(CLAY_ID("MixMasterSpacer"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }) {} .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }
) {}
// Master pan knob // Master pan knob
ui_knob("MixMasterPan", "Pan", &app->mix_master_pan, 50.0f, 1, 0.0f, 1); ui_knob("MixMasterPan", "Pan", &app->mix_master_pan, 50.0f, 1, 0.0f, 1);
@@ -1303,7 +1398,9 @@ static void build_patch_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = pv_top, .custom = { .customData = pv_grad }, ) { .backgroundColor = pv_top,
.custom = { .customData = pv_grad },
) {
static const char *patch_tabs[] = { "Matrix", "Graph" }; static const char *patch_tabs[] = { "Matrix", "Graph" };
ui_tab_bar("PatchTabs", patch_tabs, 2, &app->patch_tab); ui_tab_bar("PatchTabs", patch_tabs, 2, &app->patch_tab);
@@ -1349,7 +1446,8 @@ static void build_patch_view(AppState *app) {
.childGap = uip(32), .childGap = uip(32),
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() }, ) { .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() },
) {
// ============================================================ // ============================================================
// INTERNAL ROUTING matrix (32 inputs x 33 outputs) // INTERNAL ROUTING matrix (32 inputs x 33 outputs)
// ============================================================ // ============================================================
@@ -1358,7 +1456,8 @@ static void build_patch_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Title // Title
CLAY_TEXT(CLAY_STRING("Internal Routing"), &matrix_title_text); CLAY_TEXT(CLAY_STRING("Internal Routing"), &matrix_title_text);
@@ -1367,7 +1466,8 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.padding = { (U16)label_w, 0, 0, 0 }, .padding = { (U16)label_w, 0, 0, 0 },
}) { }
) {
CLAY_TEXT(CLAY_STRING("OUTPUT >"), &matrix_axis_text); CLAY_TEXT(CLAY_STRING("OUTPUT >"), &matrix_axis_text);
} }
@@ -1376,19 +1476,22 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Column headers // Column headers
CLAY(CLAY_ID("IntHeaderRow"), CLAY(CLAY_ID("IntHeaderRow"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_ID("IntCorner"), CLAY(CLAY_ID("IntCorner"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
.padding = { 0, uip(4), 0, 0 }, .padding = { 0, uip(4), 0, 0 },
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
}) { }
) {
CLAY_TEXT(CLAY_STRING("INPUT v"), &matrix_axis_text); CLAY_TEXT(CLAY_STRING("INPUT v"), &matrix_axis_text);
} }
@@ -1405,7 +1508,8 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, ) { },
) {
CLAY_TEXT(dst_str, d == 0 ? &matrix_axis_text : &matrix_hdr_text); CLAY_TEXT(dst_str, d == 0 ? &matrix_axis_text : &matrix_hdr_text);
} }
} }
@@ -1421,13 +1525,15 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_IDI("IntSrcLbl", s), CLAY(CLAY_IDI("IntSrcLbl", s),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
.padding = { 0, uip(4), 0, 0 }, .padding = { 0, uip(4), 0, 0 },
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
}, ) { },
) {
CLAY_TEXT(src_str, &matrix_hdr_text); CLAY_TEXT(src_str, &matrix_hdr_text);
} }
@@ -1475,7 +1581,9 @@ static void build_patch_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = cell_bg, .border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } }, ) { .backgroundColor = cell_bg,
.border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } },
) {
if (is_feedback) { if (is_feedback) {
CLAY_TEXT(CLAY_STRING("-"), &fb_text); CLAY_TEXT(CLAY_STRING("-"), &fb_text);
} else if (active) { } else if (active) {
@@ -1500,7 +1608,8 @@ static void build_patch_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Title // Title
CLAY_TEXT(CLAY_STRING("Hardware Routing"), &matrix_title_text); CLAY_TEXT(CLAY_STRING("Hardware Routing"), &matrix_title_text);
@@ -1509,7 +1618,8 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.padding = { (U16)label_w, 0, 0, 0 }, .padding = { (U16)label_w, 0, 0, 0 },
}) { }
) {
CLAY_TEXT(CLAY_STRING("HW OUTPUT >"), &matrix_axis_text); CLAY_TEXT(CLAY_STRING("HW OUTPUT >"), &matrix_axis_text);
} }
@@ -1518,19 +1628,22 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Column headers // Column headers
CLAY(CLAY_ID("HwHeaderRow"), CLAY(CLAY_ID("HwHeaderRow"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_ID("HwCorner"), CLAY(CLAY_ID("HwCorner"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
.padding = { 0, uip(4), 0, 0 }, .padding = { 0, uip(4), 0, 0 },
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
}) { }
) {
CLAY_TEXT(CLAY_STRING("CH OUT v"), &matrix_axis_text); CLAY_TEXT(CLAY_STRING("CH OUT v"), &matrix_axis_text);
} }
@@ -1543,7 +1656,8 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, ) { },
) {
CLAY_TEXT(dst_str, &matrix_hdr_text); CLAY_TEXT(dst_str, &matrix_hdr_text);
} }
} }
@@ -1559,13 +1673,15 @@ static void build_patch_view(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
CLAY(CLAY_IDI("HwSrcLbl", s), CLAY(CLAY_IDI("HwSrcLbl", s),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
.padding = { 0, uip(4), 0, 0 }, .padding = { 0, uip(4), 0, 0 },
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
}, ) { },
) {
CLAY_TEXT(src_str, &matrix_hdr_text); CLAY_TEXT(src_str, &matrix_hdr_text);
} }
@@ -1595,7 +1711,9 @@ static void build_patch_view(AppState *app) {
.sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) }, .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = cell_bg, .border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } }, ) { .backgroundColor = cell_bg,
.border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } },
) {
if (active) { if (active) {
CLAY_TEXT(CLAY_STRING("X"), &cell_x_text); CLAY_TEXT(CLAY_STRING("X"), &cell_x_text);
} }
@@ -1618,7 +1736,8 @@ static void build_patch_view(AppState *app) {
.padding = { uip(16), uip(16), uip(12), uip(12) }, .padding = { uip(16), uip(16), uip(12), uip(12) },
.childGap = 0, .childGap = 0,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}) { }
) {
CLAY_TEXT(CLAY_STRING("Graph view coming soon"), &g_text_config_dim); CLAY_TEXT(CLAY_STRING("Graph view coming soon"), &g_text_config_dim);
} }
} }
@@ -1644,7 +1763,8 @@ static void build_ui(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
build_header_bar(app); build_header_bar(app);
if (app->master_layout == 0) { if (app->master_layout == 0) {
@@ -1653,14 +1773,16 @@ static void build_ui(AppState *app) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
build_browser_panel(app); build_browser_panel(app);
// Browser splitter (vertical, 1px line) // Browser splitter (vertical, 1px line)
if (app->show_browser) { if (app->show_browser) {
CLAY(CLAY_ID("SplitBrowser"), CLAY(CLAY_ID("SplitBrowser"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } }, .layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
} }
build_main_panel(app); build_main_panel(app);
@@ -1669,13 +1791,15 @@ static void build_ui(AppState *app) {
// Right splitter (vertical, 1px line) // Right splitter (vertical, 1px line)
CLAY(CLAY_ID("SplitRight"), CLAY(CLAY_ID("SplitRight"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } }, .layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
CLAY(CLAY_ID("RightColumn"), CLAY(CLAY_ID("RightColumn"),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(uis(app->right_col_width)), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_FIXED(uis(app->right_col_width)), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, ) { },
) {
build_right_panel(app); build_right_panel(app);
} }
} }
@@ -1685,7 +1809,8 @@ static void build_ui(AppState *app) {
if (app->show_log) { if (app->show_log) {
CLAY(CLAY_ID("SplitLog"), CLAY(CLAY_ID("SplitLog"),
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }, .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
.backgroundColor = g_theme.border) {} .backgroundColor = g_theme.border
) {}
} }
build_log_panel(app); build_log_panel(app);
@@ -1701,6 +1826,7 @@ static void build_ui(AppState *app) {
} }
} }
} }
} }
//////////////////////////////// ////////////////////////////////
@@ -1891,10 +2017,7 @@ int main(int argc, char **argv) {
app.log_height = 180.0f; app.log_height = 180.0f;
app.panel_drag = 0; app.panel_drag = 0;
app.master_layout = 0; app.master_layout = 0;
for (S32 i = 0; i < 8; i++) { for (S32 i = 0; i < 8; i++) { app.mix_faders[i] = 0.0f; app.mix_pans[i] = 0.0f; }
app.mix_faders[i] = 0.0f;
app.mix_pans[i] = 0.0f;
}
app.mix_master_pan = 0.0f; app.mix_master_pan = 0.0f;
app.patch_tab = 0; app.patch_tab = 0;
memset(app.patch_matrix, 0, sizeof(app.patch_matrix)); memset(app.patch_matrix, 0, sizeof(app.patch_matrix));
@@ -1902,12 +2025,7 @@ int main(int argc, char **argv) {
snprintf(app.demo_text_a, sizeof(app.demo_text_a), "My Instrument"); snprintf(app.demo_text_a, sizeof(app.demo_text_a), "My Instrument");
#ifdef __APPLE__ #ifdef __APPLE__
snprintf(app.demo_text_b, sizeof(app.demo_text_b), "~/Samples/output"); snprintf(app.demo_text_b, sizeof(app.demo_text_b), "~/Samples/output");
{ { mach_timebase_info_data_t tbi; mach_timebase_info(&tbi); app.freq_numer = tbi.numer; app.freq_denom = tbi.denom; }
mach_timebase_info_data_t tbi;
mach_timebase_info(&tbi);
app.freq_numer = tbi.numer;
app.freq_denom = tbi.denom;
}
app.last_time = mach_absolute_time(); app.last_time = mach_absolute_time();
#else #else
snprintf(app.demo_text_b, sizeof(app.demo_text_b), "C:\\Samples\\output"); snprintf(app.demo_text_b, sizeof(app.demo_text_b), "C:\\Samples\\output");

View File

@@ -1,8 +1,8 @@
#include "midi/midi.h" #include "midi/midi.h"
#include <CoreFoundation/CoreFoundation.h>
#include <CoreMIDI/CoreMIDI.h> #include <CoreMIDI/CoreMIDI.h>
#include <stdatomic.h> #include <CoreFoundation/CoreFoundation.h>
#include <string.h> #include <string.h>
#include <stdatomic.h>
#define MIDI_MAX_DEVICES 64 #define MIDI_MAX_DEVICES 64
#define MIDI_RELEASE_FLASH_DURATION 0.15f #define MIDI_RELEASE_FLASH_DURATION 0.15f
@@ -50,10 +50,7 @@ static void midi_read_callback(const MIDIPacketList *pktlist, void *readProcRefC
U8 status = packet->data[j]; U8 status = packet->data[j];
// Skip non-status bytes (running status not handled for simplicity) // Skip non-status bytes (running status not handled for simplicity)
if (status < 0x80) { if (status < 0x80) { j++; continue; }
j++;
continue;
}
U8 kind = status & 0xF0; U8 kind = status & 0xF0;
@@ -95,8 +92,7 @@ static void midi_read_callback(const MIDIPacketList *pktlist, void *readProcRefC
} else if (kind == 0xF0) { } else if (kind == 0xF0) {
// System messages — skip to end or next status byte // System messages — skip to end or next status byte
j++; j++;
while (j < packet->length && packet->data[j] < 0x80) while (j < packet->length && packet->data[j] < 0x80) j++;
j++;
} else { } else {
j += 3; // Default: 3-byte message j += 3; // Default: 3-byte message
} }

View File

@@ -1,7 +1,7 @@
#include "midi/midi.h" #include "midi/midi.h"
#include <windows.h>
#include <mmeapi.h> #include <mmeapi.h>
#include <string.h> #include <string.h>
#include <windows.h>
#define MIDI_MAX_DEVICES 64 #define MIDI_MAX_DEVICES 64
#define MIDI_RELEASE_FLASH_DURATION 0.15f #define MIDI_RELEASE_FLASH_DURATION 0.15f

View File

@@ -4,27 +4,16 @@
// macOS virtual key codes (avoids Carbon.h include) // macOS virtual key codes (avoids Carbon.h include)
enum { enum {
kVK_ANSI_A = 0x00, kVK_ANSI_A = 0x00, kVK_ANSI_C = 0x08, kVK_ANSI_V = 0x09,
kVK_ANSI_C = 0x08,
kVK_ANSI_V = 0x09,
kVK_ANSI_X = 0x07, kVK_ANSI_X = 0x07,
kVK_Return = 0x24, kVK_Return = 0x24, kVK_Tab = 0x30, kVK_Delete = 0x33,
kVK_Tab = 0x30, kVK_Escape = 0x35, kVK_ForwardDelete = 0x75,
kVK_Delete = 0x33, kVK_LeftArrow = 0x7B, kVK_RightArrow = 0x7C,
kVK_Escape = 0x35, kVK_DownArrow = 0x7D, kVK_UpArrow = 0x7E,
kVK_ForwardDelete = 0x75, kVK_Home = 0x73, kVK_End = 0x77,
kVK_LeftArrow = 0x7B, kVK_Command = 0x37, kVK_Shift = 0x38,
kVK_RightArrow = 0x7C, kVK_RightShift = 0x3C, kVK_RightCommand = 0x36,
kVK_DownArrow = 0x7D, kVK_ANSI_Equal = 0x18, kVK_ANSI_Minus = 0x1B,
kVK_UpArrow = 0x7E,
kVK_Home = 0x73,
kVK_End = 0x77,
kVK_Command = 0x37,
kVK_Shift = 0x38,
kVK_RightShift = 0x3C,
kVK_RightCommand = 0x36,
kVK_ANSI_Equal = 0x18,
kVK_ANSI_Minus = 0x1B,
kVK_ANSI_0 = 0x1D, kVK_ANSI_0 = 0x1D,
kVK_ANSI_KeypadEnter = 0x4C, kVK_ANSI_KeypadEnter = 0x4C,
}; };
@@ -69,13 +58,8 @@ static PlatformWindow *g_main_window = nullptr;
@end @end
@implementation ASmplAppDelegate @implementation ASmplAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)notification { - (void)applicationDidFinishLaunching:(NSNotification *)notification { (void)notification; }
(void)notification; - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { (void)sender; return YES; }
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
(void)sender;
return YES;
}
@end @end
@interface ASmplWindowDelegate : NSObject <NSWindowDelegate> { @interface ASmplWindowDelegate : NSObject <NSWindowDelegate> {
@@ -117,10 +101,7 @@ static void platform_macos_insert_text_pw(PlatformWindow *pw, const char *utf8)
PlatformInput *ev = &pw->input; PlatformInput *ev = &pw->input;
while (*utf8 && ev->char_count < PLATFORM_MAX_CHARS_PER_FRAME) { while (*utf8 && ev->char_count < PLATFORM_MAX_CHARS_PER_FRAME) {
U8 c = (U8)*utf8; U8 c = (U8)*utf8;
if (c < 32) { if (c < 32) { utf8++; continue; }
utf8++;
continue;
}
// Handle ASCII printable range (single-byte UTF-8) // Handle ASCII printable range (single-byte UTF-8)
if (c < 0x80) { if (c < 0x80) {
ev->chars[ev->char_count++] = (U16)c; ev->chars[ev->char_count++] = (U16)c;
@@ -174,45 +155,25 @@ static void platform_macos_key_down_pw(PlatformWindow *pw, U16 keycode, NSEventM
@implementation ASmplView @implementation ASmplView
- (BOOL)acceptsFirstResponder { - (BOOL)acceptsFirstResponder { return YES; }
return YES; - (BOOL)canBecomeKeyView { return YES; }
}
- (BOOL)canBecomeKeyView {
return YES;
}
// Needed for NSTextInputClient // Needed for NSTextInputClient
- (BOOL)hasMarkedText { - (BOOL)hasMarkedText { return NO; }
return NO; - (NSRange)markedRange { return NSMakeRange(NSNotFound, 0); }
} - (NSRange)selectedRange { return NSMakeRange(NSNotFound, 0); }
- (NSRange)markedRange {
return NSMakeRange(NSNotFound, 0);
}
- (NSRange)selectedRange {
return NSMakeRange(NSNotFound, 0);
}
- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {
(void)string; (void)string; (void)selectedRange; (void)replacementRange;
(void)selectedRange;
(void)replacementRange;
}
- (void)unmarkText {
}
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText {
return @[];
} }
- (void)unmarkText {}
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText { return @[]; }
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange { - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange {
(void)range; (void)range; (void)actualRange;
(void)actualRange;
return nil; return nil;
} }
- (NSUInteger)characterIndexForPoint:(NSPoint)point { - (NSUInteger)characterIndexForPoint:(NSPoint)point { (void)point; return NSNotFound; }
(void)point;
return NSNotFound;
}
- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange { - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange {
(void)range; (void)range; (void)actualRange;
(void)actualRange;
return NSZeroRect; return NSZeroRect;
} }
@@ -249,12 +210,8 @@ static void platform_macos_key_down_pw(PlatformWindow *pw, U16 keycode, NSEventM
if (_platformWindow) _platformWindow->mouse_down_state = 0; if (_platformWindow) _platformWindow->mouse_down_state = 0;
} }
- (void)mouseMoved:(NSEvent *)event { - (void)mouseMoved:(NSEvent *)event { (void)event; }
(void)event; - (void)mouseDragged:(NSEvent *)event { (void)event; }
}
- (void)mouseDragged:(NSEvent *)event {
(void)event;
}
- (void)scrollWheel:(NSEvent *)event { - (void)scrollWheel:(NSEvent *)event {
if (!_platformWindow) return; if (!_platformWindow) return;
@@ -264,10 +221,7 @@ static void platform_macos_key_down_pw(PlatformWindow *pw, U16 keycode, NSEventM
_platformWindow->input.scroll_delta.y += dy; _platformWindow->input.scroll_delta.y += dy;
} }
- (BOOL)acceptsFirstMouse:(NSEvent *)event { - (BOOL)acceptsFirstMouse:(NSEvent *)event { (void)event; return YES; }
(void)event;
return YES;
}
@end @end

View File

@@ -3,8 +3,8 @@
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#include <malloc.h>
#include <windows.h> #include <windows.h>
#include <malloc.h>
struct PlatformWindow { struct PlatformWindow {
HWND hwnd; HWND hwnd;
@@ -143,7 +143,8 @@ PlatformWindow *platform_create_window(PlatformWindowDesc *desc) {
x, y, x, y,
rect.right - rect.left, rect.right - rect.left,
rect.bottom - rect.top, rect.bottom - rect.top,
parent_hwnd, nullptr, GetModuleHandleW(nullptr), nullptr); parent_hwnd, nullptr, GetModuleHandleW(nullptr), nullptr
);
_freea(wtitle); _freea(wtitle);

View File

@@ -30,8 +30,8 @@
#include "renderer/font_inter.gen.h" #include "renderer/font_inter.gen.h"
// Embedded SPIR-V shaders (generated at build time by glslc) // Embedded SPIR-V shaders (generated at build time by glslc)
#include "renderer/ui_frag.spv.h"
#include "renderer/ui_vert.spv.h" #include "renderer/ui_vert.spv.h"
#include "renderer/ui_frag.spv.h"
#define NUM_BACK_BUFFERS 2 #define NUM_BACK_BUFFERS 2
#define MAX_VERTICES (64 * 1024) #define MAX_VERTICES (64 * 1024)
@@ -172,9 +172,9 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type, VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT *data, const VkDebugUtilsMessengerCallbackDataEXT *data,
void *user_data) { void *user_data)
(void)type; {
(void)user_data; (void)type; (void)user_data;
if (severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { if (severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
OutputDebugStringA("VK: "); OutputDebugStringA("VK: ");
OutputDebugStringA(data->pMessage); OutputDebugStringA(data->pMessage);
@@ -220,7 +220,8 @@ static void end_one_shot(Renderer *r, VkCommandBuffer cb) {
static void transition_image(VkCommandBuffer cb, VkImage image, static void transition_image(VkCommandBuffer cb, VkImage image,
VkImageLayout old_layout, VkImageLayout new_layout, VkImageLayout old_layout, VkImageLayout new_layout,
VkAccessFlags src_access, VkAccessFlags dst_access, VkAccessFlags src_access, VkAccessFlags dst_access,
VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage) { VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage)
{
VkImageMemoryBarrier barrier = {0}; VkImageMemoryBarrier barrier = {0};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = old_layout; barrier.oldLayout = old_layout;
@@ -279,8 +280,11 @@ static B32 create_instance(Renderer *r) {
{ {
VkDebugUtilsMessengerCreateInfoEXT dbg = {0}; VkDebugUtilsMessengerCreateInfoEXT dbg = {0};
dbg.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; dbg.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
dbg.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; dbg.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
dbg.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
dbg.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
dbg.pfnUserCallback = vk_debug_callback; dbg.pfnUserCallback = vk_debug_callback;
PFN_vkCreateDebugUtilsMessengerEXT func = PFN_vkCreateDebugUtilsMessengerEXT func =
@@ -644,42 +648,15 @@ static B32 create_pipeline(Renderer *r) {
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attrs[9] = {}; VkVertexInputAttributeDescription attrs[9] = {};
attrs[0].location = 0; attrs[0].location = 0; attrs[0].binding = 0; attrs[0].format = VK_FORMAT_R32G32_SFLOAT; attrs[0].offset = offsetof(UIVertex, pos);
attrs[0].binding = 0; attrs[1].location = 1; attrs[1].binding = 0; attrs[1].format = VK_FORMAT_R32G32_SFLOAT; attrs[1].offset = offsetof(UIVertex, uv);
attrs[0].format = VK_FORMAT_R32G32_SFLOAT; attrs[2].location = 2; attrs[2].binding = 0; attrs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT; attrs[2].offset = offsetof(UIVertex, col);
attrs[0].offset = offsetof(UIVertex, pos); attrs[3].location = 3; attrs[3].binding = 0; attrs[3].format = VK_FORMAT_R32G32_SFLOAT; attrs[3].offset = offsetof(UIVertex, rect_min);
attrs[1].location = 1; attrs[4].location = 4; attrs[4].binding = 0; attrs[4].format = VK_FORMAT_R32G32_SFLOAT; attrs[4].offset = offsetof(UIVertex, rect_max);
attrs[1].binding = 0; attrs[5].location = 5; attrs[5].binding = 0; attrs[5].format = VK_FORMAT_R32G32B32A32_SFLOAT; attrs[5].offset = offsetof(UIVertex, corner_radii);
attrs[1].format = VK_FORMAT_R32G32_SFLOAT; attrs[6].location = 6; attrs[6].binding = 0; attrs[6].format = VK_FORMAT_R32_SFLOAT; attrs[6].offset = offsetof(UIVertex, border_thickness);
attrs[1].offset = offsetof(UIVertex, uv); attrs[7].location = 7; attrs[7].binding = 0; attrs[7].format = VK_FORMAT_R32_SFLOAT; attrs[7].offset = offsetof(UIVertex, softness);
attrs[2].location = 2; attrs[8].location = 8; attrs[8].binding = 0; attrs[8].format = VK_FORMAT_R32_SFLOAT; attrs[8].offset = offsetof(UIVertex, mode);
attrs[2].binding = 0;
attrs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attrs[2].offset = offsetof(UIVertex, col);
attrs[3].location = 3;
attrs[3].binding = 0;
attrs[3].format = VK_FORMAT_R32G32_SFLOAT;
attrs[3].offset = offsetof(UIVertex, rect_min);
attrs[4].location = 4;
attrs[4].binding = 0;
attrs[4].format = VK_FORMAT_R32G32_SFLOAT;
attrs[4].offset = offsetof(UIVertex, rect_max);
attrs[5].location = 5;
attrs[5].binding = 0;
attrs[5].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attrs[5].offset = offsetof(UIVertex, corner_radii);
attrs[6].location = 6;
attrs[6].binding = 0;
attrs[6].format = VK_FORMAT_R32_SFLOAT;
attrs[6].offset = offsetof(UIVertex, border_thickness);
attrs[7].location = 7;
attrs[7].binding = 0;
attrs[7].format = VK_FORMAT_R32_SFLOAT;
attrs[7].offset = offsetof(UIVertex, softness);
attrs[8].location = 8;
attrs[8].binding = 0;
attrs[8].format = VK_FORMAT_R32_SFLOAT;
attrs[8].offset = offsetof(UIVertex, mode);
VkPipelineVertexInputStateCreateInfo vertex_input = {0}; VkPipelineVertexInputStateCreateInfo vertex_input = {0};
vertex_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
@@ -723,7 +700,8 @@ static B32 create_pipeline(Renderer *r) {
blend_attach.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; blend_attach.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
blend_attach.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; blend_attach.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blend_attach.alphaBlendOp = VK_BLEND_OP_ADD; blend_attach.alphaBlendOp = VK_BLEND_OP_ADD;
blend_attach.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; blend_attach.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendStateCreateInfo blend = {0}; VkPipelineColorBlendStateCreateInfo blend = {0};
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
@@ -999,7 +977,8 @@ static void emit_quad(DrawBatch *batch,
F32 cr, F32 cg, F32 cb, F32 ca, F32 cr, F32 cg, F32 cb, F32 ca,
F32 rmin_x, F32 rmin_y, F32 rmax_x, F32 rmax_y, F32 rmin_x, F32 rmin_y, F32 rmax_x, F32 rmax_y,
F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl, F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl,
F32 border_thickness, F32 softness, F32 mode) { F32 border_thickness, F32 softness, F32 mode)
{
if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES) if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES)
return; return;
@@ -1009,54 +988,28 @@ static void emit_quad(DrawBatch *batch,
F32 px0 = x0, py0 = y0, px1 = x1, py1 = y1; F32 px0 = x0, py0 = y0, px1 = x1, py1 = y1;
if (mode < 0.5f) { if (mode < 0.5f) {
F32 pad = softness + 1.0f; F32 pad = softness + 1.0f;
px0 -= pad; px0 -= pad; py0 -= pad; px1 += pad; py1 += pad;
py0 -= pad;
px1 += pad;
py1 += pad;
} }
v[0].pos[0] = px0; v[0].pos[0] = px0; v[0].pos[1] = py0; v[0].uv[0] = u0; v[0].uv[1] = v0;
v[0].pos[1] = py0; v[1].pos[0] = px1; v[1].pos[1] = py0; v[1].uv[0] = u1; v[1].uv[1] = v0;
v[0].uv[0] = u0; v[2].pos[0] = px1; v[2].pos[1] = py1; v[2].uv[0] = u1; v[2].uv[1] = v1;
v[0].uv[1] = v0; v[3].pos[0] = px0; v[3].pos[1] = py1; v[3].uv[0] = u0; v[3].uv[1] = v1;
v[1].pos[0] = px1;
v[1].pos[1] = py0;
v[1].uv[0] = u1;
v[1].uv[1] = v0;
v[2].pos[0] = px1;
v[2].pos[1] = py1;
v[2].uv[0] = u1;
v[2].uv[1] = v1;
v[3].pos[0] = px0;
v[3].pos[1] = py1;
v[3].uv[0] = u0;
v[3].uv[1] = v1;
for (S32 i = 0; i < 4; i++) { for (S32 i = 0; i < 4; i++) {
v[i].col[0] = cr; v[i].col[0] = cr; v[i].col[1] = cg; v[i].col[2] = cb; v[i].col[3] = ca;
v[i].col[1] = cg; v[i].rect_min[0] = rmin_x; v[i].rect_min[1] = rmin_y;
v[i].col[2] = cb; v[i].rect_max[0] = rmax_x; v[i].rect_max[1] = rmax_y;
v[i].col[3] = ca; v[i].corner_radii[0] = cr_tl; v[i].corner_radii[1] = cr_tr;
v[i].rect_min[0] = rmin_x; v[i].corner_radii[2] = cr_br; v[i].corner_radii[3] = cr_bl;
v[i].rect_min[1] = rmin_y;
v[i].rect_max[0] = rmax_x;
v[i].rect_max[1] = rmax_y;
v[i].corner_radii[0] = cr_tl;
v[i].corner_radii[1] = cr_tr;
v[i].corner_radii[2] = cr_br;
v[i].corner_radii[3] = cr_bl;
v[i].border_thickness = border_thickness; v[i].border_thickness = border_thickness;
v[i].softness = softness; v[i].softness = softness;
v[i].mode = mode; v[i].mode = mode;
} }
U32 *idx = &batch->indices[batch->index_count]; U32 *idx = &batch->indices[batch->index_count];
idx[0] = base; idx[0] = base; idx[1] = base + 1; idx[2] = base + 2;
idx[1] = base + 1; idx[3] = base; idx[4] = base + 2; idx[5] = base + 3;
idx[2] = base + 2;
idx[3] = base;
idx[4] = base + 2;
idx[5] = base + 3;
batch->vertex_count += 4; batch->vertex_count += 4;
batch->index_count += 6; batch->index_count += 6;
@@ -1066,7 +1019,8 @@ static void emit_quad_rotated(DrawBatch *batch,
F32 x0, F32 y0, F32 x1, F32 y1, F32 x0, F32 y0, F32 x1, F32 y1,
F32 u0, F32 v0, F32 u1, F32 v1, F32 u0, F32 v0, F32 u1, F32 v1,
F32 cr, F32 cg, F32 cb, F32 ca, F32 cr, F32 cg, F32 cb, F32 ca,
F32 angle_rad) { F32 angle_rad)
{
if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES) if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES)
return; return;
@@ -1083,49 +1037,34 @@ static void emit_quad_rotated(DrawBatch *batch,
v[0].pos[0] = cx + dx0 * cosA - dy0 * sinA; v[0].pos[0] = cx + dx0 * cosA - dy0 * sinA;
v[0].pos[1] = cy + dx0 * sinA + dy0 * cosA; v[0].pos[1] = cy + dx0 * sinA + dy0 * cosA;
v[0].uv[0] = u0; v[0].uv[0] = u0; v[0].uv[1] = v0;
v[0].uv[1] = v0;
v[1].pos[0] = cx + dx1 * cosA - dy0 * sinA; v[1].pos[0] = cx + dx1 * cosA - dy0 * sinA;
v[1].pos[1] = cy + dx1 * sinA + dy0 * cosA; v[1].pos[1] = cy + dx1 * sinA + dy0 * cosA;
v[1].uv[0] = u1; v[1].uv[0] = u1; v[1].uv[1] = v0;
v[1].uv[1] = v0;
v[2].pos[0] = cx + dx1 * cosA - dy1 * sinA; v[2].pos[0] = cx + dx1 * cosA - dy1 * sinA;
v[2].pos[1] = cy + dx1 * sinA + dy1 * cosA; v[2].pos[1] = cy + dx1 * sinA + dy1 * cosA;
v[2].uv[0] = u1; v[2].uv[0] = u1; v[2].uv[1] = v1;
v[2].uv[1] = v1;
v[3].pos[0] = cx + dx0 * cosA - dy1 * sinA; v[3].pos[0] = cx + dx0 * cosA - dy1 * sinA;
v[3].pos[1] = cy + dx0 * sinA + dy1 * cosA; v[3].pos[1] = cy + dx0 * sinA + dy1 * cosA;
v[3].uv[0] = u0; v[3].uv[0] = u0; v[3].uv[1] = v1;
v[3].uv[1] = v1;
for (S32 i = 0; i < 4; i++) { for (S32 i = 0; i < 4; i++) {
v[i].col[0] = cr; v[i].col[0] = cr; v[i].col[1] = cg; v[i].col[2] = cb; v[i].col[3] = ca;
v[i].col[1] = cg; v[i].rect_min[0] = 0; v[i].rect_min[1] = 0;
v[i].col[2] = cb; v[i].rect_max[0] = 0; v[i].rect_max[1] = 0;
v[i].col[3] = ca; v[i].corner_radii[0] = 0; v[i].corner_radii[1] = 0;
v[i].rect_min[0] = 0; v[i].corner_radii[2] = 0; v[i].corner_radii[3] = 0;
v[i].rect_min[1] = 0;
v[i].rect_max[0] = 0;
v[i].rect_max[1] = 0;
v[i].corner_radii[0] = 0;
v[i].corner_radii[1] = 0;
v[i].corner_radii[2] = 0;
v[i].corner_radii[3] = 0;
v[i].border_thickness = 0; v[i].border_thickness = 0;
v[i].softness = 0; v[i].softness = 0;
v[i].mode = 2.0f; v[i].mode = 2.0f;
} }
U32 *idx = &batch->indices[batch->index_count]; U32 *idx = &batch->indices[batch->index_count];
idx[0] = base; idx[0] = base; idx[1] = base + 1; idx[2] = base + 2;
idx[1] = base + 1; idx[3] = base; idx[4] = base + 2; idx[5] = base + 3;
idx[2] = base + 2;
idx[3] = base;
idx[4] = base + 2;
idx[5] = base + 3;
batch->vertex_count += 4; batch->vertex_count += 4;
batch->index_count += 6; batch->index_count += 6;
@@ -1135,7 +1074,8 @@ static void emit_rect(DrawBatch *batch,
F32 x0, F32 y0, F32 x1, F32 y1, F32 x0, F32 y0, F32 x1, F32 y1,
F32 cr, F32 cg, F32 cb, F32 ca, F32 cr, F32 cg, F32 cb, F32 ca,
F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl, F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl,
F32 border_thickness, F32 softness) { F32 border_thickness, F32 softness)
{
emit_quad(batch, x0, y0, x1, y1, emit_quad(batch, x0, y0, x1, y1,
0, 0, 0, 0, 0, 0, 0, 0,
cr, cg, cb, ca, cr, cg, cb, ca,
@@ -1149,7 +1089,8 @@ static void emit_rect_vgradient(DrawBatch *batch,
F32 tr, F32 tg, F32 tb, F32 ta, F32 tr, F32 tg, F32 tb, F32 ta,
F32 br, F32 bg, F32 bb_, F32 ba, F32 br, F32 bg, F32 bb_, F32 ba,
F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl, F32 cr_tl, F32 cr_tr, F32 cr_br, F32 cr_bl,
F32 softness) { F32 softness)
{
if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES) if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES)
return; return;
@@ -1159,61 +1100,29 @@ static void emit_rect_vgradient(DrawBatch *batch,
F32 pad = softness + 1.0f; F32 pad = softness + 1.0f;
F32 px0 = x0 - pad, py0 = y0 - pad, px1 = x1 + pad, py1 = y1 + pad; F32 px0 = x0 - pad, py0 = y0 - pad, px1 = x1 + pad, py1 = y1 + pad;
v[0].pos[0] = px0; v[0].pos[0] = px0; v[0].pos[1] = py0; v[0].uv[0] = 0; v[0].uv[1] = 0;
v[0].pos[1] = py0; v[1].pos[0] = px1; v[1].pos[1] = py0; v[1].uv[0] = 0; v[1].uv[1] = 0;
v[0].uv[0] = 0; v[2].pos[0] = px1; v[2].pos[1] = py1; v[2].uv[0] = 0; v[2].uv[1] = 0;
v[0].uv[1] = 0; v[3].pos[0] = px0; v[3].pos[1] = py1; v[3].uv[0] = 0; v[3].uv[1] = 0;
v[1].pos[0] = px1;
v[1].pos[1] = py0;
v[1].uv[0] = 0;
v[1].uv[1] = 0;
v[2].pos[0] = px1;
v[2].pos[1] = py1;
v[2].uv[0] = 0;
v[2].uv[1] = 0;
v[3].pos[0] = px0;
v[3].pos[1] = py1;
v[3].uv[0] = 0;
v[3].uv[1] = 0;
v[0].col[0] = tr; v[0].col[0] = tr; v[0].col[1] = tg; v[0].col[2] = tb; v[0].col[3] = ta;
v[0].col[1] = tg; v[1].col[0] = tr; v[1].col[1] = tg; v[1].col[2] = tb; v[1].col[3] = ta;
v[0].col[2] = tb; v[2].col[0] = br; v[2].col[1] = bg; v[2].col[2] = bb_; v[2].col[3] = ba;
v[0].col[3] = ta; v[3].col[0] = br; v[3].col[1] = bg; v[3].col[2] = bb_; v[3].col[3] = ba;
v[1].col[0] = tr;
v[1].col[1] = tg;
v[1].col[2] = tb;
v[1].col[3] = ta;
v[2].col[0] = br;
v[2].col[1] = bg;
v[2].col[2] = bb_;
v[2].col[3] = ba;
v[3].col[0] = br;
v[3].col[1] = bg;
v[3].col[2] = bb_;
v[3].col[3] = ba;
for (S32 i = 0; i < 4; i++) { for (S32 i = 0; i < 4; i++) {
v[i].rect_min[0] = x0; v[i].rect_min[0] = x0; v[i].rect_min[1] = y0;
v[i].rect_min[1] = y0; v[i].rect_max[0] = x1; v[i].rect_max[1] = y1;
v[i].rect_max[0] = x1; v[i].corner_radii[0] = cr_tl; v[i].corner_radii[1] = cr_tr;
v[i].rect_max[1] = y1; v[i].corner_radii[2] = cr_br; v[i].corner_radii[3] = cr_bl;
v[i].corner_radii[0] = cr_tl;
v[i].corner_radii[1] = cr_tr;
v[i].corner_radii[2] = cr_br;
v[i].corner_radii[3] = cr_bl;
v[i].border_thickness = 0; v[i].border_thickness = 0;
v[i].softness = softness; v[i].softness = softness;
v[i].mode = 0; v[i].mode = 0;
} }
U32 *idx = &batch->indices[batch->index_count]; U32 *idx = &batch->indices[batch->index_count];
idx[0] = base; idx[0] = base; idx[1] = base + 1; idx[2] = base + 2;
idx[1] = base + 1; idx[3] = base; idx[4] = base + 2; idx[5] = base + 3;
idx[2] = base + 2;
idx[3] = base;
idx[4] = base + 2;
idx[5] = base + 3;
batch->vertex_count += 4; batch->vertex_count += 4;
batch->index_count += 6; batch->index_count += 6;
@@ -1221,7 +1130,8 @@ static void emit_rect_vgradient(DrawBatch *batch,
static void emit_text_glyphs(DrawBatch *batch, Renderer *r, static void emit_text_glyphs(DrawBatch *batch, Renderer *r,
Clay_BoundingBox bbox, Clay_Color color, const char *text, S32 text_len, Clay_BoundingBox bbox, Clay_Color color, const char *text, S32 text_len,
U16 font_size) { U16 font_size)
{
if (text_len == 0 || color.a < 0.1f) return; if (text_len == 0 || color.a < 0.1f) return;
F32 cr = color.r / 255.f; F32 cr = color.r / 255.f;
@@ -1269,7 +1179,8 @@ static void emit_text_glyphs(DrawBatch *batch, Renderer *r,
// Flush helper // Flush helper
static void flush_batch(Renderer *r, DrawBatch *batch, U32 buf_idx, static void flush_batch(Renderer *r, DrawBatch *batch, U32 buf_idx,
U32 *flush_index_start, VkDescriptorSet tex_set) { U32 *flush_index_start, VkDescriptorSet tex_set)
{
U32 draw_index_count = batch->index_count - *flush_index_start; U32 draw_index_count = batch->index_count - *flush_index_start;
if (draw_index_count == 0) return; if (draw_index_count == 0) return;
@@ -1817,14 +1728,8 @@ void renderer_resize(Renderer *r, S32 width, S32 height) {
// Clean up old swap chain resources // Clean up old swap chain resources
for (U32 i = 0; i < NUM_BACK_BUFFERS; i++) { for (U32 i = 0; i < NUM_BACK_BUFFERS; i++) {
if (r->framebuffers[i]) { if (r->framebuffers[i]) { vkDestroyFramebuffer(r->device, r->framebuffers[i], NULL); r->framebuffers[i] = VK_NULL_HANDLE; }
vkDestroyFramebuffer(r->device, r->framebuffers[i], NULL); if (r->swap_chain_views[i]) { vkDestroyImageView(r->device, r->swap_chain_views[i], NULL); r->swap_chain_views[i] = VK_NULL_HANDLE; }
r->framebuffers[i] = VK_NULL_HANDLE;
}
if (r->swap_chain_views[i]) {
vkDestroyImageView(r->device, r->swap_chain_views[i], NULL);
r->swap_chain_views[i] = VK_NULL_HANDLE;
}
} }
VkSwapchainKHR old_swap = r->swap_chain; VkSwapchainKHR old_swap = r->swap_chain;
@@ -1850,14 +1755,8 @@ void renderer_set_font_scale(Renderer *r, F32 scale) {
F32 target_size = 22.0f * scale; F32 target_size = 22.0f * scale;
if (fabsf(target_size - r->font_atlas_size) < 0.1f) return; if (fabsf(target_size - r->font_atlas_size) < 0.1f) return;
vkDeviceWaitIdle(r->device); vkDeviceWaitIdle(r->device);
if (r->font_view) { if (r->font_view) { vkDestroyImageView(r->device, r->font_view, NULL); r->font_view = VK_NULL_HANDLE; }
vkDestroyImageView(r->device, r->font_view, NULL); if (r->font_image) { vmaDestroyImage(r->allocator, r->font_image, r->font_alloc); r->font_image = VK_NULL_HANDLE; }
r->font_view = VK_NULL_HANDLE;
}
if (r->font_image) {
vmaDestroyImage(r->allocator, r->font_image, r->font_alloc);
r->font_image = VK_NULL_HANDLE;
}
create_font_atlas(r, target_size); create_font_atlas(r, target_size);
} }

View File

@@ -200,7 +200,8 @@ void ui_destroy(UI_Context *ctx) {
void ui_begin_frame(UI_Context *ctx, F32 viewport_w, F32 viewport_h, void ui_begin_frame(UI_Context *ctx, F32 viewport_w, F32 viewport_h,
Vec2F32 mouse_pos, B32 mouse_down, Vec2F32 mouse_pos, B32 mouse_down,
Vec2F32 scroll_delta, F32 dt) { Vec2F32 scroll_delta, F32 dt)
{
g_measure_ctx = ctx; g_measure_ctx = ctx;
Clay_SetCurrentContext(ctx->clay_ctx); Clay_SetCurrentContext(ctx->clay_ctx);
Clay_SetLayoutDimensions(Clay_Dimensions{viewport_w, viewport_h}); Clay_SetLayoutDimensions(Clay_Dimensions{viewport_w, viewport_h});

View File

@@ -32,7 +32,8 @@ void ui_piano(UI_PianoState *state, MidiEngine *midi, F32 avail_w, F32 avail_h)
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Compute black key size proportional to white keys // Compute black key size proportional to white keys
F32 black_key_h = avail_h * PIANO_BLACK_H_PCT; F32 black_key_h = avail_h * PIANO_BLACK_H_PCT;
if (black_key_h < uis(20)) black_key_h = uis(20); if (black_key_h < uis(20)) black_key_h = uis(20);
@@ -60,7 +61,9 @@ void ui_piano(UI_PianoState *state, MidiEngine *midi, F32 avail_w, F32 avail_h)
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
}, },
.backgroundColor = bg, .border = { .color = { 190, 190, 190, 255 }, .width = { .right = 1 } }, ) {} .backgroundColor = bg,
.border = { .color = {190, 190, 190, 255}, .width = { .right = 1 } },
) {}
} }
// Black keys (floating, attached to left white key) // Black keys (floating, attached to left white key)
@@ -86,7 +89,9 @@ void ui_piano(UI_PianoState *state, MidiEngine *midi, F32 avail_w, F32 avail_h)
.height = CLAY_SIZING_FIXED(black_key_h), .height = CLAY_SIZING_FIXED(black_key_h),
}, },
}, },
.backgroundColor = bg, .cornerRadius = { .topLeft = 0, .topRight = 0, .bottomLeft = uis(2), .bottomRight = uis(2) }, .floating = { .backgroundColor = bg,
.cornerRadius = { .topLeft = 0, .topRight = 0, .bottomLeft = uis(2), .bottomRight = uis(2) },
.floating = {
.parentId = parent_wkey.id, .parentId = parent_wkey.id,
.zIndex = 100, .zIndex = 100,
.attachPoints = { .attachPoints = {
@@ -94,7 +99,8 @@ void ui_piano(UI_PianoState *state, MidiEngine *midi, F32 avail_w, F32 avail_h)
.parent = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP,
}, },
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
}, ) {} },
) {}
} }
} }
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "midi/midi.h"
#include "ui/ui_core.h" #include "ui/ui_core.h"
#include "midi/midi.h"
#define PIANO_FIRST_NOTE 21 // A0 #define PIANO_FIRST_NOTE 21 // A0
#define PIANO_LAST_NOTE 108 // C8 #define PIANO_LAST_NOTE 108 // C8

View File

@@ -23,10 +23,7 @@ PopupWindow *popup_open(PlatformWindow *parent_window, Renderer *parent_renderer
// Find free slot // Find free slot
PopupWindow *popup = nullptr; PopupWindow *popup = nullptr;
for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++) { for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++) {
if (!g_popups[i].alive) { if (!g_popups[i].alive) { popup = &g_popups[i]; break; }
popup = &g_popups[i];
break;
}
} }
if (!popup) return nullptr; if (!popup) return nullptr;
@@ -140,7 +137,8 @@ void popup_do_frame(PopupWindow *popup, F32 dt) {
.childGap = uip(8), .childGap = uip(8),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = g_theme.bg_medium, ) { .backgroundColor = g_theme.bg_medium,
) {
if (popup->content_fn) { if (popup->content_fn) {
popup->content_fn(popup->content_user_data); popup->content_fn(popup->content_user_data);
} }

View File

@@ -1,8 +1,8 @@
#pragma once #pragma once
#include "platform/platform.h"
#include "renderer/renderer.h"
#include "ui/ui_core.h" #include "ui/ui_core.h"
#include "ui/ui_widgets.h" #include "ui/ui_widgets.h"
#include "platform/platform.h"
#include "renderer/renderer.h"
#define MAX_POPUP_WINDOWS 4 #define MAX_POPUP_WINDOWS 4

View File

@@ -5,10 +5,10 @@
// AFTER a CLAY() block, use Clay_PointerOver(elementId). // AFTER a CLAY() block, use Clay_PointerOver(elementId).
#include "ui/ui_widgets.h" #include "ui/ui_widgets.h"
#include <math.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <math.h>
UI_WidgetState g_wstate = {}; UI_WidgetState g_wstate = {};
@@ -82,7 +82,9 @@ static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
.height = CLAY_SIZING_FIXED(bb.height + expand*2), .height = CLAY_SIZING_FIXED(bb.height + expand*2),
}, },
}, },
.backgroundColor = { 0, 0, 0, per_layer }, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS + expand), .floating = { .backgroundColor = {0, 0, 0, per_layer},
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS + expand),
.floating = {
.offset = { bb.x - expand + ox, bb.y - expand + oy }, .offset = { bb.x - expand + ox, bb.y - expand + oy },
.zIndex = z, .zIndex = z,
.attachPoints = { .attachPoints = {
@@ -90,7 +92,8 @@ static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
.parent = CLAY_ATTACH_POINT_LEFT_TOP, .parent = CLAY_ATTACH_POINT_LEFT_TOP,
}, },
.attachTo = CLAY_ATTACH_TO_ROOT, .attachTo = CLAY_ATTACH_TO_ROOT,
}) {} }
) {}
} else { } else {
CLAY(shadow_eid, CLAY(shadow_eid,
.layout = { .layout = {
@@ -99,7 +102,9 @@ static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
.height = CLAY_SIZING_FIXED(bb.height + expand*2), .height = CLAY_SIZING_FIXED(bb.height + expand*2),
}, },
}, },
.backgroundColor = { 0, 0, 0, per_layer }, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS + expand), .floating = { .backgroundColor = {0, 0, 0, per_layer},
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS + expand),
.floating = {
.offset = { -expand + ox, -expand + oy }, .offset = { -expand + ox, -expand + oy },
.parentId = parent_id, .parentId = parent_id,
.zIndex = z, .zIndex = z,
@@ -108,7 +113,8 @@ static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
.parent = parent_attach, .parent = parent_attach,
}, },
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
}) {} }
) {}
} }
} }
} }
@@ -228,7 +234,8 @@ void ui_icon(UI_IconID icon, F32 size, Clay_Color color) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(size), .height = CLAY_SIZING_FIXED(size) }, .sizing = { .width = CLAY_SIZING_FIXED(size), .height = CLAY_SIZING_FIXED(size) },
}, },
.custom = { .customData = data }) {} .custom = { .customData = data }
) {}
} }
//////////////////////////////// ////////////////////////////////
@@ -240,7 +247,8 @@ void ui_label(const char *id, const char *text) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
.padding = { 0, 0, uip(2), uip(2) }, .padding = { 0, 0, uip(2), uip(2) },
}) { }
) {
CLAY_TEXT(clay_str(text), &g_widget_text_config); CLAY_TEXT(clay_str(text), &g_widget_text_config);
} }
} }
@@ -265,7 +273,10 @@ B32 ui_button(const char *id, const char *text) {
.padding = { uip(12), uip(12), uip(1), 0 }, .padding = { uip(12), uip(12), uip(1), 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = base, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .custom = { .customData = grad }, ) { .backgroundColor = base,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.custom = { .customData = grad },
) {
CLAY_TEXT(clay_str(text), &g_widget_text_config_btn); CLAY_TEXT(clay_str(text), &g_widget_text_config_btn);
} }
@@ -288,7 +299,8 @@ B32 ui_checkbox(const char *id, const char *label, B32 *value) {
.childGap = uip(8), .childGap = uip(8),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Box // Box
Clay_Color box_bg = *value ? g_theme.accent : g_theme.bg_dark; Clay_Color box_bg = *value ? g_theme.accent : g_theme.bg_dark;
if (hovered) { if (hovered) {
@@ -299,7 +311,10 @@ B32 ui_checkbox(const char *id, const char *label, B32 *value) {
.sizing = { .width = CLAY_SIZING_FIXED(WIDGET_CHECKBOX_SIZE), .height = CLAY_SIZING_FIXED(WIDGET_CHECKBOX_SIZE) }, .sizing = { .width = CLAY_SIZING_FIXED(WIDGET_CHECKBOX_SIZE), .height = CLAY_SIZING_FIXED(WIDGET_CHECKBOX_SIZE) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = box_bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } }) { .backgroundColor = box_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } }
) {
if (*value) { if (*value) {
ui_icon(UI_ICON_CHECK, WIDGET_CHECKBOX_SIZE * 0.75f, g_theme.button_text); ui_icon(UI_ICON_CHECK, WIDGET_CHECKBOX_SIZE * 0.75f, g_theme.button_text);
} }
@@ -329,7 +344,8 @@ B32 ui_radio_group(const char *id, const char **options, S32 count, S32 *selecte
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.childGap = uip(4), .childGap = uip(4),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
for (S32 i = 0; i < count; i++) { for (S32 i = 0; i < count; i++) {
B32 is_selected = (*selected == i); B32 is_selected = (*selected == i);
Clay_ElementId row_id = WIDI(id, i + 100); Clay_ElementId row_id = WIDI(id, i + 100);
@@ -341,7 +357,8 @@ B32 ui_radio_group(const char *id, const char **options, S32 count, S32 *selecte
.childGap = uip(8), .childGap = uip(8),
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}) { }
) {
// Radio circle // Radio circle
Clay_Color dot_bg = is_selected ? g_theme.accent : g_theme.bg_dark; Clay_Color dot_bg = is_selected ? g_theme.accent : g_theme.bg_dark;
if (row_hovered) { if (row_hovered) {
@@ -352,13 +369,18 @@ B32 ui_radio_group(const char *id, const char **options, S32 count, S32 *selecte
.sizing = { .width = CLAY_SIZING_FIXED(WIDGET_RADIO_OUTER), .height = CLAY_SIZING_FIXED(WIDGET_RADIO_OUTER) }, .sizing = { .width = CLAY_SIZING_FIXED(WIDGET_RADIO_OUTER), .height = CLAY_SIZING_FIXED(WIDGET_RADIO_OUTER) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = dot_bg, .cornerRadius = CLAY_CORNER_RADIUS(uis(8)), .border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } }) { .backgroundColor = dot_bg,
.cornerRadius = CLAY_CORNER_RADIUS(uis(8)),
.border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } }
) {
if (is_selected) { if (is_selected) {
CLAY(WIDI(id, i + 300), CLAY(WIDI(id, i + 300),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(WIDGET_RADIO_INNER), .height = CLAY_SIZING_FIXED(WIDGET_RADIO_INNER) }, .sizing = { .width = CLAY_SIZING_FIXED(WIDGET_RADIO_INNER), .height = CLAY_SIZING_FIXED(WIDGET_RADIO_INNER) },
}, },
.backgroundColor = g_theme.button_text, .cornerRadius = CLAY_CORNER_RADIUS(uis(4))) {} .backgroundColor = g_theme.button_text,
.cornerRadius = CLAY_CORNER_RADIUS(uis(4))
) {}
} }
} }
@@ -398,13 +420,8 @@ void ui_text_input_reset_display_bufs() {
static void text_input_get_sel(S32 *lo, S32 *hi) { static void text_input_get_sel(S32 *lo, S32 *hi) {
S32 a = g_wstate.sel_start; S32 a = g_wstate.sel_start;
S32 b = g_wstate.sel_end; S32 b = g_wstate.sel_end;
if (a <= b) { if (a <= b) { *lo = a; *hi = b; }
*lo = a; else { *lo = b; *hi = a; }
*hi = b;
} else {
*lo = b;
*hi = a;
}
} }
// Helper: true if there's an active selection // Helper: true if there's an active selection
@@ -543,10 +560,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
S32 clip_len = (S32)strlen(clip); S32 clip_len = (S32)strlen(clip);
// Filter to single line (stop at newline) // Filter to single line (stop at newline)
for (S32 i = 0; i < clip_len; i++) { for (S32 i = 0; i < clip_len; i++) {
if (clip[i] == '\n' || clip[i] == '\r') { if (clip[i] == '\n' || clip[i] == '\r') { clip_len = i; break; }
clip_len = i;
break;
}
} }
S32 space = buf_size - 1 - len; S32 space = buf_size - 1 - len;
if (clip_len > space) clip_len = space; if (clip_len > space) clip_len = space;
@@ -594,8 +608,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
break; break;
case PKEY_LEFT: case PKEY_LEFT:
if (text_input_has_sel()) { if (text_input_has_sel()) {
S32 lo, hi; S32 lo, hi; text_input_get_sel(&lo, &hi);
text_input_get_sel(&lo, &hi);
g_wstate.cursor_pos = lo; g_wstate.cursor_pos = lo;
} else if (g_wstate.cursor_pos > 0) { } else if (g_wstate.cursor_pos > 0) {
g_wstate.cursor_pos--; g_wstate.cursor_pos--;
@@ -606,8 +619,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
break; break;
case PKEY_RIGHT: case PKEY_RIGHT:
if (text_input_has_sel()) { if (text_input_has_sel()) {
S32 lo, hi; S32 lo, hi; text_input_get_sel(&lo, &hi);
text_input_get_sel(&lo, &hi);
g_wstate.cursor_pos = hi; g_wstate.cursor_pos = hi;
} else if (g_wstate.cursor_pos < len) { } else if (g_wstate.cursor_pos < len) {
g_wstate.cursor_pos++; g_wstate.cursor_pos++;
@@ -666,10 +678,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
// our ID was just added above. Find it and advance to next. // our ID was just added above. Find it and advance to next.
S32 my_idx = -1; S32 my_idx = -1;
for (S32 i = 0; i < g_wstate.text_input_count; i++) { for (S32 i = 0; i < g_wstate.text_input_count; i++) {
if (g_wstate.text_input_ids[i] == eid.id) { if (g_wstate.text_input_ids[i] == eid.id) { my_idx = i; break; }
my_idx = i;
break;
}
} }
if (my_idx >= 0) { if (my_idx >= 0) {
// Focus next (wrapping). But we might not have all inputs registered // Focus next (wrapping). But we might not have all inputs registered
@@ -723,7 +732,11 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .custom = { .customData = inset_grad }, .border = { .color = border_color, .width = { 1, 1, 1, 1 } }, ) { .backgroundColor = bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.custom = { .customData = inset_grad },
.border = { .color = border_color, .width = { 1, 1, 1, 1 } },
) {
if (len == 0 && !is_focused) { if (len == 0 && !is_focused) {
// Placeholder // Placeholder
CLAY_TEXT(CLAY_STRING("..."), &g_widget_text_config_dim); CLAY_TEXT(CLAY_STRING("..."), &g_widget_text_config_dim);
@@ -746,7 +759,8 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
}, },
.backgroundColor = g_theme.accent) { .backgroundColor = g_theme.accent
) {
CLAY_TEXT(clay_str(dbuf_sel), &g_widget_text_config_sel); CLAY_TEXT(clay_str(dbuf_sel), &g_widget_text_config_sel);
} }
} }
@@ -812,14 +826,11 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
while (lo < hi) { while (lo < hi) {
S32 mid = (lo + hi + 1) / 2; S32 mid = (lo + hi + 1) / 2;
Vec2F32 seg = ui_measure_text(current_label, mid, FONT_SIZE_NORMAL); Vec2F32 seg = ui_measure_text(current_label, mid, FONT_SIZE_NORMAL);
if (seg.x <= target_w) lo = mid; if (seg.x <= target_w) lo = mid; else hi = mid - 1;
else hi = mid - 1;
} }
if (lo + 3 < (S32)sizeof(dd_trunc_buf)) { if (lo + 3 < (S32)sizeof(dd_trunc_buf)) {
memcpy(dd_trunc_buf, current_label, lo); memcpy(dd_trunc_buf, current_label, lo);
dd_trunc_buf[lo] = '.'; dd_trunc_buf[lo] = '.'; dd_trunc_buf[lo+1] = '.'; dd_trunc_buf[lo+2] = '.';
dd_trunc_buf[lo + 1] = '.';
dd_trunc_buf[lo + 2] = '.';
dd_trunc_buf[lo+3] = '\0'; dd_trunc_buf[lo+3] = '\0';
display_label = dd_trunc_buf; display_label = dd_trunc_buf;
} }
@@ -839,11 +850,16 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = bg, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .custom = { .customData = dd_grad }, .border = { .color = is_open ? g_theme.accent : g_theme.border, .width = { 1, 1, 1, 1 } }, ) { .backgroundColor = bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.custom = { .customData = dd_grad },
.border = { .color = is_open ? g_theme.accent : g_theme.border, .width = { 1, 1, 1, 1 } },
) {
CLAY(text_eid, CLAY(text_eid,
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
}) { }
) {
CLAY_TEXT(clay_str(display_label), &g_widget_text_config); CLAY_TEXT(clay_str(display_label), &g_widget_text_config);
} }
@@ -851,7 +867,8 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(uis(20)), .height = CLAY_SIZING_FIXED(uis(20)) }, .sizing = { .width = CLAY_SIZING_FIXED(uis(20)), .height = CLAY_SIZING_FIXED(uis(20)) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}) { }
) {
ui_icon(UI_ICON_CHEVRON_DOWN, uis(12), g_theme.text_dim); ui_icon(UI_ICON_CHEVRON_DOWN, uis(12), g_theme.text_dim);
} }
} }
@@ -885,7 +902,9 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
.sizing = { .width = CLAY_SIZING_FIT(.min = header_width), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(.min = header_width), .height = CLAY_SIZING_FIT() },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS), .floating = { .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.floating = {
.parentId = eid.id, .parentId = eid.id,
.zIndex = 2000, .zIndex = 2000,
.attachPoints = { .attachPoints = {
@@ -894,7 +913,8 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
}, },
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
}, },
.border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } }, ) { .border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } },
) {
for (S32 i = 0; i < count; i++) { for (S32 i = 0; i < count; i++) {
B32 is_item_selected = (*selected == i); B32 is_item_selected = (*selected == i);
Clay_ElementId item_id = WIDI(id, i + 600); Clay_ElementId item_id = WIDI(id, i + 600);
@@ -904,18 +924,11 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
if (item_hovered) item_bg = g_theme.bg_lighter; if (item_hovered) item_bg = g_theme.bg_lighter;
Clay_TextElementConfig *item_text = (is_item_selected && !item_hovered) Clay_TextElementConfig *item_text = (is_item_selected && !item_hovered)
? &g_widget_text_config_btn ? &g_widget_text_config_btn : &g_widget_text_config;
: &g_widget_text_config;
Clay_CornerRadius item_radius = {}; Clay_CornerRadius item_radius = {};
if (i == 0) { if (i == 0) { item_radius.topLeft = CORNER_RADIUS; item_radius.topRight = CORNER_RADIUS; }
item_radius.topLeft = CORNER_RADIUS; if (i == count - 1) { item_radius.bottomLeft = CORNER_RADIUS; item_radius.bottomRight = CORNER_RADIUS; }
item_radius.topRight = CORNER_RADIUS;
}
if (i == count - 1) {
item_radius.bottomLeft = CORNER_RADIUS;
item_radius.bottomRight = CORNER_RADIUS;
}
CLAY(item_id, CLAY(item_id,
.layout = { .layout = {
@@ -923,7 +936,9 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
.padding = { uip(8), uip(8), 0, 0 }, .padding = { uip(8), uip(8), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = item_bg, .cornerRadius = item_radius) { .backgroundColor = item_bg,
.cornerRadius = item_radius
) {
CLAY_TEXT(clay_str(options[i]), item_text); CLAY_TEXT(clay_str(options[i]), item_text);
} }
@@ -940,10 +955,7 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
// Check if any item was clicked (already handled above) // Check if any item was clicked (already handled above)
B32 clicked_item = 0; B32 clicked_item = 0;
for (S32 i = 0; i < count; i++) { for (S32 i = 0; i < count; i++) {
if (Clay_PointerOver(WIDI(id, i + 600))) { if (Clay_PointerOver(WIDI(id, i + 600))) { clicked_item = 1; break; }
clicked_item = 1;
break;
}
} }
if (!clicked_item) { if (!clicked_item) {
g_wstate.open_dropdown_id = 0; g_wstate.open_dropdown_id = 0;
@@ -973,7 +985,9 @@ S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
.padding = { 0, 0, 0, 0 }, .padding = { 0, 0, 0, 0 },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = g_theme.bg_medium, .border = { .color = g_theme.border, .width = { .bottom = 1 } }, ) { .backgroundColor = g_theme.bg_medium,
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
) {
for (S32 i = 0; i < count; i++) { for (S32 i = 0; i < count; i++) {
Clay_ElementId tab_eid = Clay__HashStringWithOffset(id_str, (U32)i, 0); Clay_ElementId tab_eid = Clay__HashStringWithOffset(id_str, (U32)i, 0);
B32 is_active = (i == *selected); B32 is_active = (i == *selected);
@@ -988,7 +1002,9 @@ S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
.padding = { TAB_PADDING_H, TAB_PADDING_H, 0, uip(6) }, .padding = { TAB_PADDING_H, TAB_PADDING_H, 0, uip(6) },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.cornerRadius = { .topLeft = TAB_CORNER_RADIUS, .topRight = TAB_CORNER_RADIUS, .bottomLeft = 0, .bottomRight = 0 }, .custom = { .customData = &g_tab_gradient }, ) { .cornerRadius = { .topLeft = TAB_CORNER_RADIUS, .topRight = TAB_CORNER_RADIUS, .bottomLeft = 0, .bottomRight = 0 },
.custom = { .customData = &g_tab_gradient },
) {
CLAY_TEXT(lbl_str, &g_widget_text_config_tab); CLAY_TEXT(lbl_str, &g_widget_text_config_tab);
} }
} else { } else {
@@ -999,7 +1015,9 @@ S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
.padding = { TAB_PADDING_H, TAB_PADDING_H, 0, uip(6) }, .padding = { TAB_PADDING_H, TAB_PADDING_H, 0, uip(6) },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = bg, .cornerRadius = { .topLeft = TAB_CORNER_RADIUS, .topRight = TAB_CORNER_RADIUS, .bottomLeft = 0, .bottomRight = 0 }, ) { .backgroundColor = bg,
.cornerRadius = { .topLeft = TAB_CORNER_RADIUS, .topRight = TAB_CORNER_RADIUS, .bottomLeft = 0, .bottomRight = 0 },
) {
CLAY_TEXT(lbl_str, &g_widget_text_config_tab_inactive); CLAY_TEXT(lbl_str, &g_widget_text_config_tab_inactive);
} }
} }
@@ -1034,11 +1052,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
#define KE_HAS_SEL() (*esel0 != *esel1) #define KE_HAS_SEL() (*esel0 != *esel1)
#define KE_SEL_LO() (*esel0 < *esel1 ? *esel0 : *esel1) #define KE_SEL_LO() (*esel0 < *esel1 ? *esel0 : *esel1)
#define KE_SEL_HI() (*esel0 < *esel1 ? *esel1 : *esel0) #define KE_SEL_HI() (*esel0 < *esel1 ? *esel1 : *esel0)
#define KE_CLEAR_SEL() \ #define KE_CLEAR_SEL() do { *esel0 = *ecur; *esel1 = *ecur; } while(0)
do { \
*esel0 = *ecur; \
*esel1 = *ecur; \
} while (0)
auto ke_delete_sel = [&]() -> S32 { auto ke_delete_sel = [&]() -> S32 {
S32 lo = KE_SEL_LO(), hi = KE_SEL_HI(); S32 lo = KE_SEL_LO(), hi = KE_SEL_HI();
@@ -1054,19 +1068,13 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (ctrl) { if (ctrl) {
if (key == PKEY_A) { if (key == PKEY_A) {
*esel0 = 0; *esel0 = 0; *esel1 = elen; *ecur = elen; continue;
*esel1 = elen;
*ecur = elen;
continue;
} }
if (key == PKEY_C) { if (key == PKEY_C) {
if (KE_HAS_SEL()) { if (KE_HAS_SEL()) {
S32 lo = KE_SEL_LO(), hi = KE_SEL_HI(); S32 lo = KE_SEL_LO(), hi = KE_SEL_HI();
char tmp[32]; char tmp[32]; S32 n = hi - lo; if (n > 31) n = 31;
S32 n = hi - lo; memcpy(tmp, &ebuf[lo], n); tmp[n] = '\0';
if (n > 31) n = 31;
memcpy(tmp, &ebuf[lo], n);
tmp[n] = '\0';
platform_clipboard_set(tmp); platform_clipboard_set(tmp);
} }
continue; continue;
@@ -1074,11 +1082,8 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (key == PKEY_X) { if (key == PKEY_X) {
if (KE_HAS_SEL()) { if (KE_HAS_SEL()) {
S32 lo = KE_SEL_LO(), hi = KE_SEL_HI(); S32 lo = KE_SEL_LO(), hi = KE_SEL_HI();
char tmp[32]; char tmp[32]; S32 n = hi - lo; if (n > 31) n = 31;
S32 n = hi - lo; memcpy(tmp, &ebuf[lo], n); tmp[n] = '\0';
if (n > 31) n = 31;
memcpy(tmp, &ebuf[lo], n);
tmp[n] = '\0';
platform_clipboard_set(tmp); platform_clipboard_set(tmp);
elen = ke_delete_sel(); elen = ke_delete_sel();
} }
@@ -1089,8 +1094,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (clip) { if (clip) {
if (KE_HAS_SEL()) elen = ke_delete_sel(); if (KE_HAS_SEL()) elen = ke_delete_sel();
S32 clip_len = (S32)strlen(clip); S32 clip_len = (S32)strlen(clip);
char filtered[32]; char filtered[32]; S32 flen = 0;
S32 flen = 0;
for (S32 i = 0; i < clip_len && flen < 30; i++) { for (S32 i = 0; i < clip_len && flen < 30; i++) {
char c = clip[i]; char c = clip[i];
if ((c >= '0' && c <= '9') || c == '.' || c == '-') if ((c >= '0' && c <= '9') || c == '.' || c == '-')
@@ -1101,8 +1105,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (flen > 0) { if (flen > 0) {
memmove(&ebuf[*ecur + flen], &ebuf[*ecur], elen - *ecur + 1); memmove(&ebuf[*ecur + flen], &ebuf[*ecur], elen - *ecur + 1);
memcpy(&ebuf[*ecur], filtered, flen); memcpy(&ebuf[*ecur], filtered, flen);
*ecur += flen; *ecur += flen; elen += flen;
elen += flen;
} }
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} }
@@ -1111,40 +1114,29 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
continue; continue;
} }
if (key == PKEY_RETURN) { if (key == PKEY_RETURN) { commit = 1; }
commit = 1; else if (key == PKEY_ESCAPE) { cancel = 1; }
} else if (key == PKEY_ESCAPE) { else if (key == PKEY_BACKSPACE) {
cancel = 1; if (KE_HAS_SEL()) { elen = ke_delete_sel(); }
} else if (key == PKEY_BACKSPACE) { else if (*ecur > 0) {
if (KE_HAS_SEL()) {
elen = ke_delete_sel();
} else if (*ecur > 0) {
memmove(&ebuf[*ecur - 1], &ebuf[*ecur], elen - *ecur + 1); memmove(&ebuf[*ecur - 1], &ebuf[*ecur], elen - *ecur + 1);
(*ecur)--; (*ecur)--; elen--;
elen--;
} }
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} else if (key == PKEY_DELETE) { } else if (key == PKEY_DELETE) {
if (KE_HAS_SEL()) { if (KE_HAS_SEL()) { elen = ke_delete_sel(); }
elen = ke_delete_sel(); else if (*ecur < elen) {
} else if (*ecur < elen) {
memmove(&ebuf[*ecur], &ebuf[*ecur + 1], elen - *ecur); memmove(&ebuf[*ecur], &ebuf[*ecur + 1], elen - *ecur);
elen--; elen--;
} }
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} else if (key == PKEY_LEFT) { } else if (key == PKEY_LEFT) {
if (KE_HAS_SEL()) { if (KE_HAS_SEL()) { *ecur = KE_SEL_LO(); }
*ecur = KE_SEL_LO(); else if (*ecur > 0) { (*ecur)--; }
} else if (*ecur > 0) {
(*ecur)--;
}
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} else if (key == PKEY_RIGHT) { } else if (key == PKEY_RIGHT) {
if (KE_HAS_SEL()) { if (KE_HAS_SEL()) { *ecur = KE_SEL_HI(); }
*ecur = KE_SEL_HI(); else if (*ecur < elen) { (*ecur)++; }
} else if (*ecur < elen) {
(*ecur)++;
}
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} }
} }
@@ -1157,9 +1149,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (KE_HAS_SEL()) elen = ke_delete_sel(); if (KE_HAS_SEL()) elen = ke_delete_sel();
if (elen < 30) { if (elen < 30) {
memmove(&ebuf[*ecur + 1], &ebuf[*ecur], elen - *ecur + 1); memmove(&ebuf[*ecur + 1], &ebuf[*ecur], elen - *ecur + 1);
ebuf[*ecur] = (char)ch; ebuf[*ecur] = (char)ch; (*ecur)++; elen++;
(*ecur)++;
elen++;
} }
KE_CLEAR_SEL(); KE_CLEAR_SEL();
} }
@@ -1178,10 +1168,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (parsed < lo) parsed = lo; if (parsed < lo) parsed = lo;
if (parsed > max_val) parsed = max_val; if (parsed > max_val) parsed = max_val;
if (parsed != *value) { if (parsed != *value) { *value = parsed; *changed = 1; }
*value = parsed;
*changed = 1;
}
} }
g_wstate.knob_edit_id = 0; g_wstate.knob_edit_id = 0;
return 1; return 1;
@@ -1229,30 +1216,31 @@ static void value_edit_render(U32 hash, F32 width) {
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_LEFT_TO_RIGHT, .layoutDirection = CLAY_LEFT_TO_RIGHT,
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(uis(2)), .border = { .color = g_theme.accent, .width = { 1, 1, 1, 1 } }) { .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(uis(2)),
.border = { .color = g_theme.accent, .width = { 1, 1, 1, 1 } }
) {
if (has_sel) { if (has_sel) {
if (sel_lo > 0) { if (sel_lo > 0) {
S32 n = sel_lo; S32 n = sel_lo;
memcpy(ke_dbuf_before, ebuf, n); memcpy(ke_dbuf_before, ebuf, n); ke_dbuf_before[n] = '\0';
ke_dbuf_before[n] = '\0';
Clay_String s_before = { .length = n, .chars = ke_dbuf_before }; Clay_String s_before = { .length = n, .chars = ke_dbuf_before };
CLAY_TEXT(s_before, &edit_cfg); CLAY_TEXT(s_before, &edit_cfg);
} }
{ {
S32 n = sel_hi - sel_lo; S32 n = sel_hi - sel_lo;
memcpy(ke_dbuf_sel, &ebuf[sel_lo], n); memcpy(ke_dbuf_sel, &ebuf[sel_lo], n); ke_dbuf_sel[n] = '\0';
ke_dbuf_sel[n] = '\0';
Clay_String s_sel = { .length = n, .chars = ke_dbuf_sel }; Clay_String s_sel = { .length = n, .chars = ke_dbuf_sel };
CLAY(CLAY_IDI("ValEditSel", (S32)hash), CLAY(CLAY_IDI("ValEditSel", (S32)hash),
.layout = { .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() } }, .layout = { .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() } },
.backgroundColor = g_theme.accent) { .backgroundColor = g_theme.accent
) {
CLAY_TEXT(s_sel, &edit_sel_cfg); CLAY_TEXT(s_sel, &edit_sel_cfg);
} }
} }
if (sel_hi < elen) { if (sel_hi < elen) {
S32 n = elen - sel_hi; S32 n = elen - sel_hi;
memcpy(ke_dbuf_after, &ebuf[sel_hi], n); memcpy(ke_dbuf_after, &ebuf[sel_hi], n); ke_dbuf_after[n] = '\0';
ke_dbuf_after[n] = '\0';
Clay_String s_after = { .length = n, .chars = ke_dbuf_after }; Clay_String s_after = { .length = n, .chars = ke_dbuf_after };
CLAY_TEXT(s_after, &edit_cfg); CLAY_TEXT(s_after, &edit_cfg);
} }
@@ -1284,10 +1272,7 @@ static void value_edit_click_away(Clay_ElementId eid, F32 *value, F32 max_val, B
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (parsed < lo) parsed = lo; if (parsed < lo) parsed = lo;
if (parsed > max_val) parsed = max_val; if (parsed > max_val) parsed = max_val;
if (parsed != *value) { if (parsed != *value) { *value = parsed; *changed = 1; }
*value = parsed;
*changed = 1;
}
} }
g_wstate.knob_edit_id = 0; g_wstate.knob_edit_id = 0;
} }
@@ -1311,11 +1296,8 @@ static void value_edit_enter(U32 hash, F32 value, B32 is_signed) {
// Normalize a value to [0,1] range. // Normalize a value to [0,1] range.
static F32 value_normalize(F32 value, F32 max_val, B32 is_signed) { static F32 value_normalize(F32 value, F32 max_val, B32 is_signed) {
F32 n; F32 n;
if (is_signed) { if (is_signed) { n = (value + max_val) / (2.0f * max_val); }
n = (value + max_val) / (2.0f * max_val); else { n = value / max_val; }
} else {
n = value / max_val;
}
if (n < 0.0f) n = 0.0f; if (n < 0.0f) n = 0.0f;
if (n > 1.0f) n = 1.0f; if (n > 1.0f) n = 1.0f;
return n; return n;
@@ -1325,11 +1307,8 @@ static F32 value_normalize(F32 value, F32 max_val, B32 is_signed) {
static char *value_format_text(F32 value, B32 is_signed, S32 *out_len) { static char *value_format_text(F32 value, B32 is_signed, S32 *out_len) {
if (g_knob_text_buf_count >= UI_MAX_KNOB_TEXT_BUFS) return nullptr; if (g_knob_text_buf_count >= UI_MAX_KNOB_TEXT_BUFS) return nullptr;
char *buf = g_knob_text_bufs[g_knob_text_buf_count++]; char *buf = g_knob_text_bufs[g_knob_text_buf_count++];
if (is_signed) { if (is_signed) { *out_len = snprintf(buf, 32, "%+.1f", value); }
*out_len = snprintf(buf, 32, "%+.1f", value); else { *out_len = snprintf(buf, 32, "%.1f", value); }
} else {
*out_len = snprintf(buf, 32, "%.1f", value);
}
return buf; return buf;
} }
@@ -1368,10 +1347,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (new_val < lo) new_val = lo; if (new_val < lo) new_val = lo;
if (new_val > max_val) new_val = max_val; if (new_val > max_val) new_val = max_val;
if (new_val != *value) { if (new_val != *value) { *value = new_val; changed = 1; }
*value = new_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
angle_rad = (-135.0f + normalized * 270.0f) * deg_to_rad; angle_rad = (-135.0f + normalized * 270.0f) * deg_to_rad;
} }
@@ -1397,7 +1373,8 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
.childGap = WIDGET_KNOB_LABEL_GAP, .childGap = WIDGET_KNOB_LABEL_GAP,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
Clay_ElementId knob_eid = CLAY_IDI("KnobBg", (S32)knob_hash); Clay_ElementId knob_eid = CLAY_IDI("KnobBg", (S32)knob_hash);
B32 hovered = Clay_PointerOver(knob_eid); B32 hovered = Clay_PointerOver(knob_eid);
@@ -1406,7 +1383,9 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
.sizing = { .width = CLAY_SIZING_FIXED(knob_size), .height = CLAY_SIZING_FIXED(knob_size) }, .sizing = { .width = CLAY_SIZING_FIXED(knob_size), .height = CLAY_SIZING_FIXED(knob_size) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(knob_size / 2.0f)) { .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(knob_size / 2.0f)
) {
if (g_rotated_icon_pool_count < UI_MAX_ROTATED_ICONS_PER_FRAME) { if (g_rotated_icon_pool_count < UI_MAX_ROTATED_ICONS_PER_FRAME) {
S32 ri_idx = g_rotated_icon_pool_count; S32 ri_idx = g_rotated_icon_pool_count;
CustomRotatedIconData *rdata = &g_rotated_icon_pool[g_rotated_icon_pool_count++]; CustomRotatedIconData *rdata = &g_rotated_icon_pool[g_rotated_icon_pool_count++];
@@ -1420,7 +1399,8 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(icon_size), .height = CLAY_SIZING_FIXED(icon_size) }, .sizing = { .width = CLAY_SIZING_FIXED(icon_size), .height = CLAY_SIZING_FIXED(icon_size) },
}, },
.custom = { .customData = rdata }) {} .custom = { .customData = rdata }
) {}
} }
} }
@@ -1432,10 +1412,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
kd->last_click_frame = g_frame_number; kd->last_click_frame = g_frame_number;
if (is_double_click) { if (is_double_click) {
if (*value != default_val) { if (*value != default_val) { *value = default_val; changed = 1; }
*value = default_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
angle_rad = (-135.0f + normalized * 270.0f) * deg_to_rad; angle_rad = (-135.0f + normalized * 270.0f) * deg_to_rad;
kd->last_click_id = 0; kd->last_click_id = 0;
@@ -1465,7 +1442,8 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
.sizing = { .width = CLAY_SIZING_FIXED(knob_size), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIXED(knob_size), .height = CLAY_SIZING_FIT() },
.padding = { uip(2), uip(2), uip(1), uip(1) }, .padding = { uip(2), uip(2), uip(1), uip(1) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
CLAY_TEXT(val_str, &knob_val_cfg); CLAY_TEXT(val_str, &knob_val_cfg);
} }
@@ -1514,10 +1492,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (new_val < lo) new_val = lo; if (new_val < lo) new_val = lo;
if (new_val > max_val) new_val = max_val; if (new_val > max_val) new_val = max_val;
if (new_val != *value) { if (new_val != *value) { *value = new_val; changed = 1; }
*value = new_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
} }
@@ -1545,7 +1520,8 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.childGap = WIDGET_KNOB_LABEL_GAP, .childGap = WIDGET_KNOB_LABEL_GAP,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Label // Label
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim); CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
@@ -1557,13 +1533,16 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(thumb_h) }, .sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(thumb_h) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
}) { }
) {
// Visible track (centered inside hit area) // Visible track (centered inside hit area)
CLAY(CLAY_IDI("SlHTrack", (S32)hash), CLAY(CLAY_IDI("SlHTrack", (S32)hash),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) }, .sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(track_h / 2.0f)) { .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(track_h / 2.0f)
) {
// Fill bar // Fill bar
F32 fill_w = normalized * track_w; F32 fill_w = normalized * track_w;
if (fill_w < 1.0f) fill_w = 1.0f; if (fill_w < 1.0f) fill_w = 1.0f;
@@ -1571,7 +1550,9 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(fill_w), .height = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_FIXED(fill_w), .height = CLAY_SIZING_GROW() },
}, },
.backgroundColor = fill_color, .cornerRadius = CLAY_CORNER_RADIUS(track_h / 2.0f)) {} .backgroundColor = fill_color,
.cornerRadius = CLAY_CORNER_RADIUS(track_h / 2.0f)
) {}
} }
// Floating icon thumb (attached to hit area) // Floating icon thumb (attached to hit area)
@@ -1598,7 +1579,8 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, },
.custom = { .customData = idata }, ) {} .custom = { .customData = idata },
) {}
} }
} }
@@ -1610,10 +1592,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
kd->last_click_frame = g_frame_number; kd->last_click_frame = g_frame_number;
if (is_double_click) { if (is_double_click) {
if (*value != default_val) { if (*value != default_val) { *value = default_val; changed = 1; }
*value = default_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
kd->last_click_id = 0; kd->last_click_id = 0;
} else { } else {
@@ -1642,7 +1621,8 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIT() },
.padding = { uip(2), uip(2), uip(1), uip(1) }, .padding = { uip(2), uip(2), uip(1), uip(1) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
CLAY_TEXT(val_str, &sl_val_cfg); CLAY_TEXT(val_str, &sl_val_cfg);
} }
@@ -1688,10 +1668,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (new_val < lo) new_val = lo; if (new_val < lo) new_val = lo;
if (new_val > max_val) new_val = max_val; if (new_val > max_val) new_val = max_val;
if (new_val != *value) { if (new_val != *value) { *value = new_val; changed = 1; }
*value = new_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
} }
@@ -1719,7 +1696,8 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.childGap = WIDGET_KNOB_LABEL_GAP, .childGap = WIDGET_KNOB_LABEL_GAP,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Label // Label
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim); CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
@@ -1731,14 +1709,17 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(track_h) }, .sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(track_h) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
// Visible track (centered inside hit area) // Visible track (centered inside hit area)
CLAY(CLAY_IDI("SlVTrack", (S32)hash), CLAY(CLAY_IDI("SlVTrack", (S32)hash),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) }, .sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
.childAlignment = { .y = CLAY_ALIGN_Y_BOTTOM }, .childAlignment = { .y = CLAY_ALIGN_Y_BOTTOM },
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)) { .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)
) {
// Fill bar (from bottom) // Fill bar (from bottom)
F32 fill_h = normalized * track_h; F32 fill_h = normalized * track_h;
if (fill_h < 1.0f) fill_h = 1.0f; if (fill_h < 1.0f) fill_h = 1.0f;
@@ -1746,7 +1727,9 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(fill_h) }, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(fill_h) },
}, },
.backgroundColor = fill_color, .cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)) {} .backgroundColor = fill_color,
.cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)
) {}
} }
// Floating icon thumb (attached to hit area) // Floating icon thumb (attached to hit area)
@@ -1773,7 +1756,8 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, },
.custom = { .customData = idata }, ) {} .custom = { .customData = idata },
) {}
} }
} }
@@ -1785,10 +1769,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
kd->last_click_frame = g_frame_number; kd->last_click_frame = g_frame_number;
if (is_double_click) { if (is_double_click) {
if (*value != default_val) { if (*value != default_val) { *value = default_val; changed = 1; }
*value = default_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
kd->last_click_id = 0; kd->last_click_id = 0;
} else { } else {
@@ -1817,7 +1798,8 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.padding = { uip(2), uip(2), uip(1), uip(1) }, .padding = { uip(2), uip(2), uip(1), uip(1) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
CLAY_TEXT(val_str, &sl_val_cfg); CLAY_TEXT(val_str, &sl_val_cfg);
} }
@@ -1863,10 +1845,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
F32 lo = is_signed ? -max_val : 0.0f; F32 lo = is_signed ? -max_val : 0.0f;
if (new_val < lo) new_val = lo; if (new_val < lo) new_val = lo;
if (new_val > max_val) new_val = max_val; if (new_val > max_val) new_val = max_val;
if (new_val != *value) { if (new_val != *value) { *value = new_val; changed = 1; }
*value = new_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
} }
@@ -1897,7 +1876,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.childGap = WIDGET_KNOB_LABEL_GAP, .childGap = WIDGET_KNOB_LABEL_GAP,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
}) { }
) {
// Label // Label
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim); CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
@@ -1909,13 +1889,16 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(track_h) }, .sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(track_h) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
// Visible track (centered inside hit area, empty) // Visible track (centered inside hit area, empty)
CLAY(CLAY_IDI("FdrTrack", (S32)hash), CLAY(CLAY_IDI("FdrTrack", (S32)hash),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) }, .sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
}, },
.backgroundColor = g_theme.bg_dark, .cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)) {} .backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)
) {}
// Tick marks on both sides of the track // Tick marks on both sides of the track
for (S32 i = 0; i <= num_ticks; i++) { for (S32 i = 0; i <= num_ticks; i++) {
@@ -1928,7 +1911,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) }, .sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
}, },
.backgroundColor = g_theme.text_dim, .floating = { .backgroundColor = g_theme.text_dim,
.floating = {
.offset = { .offset = {
.x = track_left - tw, .x = track_left - tw,
.y = tick_y, .y = tick_y,
@@ -1940,14 +1924,16 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, ) {} },
) {}
// Right tick // Right tick
CLAY(CLAY_IDI("FdrTkR", (S32)(hash * 100 + i)), CLAY(CLAY_IDI("FdrTkR", (S32)(hash * 100 + i)),
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) }, .sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
}, },
.backgroundColor = g_theme.text_dim, .floating = { .backgroundColor = g_theme.text_dim,
.floating = {
.offset = { .offset = {
.x = track_left + track_w, .x = track_left + track_w,
.y = tick_y, .y = tick_y,
@@ -1959,7 +1945,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, ) {} },
) {}
} }
// Floating fader cap (RGBA icon from asset SVG) // Floating fader cap (RGBA icon from asset SVG)
@@ -1985,7 +1972,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, },
.custom = { .customData = idata }, ) {} .custom = { .customData = idata },
) {}
// Color tint overlay on top of fader cap // Color tint overlay on top of fader cap
Clay_Color tint = g_theme.accent; Clay_Color tint = g_theme.accent;
@@ -1995,7 +1983,9 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.layout = { .layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) }, .sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
}, },
.backgroundColor = tint, .cornerRadius = CLAY_CORNER_RADIUS(cap_corner), .floating = { .backgroundColor = tint,
.cornerRadius = CLAY_CORNER_RADIUS(cap_corner),
.floating = {
.offset = { .x = 0, .y = cap_y }, .offset = { .x = 0, .y = cap_y },
.attachPoints = { .attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP, .element = CLAY_ATTACH_POINT_LEFT_TOP,
@@ -2004,7 +1994,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
}, ) {} },
) {}
} }
} }
@@ -2016,10 +2007,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
kd->last_click_frame = g_frame_number; kd->last_click_frame = g_frame_number;
if (is_double_click) { if (is_double_click) {
if (*value != default_val) { if (*value != default_val) { *value = default_val; changed = 1; }
*value = default_val;
changed = 1;
}
normalized = value_normalize(*value, max_val, is_signed); normalized = value_normalize(*value, max_val, is_signed);
kd->last_click_id = 0; kd->last_click_id = 0;
} else { } else {
@@ -2048,7 +2036,8 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() }, .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
.padding = { uip(2), uip(2), uip(1), uip(1) }, .padding = { uip(2), uip(2), uip(1), uip(1) },
.childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}) { }
) {
CLAY_TEXT(val_str, &fdr_val_cfg); CLAY_TEXT(val_str, &fdr_val_cfg);
} }

View File

@@ -6,9 +6,9 @@
// The caller owns all data — the widget layer only stores transient UI state // The caller owns all data — the widget layer only stores transient UI state
// like which text field is focused or which dropdown is open. // like which text field is focused or which dropdown is open.
#include "platform/platform.h"
#include "ui/ui_core.h" #include "ui/ui_core.h"
#include "ui/ui_icons.h" #include "ui/ui_icons.h"
#include "platform/platform.h"
//////////////////////////////// ////////////////////////////////
// Widget state (global, managed by widget layer) // Widget state (global, managed by widget layer)