tweak palette sliders
This commit is contained in:
parent
4f36aaf07a
commit
102bb6dc36
@ -385,6 +385,15 @@ Vec2 NormVec2(Vec2 a)
|
||||
return Vec2WithLen(a, 1.f);
|
||||
}
|
||||
|
||||
//- Clamp
|
||||
|
||||
Vec2 ClampVec2(Vec2 v, Rng2 r)
|
||||
{
|
||||
Vec2 result = Zi;
|
||||
result.x = ClampF32(v.x, r.p0.x, r.p1.x);
|
||||
result.y = ClampF32(v.y, r.p0.y, r.p1.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
//- Dot
|
||||
|
||||
|
||||
@ -101,12 +101,14 @@ Struct(Vec4Array) { Vec4 *points; u64 count; };
|
||||
//- Rng1
|
||||
|
||||
Struct(Rng) { f32 min, max; };
|
||||
Struct(RngF64) { f64 min, max; };
|
||||
Struct(RngI32) { i32 min, max; };
|
||||
Struct(RngI64) { i64 min, max; };
|
||||
Struct(RngU32) { u32 min, max; };
|
||||
Struct(RngU64) { u64 min, max; };
|
||||
|
||||
#define RNG(min, max) (Rng) { (min), (max) }
|
||||
#define RNGF64(min, max) (RngF46) { (min), (max) }
|
||||
#define RNGI32(min, max) (RngI32) { (min), (max) }
|
||||
#define RNGI64(min, max) (RngI64) { (min), (max) }
|
||||
#define RNGU32(min, max) (RngU32) { (min), (max) }
|
||||
@ -115,12 +117,14 @@ Struct(RngU64) { u64 min, max; };
|
||||
//- Rng2
|
||||
|
||||
Struct(Rng2) { Vec2 p0, p1; };
|
||||
Struct(Rng2F64) { Vec2F64 p0, p1; };
|
||||
Struct(Rng2I32) { Vec2I32 p0, p1; };
|
||||
Struct(Rng2I64) { Vec2I64 p0, p1; };
|
||||
Struct(Rng2U32) { Vec2U32 p0, p1; };
|
||||
Struct(Rng2U64) { Vec2U64 p0, p1; };
|
||||
|
||||
#define RNG2(p0, p1) (Rng2) { (p0), (p1) }
|
||||
#define RNG2F64(p0, p1) (Rng2F46) { (p0), (p1) }
|
||||
#define RNG2I32(p0, p1) (Rng2I32) { (p0), (p1) }
|
||||
#define RNG2I64(p0, p1) (Rng2I64) { (p0), (p1) }
|
||||
#define RNG2U32(p0, p1) (Rng2U32) { (p0), (p1) }
|
||||
@ -129,12 +133,14 @@ Struct(Rng2U64) { Vec2U64 p0, p1; };
|
||||
//- Rng3
|
||||
|
||||
Struct(Rng3) { Vec3 p0, p1; };
|
||||
Struct(Rng3F64) { Vec3F64 p0, p1; };
|
||||
Struct(Rng3I32) { Vec3I32 p0, p1; };
|
||||
Struct(Rng3I64) { Vec3I64 p0, p1; };
|
||||
Struct(Rng3U32) { Vec3U32 p0, p1; };
|
||||
Struct(Rng3U64) { Vec3U64 p0, p1; };
|
||||
|
||||
#define RNG3(p0, p1) (Rng3) { (p0), (p1) }
|
||||
#define RNG3F64(p0, p1) (Rng3F46) { (p0), (p1) }
|
||||
#define RNG3I32(p0, p1) (Rng3I32) { (p0), (p1) }
|
||||
#define RNG3I64(p0, p1) (Rng3I64) { (p0), (p1) }
|
||||
#define RNG3U32(p0, p1) (Rng3U32) { (p0), (p1) }
|
||||
@ -319,9 +325,12 @@ Vec2 SubVec2(Vec2 a, Vec2 b);
|
||||
f32 Vec2Len(Vec2 a);
|
||||
f32 Vec2LenSq(Vec2 a);
|
||||
Vec2 Vec2WithLen(Vec2 a, f32 len);
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 max);
|
||||
f32 Vec2Distance(Vec2 a, Vec2 b);
|
||||
Vec2 NormVec2(Vec2 a);
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 max);
|
||||
|
||||
//- Clamp
|
||||
Vec2 ClampVec2(Vec2 v, Rng2 r);
|
||||
|
||||
//- Dot
|
||||
f32 DotVec2(Vec2 a, Vec2 b);
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Conversion helpers
|
||||
|
||||
String StringFromBool(Arena *arena, b32 b)
|
||||
{
|
||||
return b ? PushString(arena, Lit("true")) : PushString(arena, Lit("false"));
|
||||
}
|
||||
|
||||
String StringFromChar(Arena *arena, char c)
|
||||
{
|
||||
u8 *dst = PushStructNoZero(arena, u8);
|
||||
@ -124,7 +129,7 @@ String StringFromFloat(Arena *arena, f64 f, u32 precision)
|
||||
f += 0.5 / (f64)PowU64(10, (u8)precision);
|
||||
|
||||
f64 part_whole = TruncF64(f);
|
||||
f64 part_decimal = f - part_whole;
|
||||
f64 part_frac = f - part_whole;
|
||||
|
||||
// Print whole part
|
||||
{
|
||||
@ -147,15 +152,15 @@ String StringFromFloat(Arena *arena, f64 f, u32 precision)
|
||||
}
|
||||
}
|
||||
|
||||
// Print decimal part
|
||||
// Print frac part
|
||||
if (precision > 0)
|
||||
{
|
||||
StringFromChar(arena, '.');
|
||||
for (u64 i = 0; i < precision; ++i)
|
||||
{
|
||||
part_decimal *= 10.0;
|
||||
u64 digit = (u64)part_decimal;
|
||||
part_decimal -= digit;
|
||||
part_frac *= 10.0;
|
||||
u64 digit = (u64)part_frac;
|
||||
part_frac -= digit;
|
||||
StringFromChar(arena, IntChars[digit % 10]);
|
||||
}
|
||||
result.len += (u64)precision + 1;
|
||||
@ -213,6 +218,97 @@ String StringFromUid(Arena *arena, Uid uid)
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Parsing helpers
|
||||
|
||||
b32 BoolFromString(String str)
|
||||
{
|
||||
b32 result = 0;
|
||||
result = MatchString(str, Lit("true"));
|
||||
return result;
|
||||
}
|
||||
|
||||
f64 FloatFromString(String str)
|
||||
{
|
||||
f64 result = 0;
|
||||
|
||||
b32 ok = 1;
|
||||
|
||||
// Eat sign
|
||||
u64 whole_start_idx = 0;
|
||||
i32 sign = 1;
|
||||
if (ok && str.len > 0)
|
||||
{
|
||||
if (whole_start_idx < str.len)
|
||||
{
|
||||
u8 c = str.text[whole_start_idx];
|
||||
if (c == '-')
|
||||
{
|
||||
sign = -1;
|
||||
whole_start_idx += 1;
|
||||
}
|
||||
else if (c == '+')
|
||||
{
|
||||
whole_start_idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find decimal place
|
||||
u64 frac_start_idx = whole_start_idx;
|
||||
for (; ok && frac_start_idx < str.len; ++frac_start_idx)
|
||||
{
|
||||
u8 c = str.text[frac_start_idx];
|
||||
if (c == '.')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse whole part
|
||||
u64 whole_part = 0;
|
||||
for (u64 char_idx = whole_start_idx; ok && char_idx < frac_start_idx; ++char_idx)
|
||||
{
|
||||
u8 c = str.text[char_idx];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
u8 digit = c - '0';
|
||||
whole_part += digit * PowU64(10, frac_start_idx - (char_idx + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse frac part
|
||||
u64 frac_part = 0;
|
||||
for (u64 char_idx = frac_start_idx + 1; ok && char_idx < str.len; ++char_idx)
|
||||
{
|
||||
u8 c = str.text[char_idx];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
u8 digit = c - '0';
|
||||
frac_part += digit * PowU64(10, str.len - (char_idx + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
result = (f64)whole_part + ((f64)frac_part / PowU64(10, str.len - (frac_start_idx + 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ String helpers
|
||||
|
||||
|
||||
@ -77,6 +77,7 @@ Struct(CodepointIter)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Conversion helpers
|
||||
|
||||
String StringFromBool(Arena *arena, b32 b);
|
||||
String StringFromChar(Arena *arena, char c);
|
||||
String StringFromUint(Arena *arena, u64 n, u64 base, u64 zfill);
|
||||
String StringFromUints(Arena *arena, u64 uints_count, u64 *uints, u64 base, u64 zfill);
|
||||
@ -86,6 +87,12 @@ String StringFromPtr(Arena *arena, void *ptr);
|
||||
String StringFromhandle(Arena *arena, u64 v0, u64 v1);
|
||||
String StringFromUid(Arena *arena, Uid uid);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Parsing helpers
|
||||
|
||||
b32 BoolFromString(String str);
|
||||
f64 FloatFromString(String str);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ String helpers
|
||||
|
||||
|
||||
@ -9,9 +9,10 @@ void BootstrapTweakVars(void)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var operations
|
||||
|
||||
TweakVar TweakEx(String name, TweakKind kind, TweakValue value, b32 set_new_value)
|
||||
String TweakEx(Arena *arena, String name, TweakDesc desc, String new_value, b32 set_to_new_value)
|
||||
{
|
||||
TweakVar result = Zi;
|
||||
String result = Zi;
|
||||
Arena *perm = PermArena();
|
||||
u64 hash = MixU64(HashFnv64(Fnv64Basis, name));
|
||||
TweakVarEntryBin *bin = &Base.tweak.entry_bins[hash % countof(Base.tweak.entry_bins)];
|
||||
LockTicketMutex(&Base.tweak.tm);
|
||||
@ -24,33 +25,38 @@ TweakVar TweakEx(String name, TweakKind kind, TweakValue value, b32 set_new_valu
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (e)
|
||||
if (!e)
|
||||
{
|
||||
if (set_new_value)
|
||||
{
|
||||
e->v.value = value;
|
||||
}
|
||||
result = e->v;
|
||||
}
|
||||
else
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
PushAlign(perm, CachelineSize);
|
||||
e = PushStruct(perm, TweakVarEntry);
|
||||
e->hash = hash;
|
||||
{
|
||||
// FIXME: Not perm
|
||||
String store_value = PushString(perm, new_value);
|
||||
|
||||
TweakVar *v = &e->v;
|
||||
v->name = PushString(perm, name);
|
||||
v->kind = kind;
|
||||
v->value = value;
|
||||
v->default_value = value;
|
||||
result = *v;
|
||||
v->desc = desc;
|
||||
v->value = store_value;
|
||||
v->default_value = store_value;
|
||||
}
|
||||
PushAlign(perm, CachelineSize);
|
||||
SllQueuePushN(bin->first, bin->last, e, next_in_bin);
|
||||
SllQueuePushN(Base.tweak.first_entry, Base.tweak.last_entry, e, next_in_list);
|
||||
Base.tweak.entries_count += 1;
|
||||
}
|
||||
else if (set_to_new_value)
|
||||
{
|
||||
if (!MatchString(e->v.value, new_value))
|
||||
{
|
||||
// FIXME: Not perm
|
||||
String store_value = PushString(perm, new_value);
|
||||
|
||||
// FIXME: free old value
|
||||
e->v.value = store_value;
|
||||
}
|
||||
}
|
||||
result = PushString(arena, e->v.value);
|
||||
}
|
||||
UnlockTicketMutex(&Base.tweak.tm);
|
||||
return result;
|
||||
@ -67,7 +73,11 @@ TweakVarArray GetAllTweakVars(Arena *arena)
|
||||
i64 var_idx = 0;
|
||||
for (TweakVarEntry *e = Base.tweak.first_entry; e; e = e->next_in_list)
|
||||
{
|
||||
result.v[var_idx] = e->v;
|
||||
TweakVar *src = &e->v;
|
||||
TweakVar *dst = &result.v[var_idx];
|
||||
*dst = *src;
|
||||
dst->value = PushString(arena, src->value);
|
||||
dst->default_value = PushString(arena, src->default_value);
|
||||
var_idx += 1;
|
||||
}
|
||||
}
|
||||
@ -76,7 +86,35 @@ TweakVarArray GetAllTweakVars(Arena *arena)
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 MatchTweakValue(TweakValue a, TweakValue b)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var retrieval helpers
|
||||
|
||||
b32 TweakBool(String name, b32 default_value)
|
||||
{
|
||||
return MatchStruct(&a, &b);
|
||||
b32 result = 0;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
TweakDesc desc = Zi;
|
||||
desc.kind = TweakKind_Bool;
|
||||
String tweak_str = TweakEx(scratch.arena, name, desc, StringFromBool(scratch.arena, default_value), 0);
|
||||
result = BoolFromString(tweak_str);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
f64 TweakFloat(String name, f64 default_value, f64 min, f64 max)
|
||||
{
|
||||
f64 result = 0;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
TweakDesc desc = Zi;
|
||||
desc.kind = TweakKind_Float;
|
||||
desc.range.min = min;
|
||||
desc.range.max = max;
|
||||
String tweak_str = TweakEx(scratch.arena, name, desc, StringFromFloat(scratch.arena, default_value, 6), 0);
|
||||
result = FloatFromString(tweak_str);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -4,19 +4,21 @@
|
||||
Enum(TweakKind)
|
||||
{
|
||||
TweakKind_Bool,
|
||||
TweakKind_Float,
|
||||
};
|
||||
|
||||
Struct(TweakValue)
|
||||
Struct(TweakDesc)
|
||||
{
|
||||
f64 x, y, z, w;
|
||||
TweakKind kind;
|
||||
RngF64 range;
|
||||
};
|
||||
|
||||
Struct(TweakVar)
|
||||
{
|
||||
String name;
|
||||
TweakKind kind;
|
||||
TweakValue value;
|
||||
TweakValue default_value;
|
||||
TweakDesc desc;
|
||||
String value;
|
||||
String default_value;
|
||||
};
|
||||
|
||||
Struct(TweakVarArray)
|
||||
@ -64,9 +66,11 @@ void BootstrapTweakVars(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var operations
|
||||
|
||||
TweakVar TweakEx(String name, TweakKind kind, TweakValue value, b32 set_new_value);
|
||||
String TweakEx(Arena *arena, String name, TweakDesc desc, String new_value, b32 set_to_new_value);
|
||||
TweakVarArray GetAllTweakVars(Arena *arena);
|
||||
|
||||
//- Helpers
|
||||
b32 MatchTweakValue(TweakValue a, TweakValue b);
|
||||
#define TweakB32(_name, _default_value) (TweakEx(Lit(_name), TweakKind_Bool, (TweakValue) { .x = !!(_default_value) }, 0).value.x >= 0.5)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var retrieval helpers
|
||||
|
||||
b32 TweakBool(String name, b32 default_value);
|
||||
f64 TweakFloat(String name, f64 default_value, f64 min, f64 max);
|
||||
|
||||
@ -180,15 +180,15 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
||||
GC_RunRect *rect = &result.rects[glyph_idx];
|
||||
|
||||
f32 advance = glyph->advance;
|
||||
if (TweakB32("Ceil glyph advances", 0))
|
||||
if (TweakBool(Lit("Ceil glyph advances"), 0))
|
||||
{
|
||||
advance = CeilF32(advance);
|
||||
}
|
||||
if (TweakB32("Floor glyph advances", 0))
|
||||
if (TweakBool(Lit("Floor glyph advances"), 0))
|
||||
{
|
||||
advance = FloorF32(advance);
|
||||
}
|
||||
if (TweakB32("Round glyph advances", 1))
|
||||
if (TweakBool(Lit("Round glyph advances"), 1))
|
||||
{
|
||||
advance = RoundF32(advance);
|
||||
}
|
||||
@ -288,7 +288,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *frame)
|
||||
GC_Glyph *glyph = cmd->glyph;
|
||||
ResourceKey resource = glyph->desc.font.r;
|
||||
GC_GlyphDesc desc = glyph->desc;
|
||||
TTF_GlyphResult ttf_result = TTF_RasterizeGlyphFromCodepoint(frame->arena, desc.codepoint, resource, desc.font_size);;
|
||||
TTF_GlyphResult ttf_result = TTF_RasterizeGlyphFromCodepoint(frame->arena, desc.codepoint, resource, desc.font_size);
|
||||
glyph->font_size = desc.font_size;
|
||||
glyph->font_ascent = ttf_result.font_ascent;
|
||||
glyph->font_descent = ttf_result.font_descent;
|
||||
|
||||
@ -472,10 +472,12 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
PushAlign(perm, CachelineSize);
|
||||
{
|
||||
pipeline = PushStruct(perm, G_D12_Pipeline);
|
||||
pipeline->desc = desc;
|
||||
pipeline->hash = hash;
|
||||
is_pipeline_new = 1;
|
||||
}
|
||||
PushAlign(perm, CachelineSize);
|
||||
SllStackPushN(bin->first, pipeline, next_in_bin);
|
||||
}
|
||||
|
||||
@ -460,7 +460,7 @@ void BuildEntryPoint(WaveLaneCtx *lane)
|
||||
M_TokenFileList lexed = M_TokensFromSrcDirs(perm, src_dirs);
|
||||
|
||||
// Parse
|
||||
M_LayerList parsed = M_LayersFromTokenFiles(perm, lexed);;
|
||||
M_LayerList parsed = M_LayersFromTokenFiles(perm, lexed);
|
||||
|
||||
// Flatten
|
||||
StringList starting_layer_names = Zi;
|
||||
|
||||
@ -407,7 +407,6 @@ String P_ReadFile(Arena *arena, P_File file)
|
||||
{
|
||||
// ReadFile returns non-zero on success
|
||||
// TODO: error checking
|
||||
PushAlign(arena, CachelineSize);
|
||||
result.text = PushStructsNoZero(arena, u8, size);
|
||||
ReadFile(
|
||||
(HANDLE)file.handle,
|
||||
|
||||
@ -90,15 +90,18 @@ V_WidgetTheme V_GetWidgetTheme(void)
|
||||
theme.h5 = 0.83;
|
||||
theme.h6 = 0.67;
|
||||
|
||||
// theme.rounding = 0;
|
||||
// theme.rounding = 1;
|
||||
theme.rounding = TweakFloat(Lit("Rounding"), 1, 0, 1);
|
||||
|
||||
theme.text_padding_x = 5;
|
||||
theme.text_padding_y = 5;
|
||||
|
||||
// theme.font_size = TweakI32("Font size", 14, RNGI32(5, 100));
|
||||
theme.font_size = TweakFloat(Lit("Font size"), 14, 10, 50);
|
||||
|
||||
theme.window_background_color = Rgb32(0xff1a1d1e);
|
||||
theme.window_border_color = Rgb32(0xff343a3b);
|
||||
theme.window_border = 1;
|
||||
theme.window_width = 500;
|
||||
theme.window_padding = theme.window_border - 1;
|
||||
theme.divider_color = theme.window_border_color;
|
||||
|
||||
@ -811,10 +814,13 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_Report child_rep = UI_ReportFromKey(resize_panel->key);
|
||||
UI_Report divider_rep = UI_ReportFromKey(resize_panel->divider_key);
|
||||
|
||||
f32 drag_offset = ui_frame->last_mouse_down_cursor_pos.v[panel->axis] - divider_rep.last_mouse_down_screen_anchor.v[panel->axis];
|
||||
|
||||
f32 child_pref_size = 0;
|
||||
child_pref_size += frame->ui_cursor.v[panel->axis];
|
||||
child_pref_size -= child_rep.screen_anchor.v[panel->axis];
|
||||
child_pref_size -= divider_rep.last_cursor_down_anchor_offset.v[panel->axis];
|
||||
// child_pref_size -= divider_rep.last_cursor_down_anchor_offset.v[panel->axis];
|
||||
child_pref_size -= drag_offset;
|
||||
|
||||
f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio;
|
||||
f32 min_ratio = 0.05;
|
||||
@ -985,7 +991,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
f32 drag_threshold = 20;
|
||||
if (tab_rep.m1.held)
|
||||
{
|
||||
Vec2 drag_start = AddVec2(tab_rep.screen_anchor, tab_rep.last_cursor_down_anchor_offset);
|
||||
Vec2 drag_start = ui_frame->last_mouse_down_cursor_pos;
|
||||
if (Vec2Len(SubVec2(frame->ui_cursor, drag_start)) > drag_threshold)
|
||||
{
|
||||
V.dragging_window = window;
|
||||
@ -1288,7 +1294,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
V_Palette *palette = &frame->palette;
|
||||
{
|
||||
f32 palette_ease = 30.0 * frame->dt;
|
||||
if (TweakB32("Slow palette ease", 0))
|
||||
if (TweakBool(Lit("Slow palette ease"), 0))
|
||||
{
|
||||
palette_ease = 1.0 * frame->dt;
|
||||
}
|
||||
@ -1311,7 +1317,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec4 divider_color = theme.divider_color;
|
||||
if (titlebar_rep.m1.held)
|
||||
{
|
||||
palette->pos = SubVec2(frame->ui_cursor, palette_rep.last_cursor_down_anchor_offset);
|
||||
Vec2 drag_offset = SubVec2(ui_frame->last_mouse_down_cursor_pos, palette_rep.last_mouse_down_screen_anchor);
|
||||
palette->pos = SubVec2(frame->ui_cursor, drag_offset);
|
||||
}
|
||||
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
|
||||
|
||||
@ -1322,8 +1329,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_Push(BackgroundColor, window_background_color);
|
||||
UI_Push(BorderColor, window_border_color);
|
||||
UI_Push(Border, theme.window_border);
|
||||
UI_Push(Rounding, UI_RPIX(15));
|
||||
UI_Push(Width, UI_PIX(theme.window_width, 0));
|
||||
UI_Push(Rounding, UI_RPIX(15 * theme.rounding));
|
||||
UI_Push(Width, UI_FNT(50, 0));
|
||||
UI_Push(Height, UI_SHRINK(0, 0));
|
||||
UI_Push(ChildLayoutAxis, Axis_Y);
|
||||
UI_Push(FloatingPos, palette->pos);
|
||||
@ -1368,12 +1375,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Build palette items list
|
||||
|
||||
f32 padding = theme.window_border;
|
||||
f32 window_padding = theme.window_border;
|
||||
UI_SetNext(Tint, 0);
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_PushCP(UI_BuildRow());
|
||||
{
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
|
||||
UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_X);
|
||||
{
|
||||
UI_SetNext(Tint, 0);
|
||||
UI_SetNext(Rounding, 0);
|
||||
@ -1452,6 +1459,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
for (PaletteItem *item = first_item; item; item = item->next)
|
||||
{
|
||||
f32 spacing = 20;
|
||||
|
||||
// Divider
|
||||
UI_BuildDivider(UI_PIX(1, 1), divider_color, Axis_Y);
|
||||
|
||||
@ -1490,7 +1499,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_Push(Tag, item->key.hash);
|
||||
|
||||
// Begin spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
|
||||
// Command label
|
||||
UI_SetNext(ChildAlignment, UI_Region_Left);
|
||||
@ -1503,46 +1512,178 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
if (item->flags & PaletteItemFlag_IsTweakVar)
|
||||
{
|
||||
TweakVar tweak_var = item->tweak_var;
|
||||
UI_Key tweak_key = UI_KeyF("tweak");
|
||||
UI_Report tweak_rep = UI_ReportFromKey(tweak_key);
|
||||
TweakValue new_tweak_value = tweak_var.value;
|
||||
TweakDesc tweak_desc = tweak_var.desc;
|
||||
String old_tweak_str = tweak_var.value;
|
||||
String new_tweak_str = tweak_var.value;
|
||||
|
||||
switch (tweak_var.kind)
|
||||
{
|
||||
// Tweak checkbox
|
||||
case TweakKind_Bool:
|
||||
{
|
||||
// Vec4 tweak_bg_color = LerpSrgb(theme.color_negative, theme.color_positive, new_tweak_value.x);
|
||||
Vec4 tweak_bg_color = Zi;
|
||||
tweak_bg_color = LerpSrgb(tweak_bg_color, theme.color_positive, new_tweak_value.x);
|
||||
// Tweak label
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
UI_BuildLabel(new_tweak_str);
|
||||
|
||||
Vec4 tweak_border_color = theme.window_border_color;
|
||||
// tweak_border_color = LerpSrgb(tweak_border_color, theme.button_hot_color, tweak_rep.hot);
|
||||
// tweak_border_color = LerpSrgb(tweak_border_color, theme.button_active_color, tweak_rep.active);
|
||||
tweak_border_color = LerpSrgb(tweak_border_color, theme.button_active_color, tweak_rep.hot);
|
||||
|
||||
if (tweak_rep.m1.downs)
|
||||
// Reset button
|
||||
if (!MatchString(new_tweak_str, tweak_var.default_value))
|
||||
{
|
||||
new_tweak_value.x = !new_tweak_value.x;
|
||||
UI_BuildSpacer(UI_PIX(spacing * 0.5, 1), Axis_X);
|
||||
UI_Key reset_key = UI_KeyF("reset");
|
||||
UI_Report reset_rep = UI_ReportFromKey(reset_key);
|
||||
|
||||
if (reset_rep.m1.presses > 0)
|
||||
{
|
||||
new_tweak_str = tweak_var.default_value;
|
||||
}
|
||||
|
||||
UI_SetNext(BackgroundColor, tweak_bg_color);
|
||||
UI_SetNext(BorderColor, tweak_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(1));
|
||||
Vec4 reset_bg_color = Zi;
|
||||
Vec4 reset_border_color = theme.window_border_color;
|
||||
reset_bg_color = LerpSrgb(reset_bg_color, theme.button_hot_color, reset_rep.hot);
|
||||
reset_bg_color = LerpSrgb(reset_bg_color, theme.button_active_color, reset_rep.active);
|
||||
reset_border_color = LerpSrgb(reset_border_color, theme.button_active_color, reset_rep.hot);
|
||||
// reset_border_color = LerpSrgb(reset_border_color, theme.button_active_color, reset_rep.active);
|
||||
UI_SetNext(BackgroundColor, reset_bg_color);
|
||||
UI_SetNext(BorderColor, reset_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(theme.rounding));
|
||||
UI_SetNext(Border, 2);
|
||||
UI_SetNext(Width, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Height, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(tweak_key));
|
||||
UI_PushCP(UI_BuildRowEx(reset_key));
|
||||
{
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
|
||||
if (!MatchTweakValue(tweak_var.value, new_tweak_value))
|
||||
{
|
||||
TweakEx(tweak_var.name, tweak_var.kind, new_tweak_value, 1);
|
||||
}
|
||||
|
||||
switch (tweak_desc.kind)
|
||||
{
|
||||
// Boolean tweak
|
||||
case TweakKind_Bool:
|
||||
{
|
||||
UI_Key cb_key = UI_KeyF("tweak checkbox");
|
||||
UI_Report cb_rep = UI_ReportFromKey(cb_key);
|
||||
|
||||
b32 tweak_bool = BoolFromString(new_tweak_str);
|
||||
if (cb_rep.m1.downs)
|
||||
{
|
||||
tweak_bool = !tweak_bool;
|
||||
new_tweak_str = StringFromBool(frame->arena, tweak_bool);
|
||||
}
|
||||
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
|
||||
// Tweak checkbox
|
||||
Vec4 cb_bg_color = Zi;
|
||||
Vec4 cb_border_color = theme.window_border_color;
|
||||
cb_bg_color = LerpSrgb(cb_bg_color, theme.color_positive, tweak_bool);
|
||||
cb_border_color = LerpSrgb(cb_border_color, theme.button_active_color, cb_rep.hot);
|
||||
|
||||
UI_SetNext(BackgroundColor, cb_bg_color);
|
||||
UI_SetNext(BorderColor, cb_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(theme.rounding));
|
||||
UI_SetNext(Border, 2);
|
||||
UI_SetNext(Width, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Height, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(cb_key));
|
||||
{
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
} break;
|
||||
|
||||
// Float tweak
|
||||
case TweakKind_Float:
|
||||
{
|
||||
UI_Key slider_key = UI_KeyF("tweak slider");
|
||||
UI_Key marker_key = UI_KeyF("tweak slider marker");
|
||||
|
||||
UI_Report slider_rep = UI_ReportFromKey(slider_key);
|
||||
UI_Report marker_rep = UI_ReportFromKey(marker_key);
|
||||
|
||||
Vec2 slider_pos = slider_rep.screen_rect.p0;
|
||||
Vec2 slider_dims = DimsFromRng2(slider_rep.screen_rect);
|
||||
|
||||
f64 range_min = tweak_desc.range.min;
|
||||
f64 range_max = tweak_desc.range.max;
|
||||
if (range_max <= range_min)
|
||||
{
|
||||
range_max = range_min + 1;
|
||||
}
|
||||
|
||||
if (TweakFloat(Lit("Test"), 0.5, 0, 1))
|
||||
{
|
||||
}
|
||||
|
||||
f64 tweak_float = FloatFromString(new_tweak_str);
|
||||
|
||||
{
|
||||
Axis slider_axis = Axis_X;
|
||||
if (slider_rep.m1.held)
|
||||
{
|
||||
|
||||
Vec2 initial_start = slider_rep.last_mouse_down_screen_rect.p0;
|
||||
Vec2 initial_end = slider_rep.last_mouse_down_screen_rect.p1;
|
||||
Vec2 initial_dims = SubVec2(initial_end, initial_start);
|
||||
|
||||
Vec2 initial_marker_offset = SubVec2(marker_rep.last_mouse_down_screen_anchor, initial_start);
|
||||
Vec2 initial_cursor = ui_frame->last_mouse_down_cursor_pos;
|
||||
|
||||
Vec2 virtual_start = SubVec2(initial_cursor, initial_marker_offset);
|
||||
Vec2 virtual_end = AddVec2(virtual_start, initial_dims);
|
||||
Vec2 virtual_cursor_offset = SubVec2(frame->ui_cursor, virtual_start);
|
||||
Vec2 virtual_cursor_ratio = DivVec2Vec2(virtual_cursor_offset, initial_dims);
|
||||
virtual_cursor_ratio = ClampVec2(virtual_cursor_ratio, RNG2(VEC2(0, 0), VEC2(1, 1)));
|
||||
|
||||
f32 precision = 3; // FIXME: Remove this
|
||||
tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio.v[slider_axis]);
|
||||
new_tweak_str = StringFromFloat(frame->arena, tweak_float, precision);
|
||||
}
|
||||
if (slider_rep.is_hot)
|
||||
{
|
||||
WND_PushCmd(
|
||||
window_frame,
|
||||
.kind = WND_CmdKind_SetCursor,
|
||||
slider_axis == Axis_X ? WND_CursorKind_HorizontalResize : WND_CursorKind_VerticalResize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
|
||||
// Tweak slider
|
||||
Vec4 slider_bg_color = Zi;
|
||||
Vec4 slider_border_color = theme.window_border_color;
|
||||
slider_border_color = LerpSrgb(slider_border_color, theme.button_active_color, slider_rep.hot);
|
||||
|
||||
UI_SetNext(BackgroundColor, slider_bg_color);
|
||||
UI_SetNext(BorderColor, slider_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(theme.rounding));
|
||||
UI_SetNext(Border, 2);
|
||||
UI_SetNext(Width, UI_FNT(10, 1));
|
||||
UI_SetNext(Height, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(slider_key));
|
||||
{
|
||||
// FIXME: Marker pos should account for marker width
|
||||
f32 ratio = 0;
|
||||
ratio = (tweak_float - range_min) / (range_max - range_min);
|
||||
ratio = ClampF32(ratio, 0, 1);
|
||||
f32 marker_pos = ratio * slider_dims.x;
|
||||
|
||||
UI_SetNext(BackgroundColor, slider_bg_color);
|
||||
UI_SetNext(BorderColor, slider_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(theme.rounding));
|
||||
UI_SetNext(Border, 2);
|
||||
UI_SetNext(Width, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Height, UI_FNT(1.25, 1));
|
||||
UI_SetNext(Anchor, UI_Region_Center);
|
||||
UI_SetNext(FloatingPos, VEC2(marker_pos, 0));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
||||
UI_BuildBoxEx(marker_key);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
} break;
|
||||
}
|
||||
|
||||
if (!MatchString(old_tweak_str, new_tweak_str))
|
||||
{
|
||||
TweakEx(frame->arena, tweak_var.name, tweak_desc, new_tweak_str, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1593,7 +1734,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
|
||||
// End spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
@ -1602,11 +1743,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
|
||||
UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_Y);
|
||||
}
|
||||
// UI_PopCP(UI_TopCP());
|
||||
UI_PopCP(palette_cp);
|
||||
@ -1622,7 +1763,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 dbg_dims = DimsFromRng2(dbg_rep.screen_rect);
|
||||
|
||||
f32 padding = 20;
|
||||
f32 rounding = 0;
|
||||
f32 rounding = 15 * theme.rounding;
|
||||
Vec4 color = VEC4(0, 0, 0, 0.75);
|
||||
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
||||
UI_SetNext(FloatingPos, VEC2(0, frame->ui_dims.y - dbg_dims.y));
|
||||
|
||||
@ -30,12 +30,13 @@ Struct(V_WidgetTheme)
|
||||
f32 h5;
|
||||
f32 h6;
|
||||
|
||||
f32 rounding;
|
||||
|
||||
Vec4 window_background_color;
|
||||
Vec4 window_border_color;
|
||||
Vec4 divider_color;
|
||||
f32 window_border;
|
||||
f32 window_padding;
|
||||
f32 window_width;
|
||||
|
||||
Vec4 button_color;
|
||||
Vec4 button_hot_color;
|
||||
|
||||
@ -518,6 +518,7 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key)
|
||||
n->cmd.box.border = UI_Top(Border);
|
||||
n->cmd.box.font = UI_Top(Font);
|
||||
n->cmd.box.font_size = UI_Top(FontSize);
|
||||
|
||||
n->cmd.box.rounding = UI_Top(Rounding);
|
||||
n->cmd.box.text = UI_Top(Text);
|
||||
n->cmd.box.anchor = UI_Top(Anchor);
|
||||
@ -635,6 +636,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
||||
//- Process controller events
|
||||
|
||||
frame->cursor_pos = last_frame->cursor_pos;
|
||||
frame->last_mouse_down_cursor_pos = last_frame->last_mouse_down_cursor_pos;
|
||||
|
||||
if (last_frame->boxes_pre != 0)
|
||||
{
|
||||
@ -828,10 +830,16 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
||||
|
||||
if (mouse_downs > 0)
|
||||
{
|
||||
report->last_cursor_down_anchor_offset = SubVec2(frame->cursor_pos, box->screen_anchor);
|
||||
report->last_mouse_down_screen_rect = box->screen_rect;
|
||||
report->last_mouse_down_screen_anchor = box->screen_anchor;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse_downs > 0)
|
||||
{
|
||||
frame->last_mouse_down_cursor_pos = frame->cursor_pos;
|
||||
}
|
||||
|
||||
frame->top_hovered_box = top_hovered_box ? top_hovered_box->key : UI_NilKey;
|
||||
frame->hot_box = hot_box ? hot_box->key : UI_NilKey;
|
||||
frame->active_box = active_box ? active_box->key : UI_NilKey;
|
||||
|
||||
@ -118,7 +118,7 @@ Enum(UI_BoxFlag)
|
||||
X(FloatingPos, Vec2) \
|
||||
X(Rounding, UI_Round) \
|
||||
X(Font, GC_FontKey) \
|
||||
X(FontSize, u32) \
|
||||
X(FontSize, f32) \
|
||||
X(Text, String) \
|
||||
X(BackgroundTexture, G_Texture2DRef) \
|
||||
X(BackgroundTextureSliceUv, Rng2) \
|
||||
@ -203,15 +203,17 @@ Struct(UI_Report)
|
||||
f32 active;
|
||||
f32 selected;
|
||||
|
||||
// Mouse button info
|
||||
Vec2 last_cursor_down_anchor_offset;
|
||||
UI_MouseReport m1;
|
||||
UI_MouseReport m2;
|
||||
UI_MouseReport m3;
|
||||
|
||||
// Where was this box last rendered in screen coordinates
|
||||
// Where was this box rendered in screen coordinates
|
||||
Rng2 screen_rect;
|
||||
Vec2 screen_anchor;
|
||||
|
||||
// Where was this box rendered during the last mouse press
|
||||
Rng2 last_mouse_down_screen_rect;
|
||||
Vec2 last_mouse_down_screen_anchor;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -378,6 +380,7 @@ Struct(UI_Frame)
|
||||
|
||||
// Control
|
||||
Vec2 cursor_pos;
|
||||
Vec2 last_mouse_down_cursor_pos;
|
||||
UI_Key top_hovered_box;
|
||||
UI_Key hot_box;
|
||||
UI_Key active_box;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user