working tweak vars
This commit is contained in:
parent
4f00af6044
commit
e8b5edb371
@ -431,7 +431,7 @@
|
||||
#define IsFixedArray(a) (IsIndexable(a) && (((void *)&a) == ((void *)a)))
|
||||
|
||||
//- offsetof
|
||||
#if !IsCompilerMsvc
|
||||
#if IsCompilerMsvc
|
||||
#ifdef _CRT_USE_BUILTIN_OFFSETOF
|
||||
#define offsetof(type, field) __builtin_offsetof(type, field)
|
||||
#else
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
|
||||
Struct(BaseCtx)
|
||||
{
|
||||
TweakVarsCtx tweak;
|
||||
CmdLineCtx cmdline;
|
||||
ResourceCtx resource;
|
||||
GstatCtx gstat;
|
||||
AsyncCtx async;
|
||||
TweakVarsCtx tweak;
|
||||
};
|
||||
|
||||
extern BaseCtx Base;
|
||||
|
||||
@ -1,39 +1,81 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
void BootstrapTweakVars(void)
|
||||
{
|
||||
// TODO: Swap in/out for persistence
|
||||
#define X(name, type, default_value) Base.tweak.shared_vars.##name = default_value;
|
||||
TweakVarsXMacro(X);
|
||||
#undef X
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var get/set
|
||||
|
||||
//- Auto-generated functions
|
||||
|
||||
#define X(name, type, default_value) \
|
||||
type GetTweak_##name(void) \
|
||||
type GetGlobalTweakVar_TweakVarKind_##name(void) \
|
||||
{ \
|
||||
type result = Zi; \
|
||||
LockTicketMutex(&Base.tweak.mutex); \
|
||||
LockTicketMutex(&Base.tweak.tm); \
|
||||
{ \
|
||||
result = Base.tweak.shared_vars.##name; \
|
||||
} \
|
||||
UnlockTicketMutex(&Base.tweak.mutex); \
|
||||
UnlockTicketMutex(&Base.tweak.tm); \
|
||||
return result; \
|
||||
} \
|
||||
void SetTweak_##name(type v) \
|
||||
void SetGlobalTweakVar_TweakVarKind_##name(type v) \
|
||||
{ \
|
||||
LockTicketMutex(&Base.tweak.mutex); \
|
||||
LockTicketMutex(&Base.tweak.tm); \
|
||||
{ \
|
||||
Base.tweak.shared_vars.name = v; \
|
||||
} \
|
||||
UnlockTicketMutex(&Base.tweak.mutex); \
|
||||
UnlockTicketMutex(&Base.tweak.tm); \
|
||||
}
|
||||
TweakVarsXMacro(X);
|
||||
#undef X
|
||||
|
||||
//- Helpers
|
||||
|
||||
TweakVars GetAllTweakVars(void)
|
||||
TweakVarDesc TweakVarDescFromKind(TweakVarKind kind)
|
||||
{
|
||||
Readonly PERSIST TweakVarDesc descs[TweakVarKind_COUNT] = {
|
||||
#define X(_name, _type, _default_value) \
|
||||
{ \
|
||||
.name = CompLit(#_name), \
|
||||
.type = TweakVarType_##_type, \
|
||||
.offset = offsetof(TweakVars, _name), \
|
||||
.default_##_type = (_default_value), \
|
||||
},
|
||||
TweakVarsXMacro(X)
|
||||
#undef X
|
||||
};
|
||||
|
||||
TweakVarDesc result = Zi;
|
||||
if (kind >= 0 && kind < countof(descs))
|
||||
{
|
||||
result = descs[kind];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TweakVars GetAllGlobalTweakVars(void)
|
||||
{
|
||||
TweakVars result;
|
||||
LockTicketMutex(&Base.tweak.mutex);
|
||||
LockTicketMutex(&Base.tweak.tm);
|
||||
{
|
||||
result = Base.tweak.shared_vars;
|
||||
}
|
||||
UnlockTicketMutex(&Base.tweak.mutex);
|
||||
UnlockTicketMutex(&Base.tweak.tm);
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetAllGlobalTweakVars(TweakVars *v)
|
||||
{
|
||||
LockTicketMutex(&Base.tweak.tm);
|
||||
{
|
||||
CopyStruct(&Base.tweak.shared_vars, v);
|
||||
}
|
||||
UnlockTicketMutex(&Base.tweak.tm);
|
||||
}
|
||||
|
||||
@ -22,22 +22,43 @@ Struct(TweakVars)
|
||||
i32 __; // Prevent empty struct
|
||||
};
|
||||
|
||||
Struct(TweakVarDesc)
|
||||
{
|
||||
String name;
|
||||
TweakVarType type;
|
||||
i32 offset;
|
||||
union
|
||||
{
|
||||
b32 default_b32;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
Struct(TweakVarsCtx)
|
||||
{
|
||||
TicketMutex mutex;
|
||||
TicketMutex tm;
|
||||
TweakVars shared_vars;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
void BootstrapTweakVars(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tweak var operations
|
||||
|
||||
//- Auto-generated functions
|
||||
#define X(name, type, ...) \
|
||||
type GetTweak_##name(void); \
|
||||
void SetTweak_##name(type v);
|
||||
type GetGlobalTweakVar_##name(void); \
|
||||
void SetGlobalTweakVar_##name(type v);
|
||||
#undef X
|
||||
|
||||
//- Helpers
|
||||
TweakVars GetAllTweakVars(void);
|
||||
#define GetTweak(name) GetTweak_##name()
|
||||
#define SetTweak(name, v) SetTweak_##name((v))
|
||||
TweakVarDesc TweakVarDescFromKind(TweakVarKind kind);
|
||||
TweakVars GetAllGlobalTweakVars(void);
|
||||
void SetAllGlobalTweakVars(TweakVars *v);
|
||||
#define GetGlobalTweakVar(name) GetGlobalTweakVar_TweakVarKind_##name()
|
||||
#define SetGlobalTweakVar(name, v) SetGlobalTweakVar_TweakVarKind_##name((v))
|
||||
|
||||
@ -451,6 +451,9 @@ i32 W32_Main(void)
|
||||
//////////////////////////////
|
||||
//- Bootstrap
|
||||
|
||||
// Bootstrap tweak vars
|
||||
BootstrapTweakVars();
|
||||
|
||||
// Bootstrap command line
|
||||
BootstrapCmdline();
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
//~ Debug tweak vars
|
||||
|
||||
#define TweakVarsXMacro(X) \
|
||||
X(CeilGlyphAdvances, b32, 1) \
|
||||
X(CeilGlyphAdvances, b32, 0) \
|
||||
/* --------------------------------- */
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -180,7 +180,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
||||
GC_RunRect *rect = &result.rects[glyph_idx];
|
||||
|
||||
f32 advance = 0;
|
||||
if (GetTweak(CeilGlyphAdvances))
|
||||
if (GetGlobalTweakVar(CeilGlyphAdvances))
|
||||
{
|
||||
advance = CeilF32(glyph->advance * scale);
|
||||
}
|
||||
|
||||
@ -28,6 +28,19 @@ V_Frame *V_LastFrame(void)
|
||||
return &V.frames[(V.current_frame_tick - 1) % countof(V.frames)];
|
||||
}
|
||||
|
||||
V_Cmd *V_PushVisCmd(String name)
|
||||
{
|
||||
V_Frame *frame = V_CurrentFrame();
|
||||
V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode);
|
||||
V_Cmd *cmd = &cmd_node->cmd;
|
||||
{
|
||||
cmd->name = name;
|
||||
}
|
||||
++frame->cmds_count;
|
||||
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, cmd_node);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
S_Cmd *V_PushSimCmd(S_CmdKind kind)
|
||||
{
|
||||
V_Frame *frame = V_CurrentFrame();
|
||||
@ -87,6 +100,9 @@ V_WidgetTheme V_GetWidgetTheme(void)
|
||||
theme.button_hot_color = Rgb32(0x103c4c);
|
||||
theme.button_selected_color = Rgb32(0x00668D);
|
||||
|
||||
theme.color_positive = VEC4(0.25, 0.5, 0.25, 1);
|
||||
theme.color_negative = VEC4(0.5, 0.25, 0.25, 1);
|
||||
|
||||
theme.window_title_font_size = 16;
|
||||
theme.text_padding_x = 5;
|
||||
theme.text_padding_y = 5;
|
||||
@ -100,227 +116,6 @@ void V_PushWidgetThemeStyles(V_WidgetTheme theme)
|
||||
UI_Push(FontSize, theme.font_size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Palette
|
||||
|
||||
void V_BeginPalette(V_Palette *widget)
|
||||
{
|
||||
ZeroStruct(&widget->build);
|
||||
widget->build.cp = UI_PushCP(UI_NilKey);
|
||||
widget->key = UI_KeyF("commands palette");
|
||||
UI_Push(Tag, widget->key.hash);
|
||||
}
|
||||
|
||||
V_PaletteItemReport V_PushPaletteItem(V_Palette *widget, V_PaletteItemDesc desc)
|
||||
{
|
||||
Arena *frame_arena = UI_FrameArena();
|
||||
|
||||
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
|
||||
{
|
||||
V_PaletteItem *item = PushStruct(frame_arena, V_PaletteItem);
|
||||
item->key = key;
|
||||
item->desc = desc;
|
||||
SllQueuePush(widget->build.first_item, widget->build.last_item, item);
|
||||
++widget->build.num_items;
|
||||
}
|
||||
|
||||
V_PaletteItemReport result = Zi;
|
||||
UI_Report rep = UI_ReportFromKey(key);
|
||||
result.ui_report = rep;
|
||||
result.pressed = rep.m1.presses > 0;
|
||||
CopyStructs(result.new_hotkeys, desc.hotkeys, MinU32(countof(result.new_hotkeys), countof(desc.hotkeys)));
|
||||
return result;
|
||||
}
|
||||
|
||||
void V_EndPalette(V_Palette *widget)
|
||||
{
|
||||
V_Frame *frame = V_CurrentFrame();
|
||||
V_WidgetTheme theme = V_GetWidgetTheme();
|
||||
Vec2 cursor_pos = UI_CursorPos();
|
||||
|
||||
UI_Key titlebar_key = UI_KeyF("title bar");
|
||||
UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key);
|
||||
UI_Report widget_rep = UI_ReportFromKey(widget->key);
|
||||
Vec2 widget_half_dims = MulVec2(DimsFromRng2(widget_rep.screen_rect), 0.5);
|
||||
|
||||
Vec4 window_background_color = theme.window_background_color;
|
||||
// Vec4 window_background_color = VEC4(0, 0, 0, 0);
|
||||
Vec4 window_border_color = theme.window_border_color;
|
||||
Vec4 titlebar_color = Zi;
|
||||
Vec4 titlebar_border_color = Zi;
|
||||
Vec4 divider_color = theme.divider_color;
|
||||
if (titlebar_rep.m1.held)
|
||||
{
|
||||
widget->pos = AddVec2(SubVec2(cursor_pos, titlebar_rep.last_mouse_down_cursor_offset), widget_half_dims);
|
||||
}
|
||||
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
|
||||
|
||||
UI_Push(Scale, LerpF32(0.75, 1, widget_rep.selected));
|
||||
UI_Push(Tint, VEC4(1, 1, 1, widget_rep.selected));
|
||||
if (widget_rep.selected < 0.25)
|
||||
{
|
||||
UI_Push(OmitFlags, UI_UseTop(OmitFlags) | UI_BoxFlag_Interactable);
|
||||
}
|
||||
|
||||
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(Height, UI_SHRINK(0, 0));
|
||||
UI_Push(ChildLayoutAxis, Axis_Y);
|
||||
UI_Push(FloatingPos, SubVec2(widget->pos, widget_half_dims));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_Selected * frame->show_palette));
|
||||
UI_PushCP(UI_BuildBoxEx(widget->key));
|
||||
{
|
||||
// Title bar
|
||||
UI_PushCP(UI_NilKey);
|
||||
{
|
||||
UI_Push(BackgroundColor, titlebar_color);
|
||||
UI_Push(BorderColor, titlebar_border_color);
|
||||
UI_Push(Rounding, UI_RPIX(0));
|
||||
UI_Push(ChildLayoutAxis, Axis_X);
|
||||
UI_Push(Width, UI_GROW(1, 0));
|
||||
UI_Push(Height, UI_FNT(2, 1));
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildBoxEx(titlebar_key));
|
||||
{
|
||||
UI_Push(Width, UI_GROW(1, 0));
|
||||
UI_Push(BorderColor, 0);
|
||||
|
||||
// Left title box
|
||||
UI_BuildRow();
|
||||
|
||||
// Title box
|
||||
UI_SetNext(FontSize, theme.window_title_font_size);
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||
UI_SetNext(Width, UI_SHRINK(0, 1));
|
||||
UI_SetNext(Text, Lit("Command Palette"));
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText);
|
||||
UI_BuildBox();
|
||||
|
||||
// Right title box
|
||||
UI_BuildRow();
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
|
||||
f32 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_SetNext(Tint, 0);
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
UI_PushCP(UI_BuildColumn());
|
||||
{
|
||||
for (V_PaletteItem *item = widget->build.first_item; item; item = item->next)
|
||||
{
|
||||
UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y);
|
||||
|
||||
UI_Key btn_key = item->key;
|
||||
UI_Report btn_rep = UI_ReportFromKey(btn_key);
|
||||
|
||||
Vec4 btn_color = theme.window_background_color;
|
||||
btn_color = LerpSrgb(btn_color, theme.button_hot_color, btn_rep.hot);
|
||||
btn_color = LerpSrgb(btn_color, theme.button_active_color, btn_rep.active);
|
||||
Vec4 btn_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, btn_rep.hot);
|
||||
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_SetNext(Tint, 0);
|
||||
UI_PushCP(UI_BuildRow());
|
||||
{
|
||||
UI_SetNext(BorderColor, btn_border_color);
|
||||
UI_SetNext(BackgroundColor, btn_color);
|
||||
UI_SetNext(Rounding, UI_RPIX(5));
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
UI_SetNext(Height, UI_FNT(1.5, 1));
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Left);
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(btn_key));
|
||||
{
|
||||
UI_Push(Tag, btn_key.hash);
|
||||
|
||||
// Begin spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
|
||||
// Command label
|
||||
// UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Left);
|
||||
UI_BuildLabel(item->desc.display_name);
|
||||
|
||||
// Middle spacer
|
||||
UI_BuildSpacer(UI_GROW(1, 0), Axis_X);
|
||||
|
||||
// Command hotkey buttons
|
||||
for (u64 i = 0; i < countof(item->desc.hotkeys); ++i)
|
||||
{
|
||||
UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i));
|
||||
UI_Report hotkey_rep = UI_ReportFromKey(hotkey_key);
|
||||
|
||||
Vec4 hotkey_color = Zi;
|
||||
Vec4 hotkey_border_color = Zi;
|
||||
{
|
||||
Vec4 hovered_color = Rgb32(0x103c4c);
|
||||
Vec4 pressed_color = hovered_color;
|
||||
pressed_color.w = 0.2;
|
||||
f32 hotkey_hot = hotkey_rep.hot;
|
||||
f32 hotkey_active = hotkey_rep.active;
|
||||
f32 hotkey_hovered = hotkey_rep.hovered;
|
||||
hotkey_color = LerpSrgb(hotkey_color, hovered_color, hotkey_hot);
|
||||
hotkey_color = LerpSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
|
||||
hotkey_border_color = LerpSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot);
|
||||
}
|
||||
|
||||
V_Hotkey hotkey = item->desc.hotkeys[i];
|
||||
if (hotkey.button == Button_None)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
UI_BuildSpacer(UI_PIX(10, 1), Axis_X);
|
||||
|
||||
String hotkey_name = V_StringFromHotkey(UI_FrameArena(), hotkey);
|
||||
UI_SetNext(BackgroundColor, hotkey_color);
|
||||
UI_SetNext(BorderColor, hotkey_border_color);
|
||||
UI_SetNext(Text, hotkey_name);
|
||||
UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1));
|
||||
UI_SetNext(Height, UI_GROW(1, 0));
|
||||
UI_SetNext(Rounding, UI_RPIX(5));
|
||||
UI_SetNext(Border, 1);
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(hotkey_key));
|
||||
{
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
}
|
||||
|
||||
// End spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
UI_PopCP(widget->build.cp);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Vis tick
|
||||
|
||||
@ -610,10 +405,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Process controller events into vis cmds
|
||||
|
||||
u64 cmds_count = 0;
|
||||
V_CmdNode *first_cmd_node = 0;
|
||||
V_CmdNode *last_cmd_node = 0;
|
||||
|
||||
b32 has_mouse_focus = UI_IsKeyNil(ui_frame->hot_box) || UI_MatchKey(ui_frame->hot_box, vis_box);
|
||||
b32 has_keyboard_focus = 1;
|
||||
if (!window_frame.has_focus)
|
||||
@ -685,10 +476,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
if (shortcut != 0 && down)
|
||||
{
|
||||
V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode);
|
||||
cmd_node->cmd.name = shortcut->cmd_name;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++cmds_count;
|
||||
V_PushVisCmd(shortcut->cmd_name);
|
||||
}
|
||||
}
|
||||
frame->held_buttons[hotkey.button] = down;
|
||||
@ -1496,30 +1284,324 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Build command palette
|
||||
|
||||
V_Palette *palette = &frame->palette;
|
||||
{
|
||||
V_BeginPalette(&frame->palette);
|
||||
palette->key = UI_KeyF("command palette");
|
||||
UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey);
|
||||
{
|
||||
// Push cmd items to palette
|
||||
for (u64 i = 0; i < countof(V_cmd_descs); ++i)
|
||||
UI_Push(Tag, palette->key.hash);
|
||||
UI_Key titlebar_key = UI_KeyF("title bar");
|
||||
UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key);
|
||||
UI_Report widget_rep = UI_ReportFromKey(palette->key);
|
||||
Vec2 widget_half_dims = MulVec2(DimsFromRng2(widget_rep.screen_rect), 0.5);
|
||||
|
||||
Vec4 window_background_color = theme.window_background_color;
|
||||
// Vec4 window_background_color = VEC4(0, 0, 0, 0);
|
||||
Vec4 window_border_color = theme.window_border_color;
|
||||
Vec4 titlebar_color = Zi;
|
||||
Vec4 titlebar_border_color = Zi;
|
||||
Vec4 divider_color = theme.divider_color;
|
||||
if (titlebar_rep.m1.held)
|
||||
{
|
||||
V_CmdDesc cmd_desc = V_cmd_descs[i];
|
||||
palette->pos = AddVec2(SubVec2(frame->ui_cursor, titlebar_rep.last_mouse_down_cursor_offset), widget_half_dims);
|
||||
}
|
||||
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
|
||||
|
||||
UI_Push(Scale, LerpF32(0.75, 1, widget_rep.selected));
|
||||
UI_Push(Tint, VEC4(1, 1, 1, widget_rep.selected));
|
||||
if (widget_rep.selected < 0.25)
|
||||
{
|
||||
UI_Push(OmitFlags, UI_UseTop(OmitFlags) | UI_BoxFlag_Interactable);
|
||||
}
|
||||
|
||||
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(Height, UI_SHRINK(0, 0));
|
||||
UI_Push(ChildLayoutAxis, Axis_Y);
|
||||
UI_Push(FloatingPos, SubVec2(palette->pos, widget_half_dims));
|
||||
UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_Selected * frame->show_palette));
|
||||
UI_PushCP(UI_BuildBoxEx(palette->key));
|
||||
{
|
||||
// Title bar
|
||||
UI_PushCP(UI_NilKey);
|
||||
{
|
||||
UI_Push(BackgroundColor, titlebar_color);
|
||||
UI_Push(BorderColor, titlebar_border_color);
|
||||
UI_Push(Rounding, UI_RPIX(0));
|
||||
UI_Push(ChildLayoutAxis, Axis_X);
|
||||
UI_Push(Width, UI_GROW(1, 0));
|
||||
UI_Push(Height, UI_FNT(2, 1));
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildBoxEx(titlebar_key));
|
||||
{
|
||||
UI_Push(Width, UI_GROW(1, 0));
|
||||
UI_Push(BorderColor, 0);
|
||||
|
||||
// Left title box
|
||||
UI_BuildRow();
|
||||
|
||||
// Title box
|
||||
UI_SetNext(FontSize, theme.window_title_font_size);
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||
UI_SetNext(Width, UI_SHRINK(0, 1));
|
||||
UI_SetNext(Text, Lit("Command Palette"));
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText);
|
||||
UI_BuildBox();
|
||||
|
||||
// Right title box
|
||||
UI_BuildRow();
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build palette items list
|
||||
|
||||
f32 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_SetNext(Tint, 0);
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
UI_PushCP(UI_BuildColumn());
|
||||
{
|
||||
Enum(PaletteItemFlag)
|
||||
{
|
||||
PaletteItemFlag_None = 0,
|
||||
PaletteItemFlag_IsCmd = (1 << 0),
|
||||
PaletteItemFlag_IsTweakVar = (2 << 0),
|
||||
};
|
||||
|
||||
Struct(PaletteItem)
|
||||
{
|
||||
PaletteItem *next;
|
||||
PaletteItem *prev;
|
||||
|
||||
UI_Key key;
|
||||
PaletteItemFlag flags;
|
||||
|
||||
V_Hotkey hotkeys[8];
|
||||
String display_name;
|
||||
|
||||
V_CmdDesc cmd_desc;
|
||||
TweakVarDesc tweak_desc;
|
||||
};
|
||||
PaletteItem *first_item = 0;
|
||||
PaletteItem *last_item = 0;
|
||||
|
||||
//////////////////////////////
|
||||
//- Push command items
|
||||
|
||||
{
|
||||
for (u64 cmd_desc_idx = 0; cmd_desc_idx < countof(V_cmd_descs); ++cmd_desc_idx)
|
||||
{
|
||||
V_CmdDesc cmd_desc = V_cmd_descs[cmd_desc_idx];
|
||||
if (!cmd_desc.flags & V_CmdDescFlag_HideFromPalette)
|
||||
{
|
||||
V_PaletteItemDesc item_desc = Zi;
|
||||
item_desc.display_name = cmd_desc.display_name;
|
||||
// FIXME: Attach active shortcuts instead of default hotkeys
|
||||
CopyStructs(item_desc.hotkeys, cmd_desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(cmd_desc.default_hotkeys)));
|
||||
if (V_PushPaletteItem(&frame->palette, item_desc).pressed > 0)
|
||||
PaletteItem *item = PushStruct(frame->arena, PaletteItem);
|
||||
{
|
||||
V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode);
|
||||
cmd_node->cmd.name = cmd_desc.name;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++cmds_count;
|
||||
item->key = UI_KeyF("cmd palette item %F", FmtString(cmd_desc.name));
|
||||
item->display_name = cmd_desc.display_name;
|
||||
item->flags |= PaletteItemFlag_IsCmd;
|
||||
item->cmd_desc = cmd_desc;
|
||||
// FIXME: Attach active shortcuts instead of default hotkeys
|
||||
CopyStructs(item->hotkeys, cmd_desc.default_hotkeys, MinU32(countof(item->hotkeys), countof(cmd_desc.default_hotkeys)));
|
||||
}
|
||||
DllQueuePush(first_item, last_item, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Push tweak variables
|
||||
|
||||
{
|
||||
for (TweakVarKind tweak_var_kind = 0; tweak_var_kind < TweakVarKind_COUNT; ++tweak_var_kind)
|
||||
{
|
||||
TweakVarDesc tweak_desc = TweakVarDescFromKind(tweak_var_kind);
|
||||
PaletteItem *item = PushStruct(frame->arena, PaletteItem);
|
||||
{
|
||||
item->key = UI_KeyF("tweak var palette item %F", FmtString(tweak_desc.name));
|
||||
item->display_name = tweak_desc.name;
|
||||
item->flags |= PaletteItemFlag_IsTweakVar;
|
||||
item->tweak_desc = tweak_desc;
|
||||
}
|
||||
V_EndPalette(&frame->palette);
|
||||
DllQueuePush(first_item, last_item, item);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build items
|
||||
|
||||
TweakVars tweak_vars = GetAllGlobalTweakVars();
|
||||
|
||||
for (PaletteItem *item = first_item; item; item = item->next)
|
||||
{
|
||||
UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y);
|
||||
|
||||
UI_Report item_rep = UI_ReportFromKey(item->key);
|
||||
if (item_rep.m1.presses)
|
||||
{
|
||||
if (item->flags & PaletteItemFlag_IsCmd)
|
||||
{
|
||||
String cmd_name = item->cmd_desc.name;
|
||||
V_PushVisCmd(cmd_name);
|
||||
}
|
||||
}
|
||||
|
||||
Vec4 item_color = theme.window_background_color;
|
||||
item_color = LerpSrgb(item_color, theme.button_hot_color, item_rep.hot);
|
||||
item_color = LerpSrgb(item_color, theme.button_active_color, item_rep.active);
|
||||
Vec4 item_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, item_rep.hot);
|
||||
|
||||
UI_SetNext(BorderColor, 0);
|
||||
UI_SetNext(Rounding, UI_RPIX(0));
|
||||
UI_PushCP(UI_BuildRow());
|
||||
{
|
||||
UI_SetNext(BorderColor, item_border_color);
|
||||
UI_SetNext(BackgroundColor, item_color);
|
||||
UI_SetNext(Rounding, UI_RPIX(5));
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
UI_SetNext(Height, UI_FNT(1.5, 1));
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Left);
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(item->key));
|
||||
{
|
||||
UI_Push(Tag, item->key.hash);
|
||||
|
||||
// Begin spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
|
||||
// Command label
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Left);
|
||||
UI_BuildLabel(item->display_name);
|
||||
|
||||
// Middle spacer
|
||||
UI_BuildSpacer(UI_GROW(1, 0), Axis_X);
|
||||
|
||||
// Tweak
|
||||
if (item->flags & PaletteItemFlag_IsTweakVar)
|
||||
{
|
||||
TweakVarDesc tweak_desc = item->tweak_desc;
|
||||
UI_Key tweak_key = UI_KeyF("tweak");
|
||||
UI_Report tweak_rep = UI_ReportFromKey(tweak_key);
|
||||
|
||||
switch (tweak_desc.type)
|
||||
{
|
||||
// Tweak checkbox
|
||||
case TweakVarType_b32:
|
||||
{
|
||||
b32 *tweak_val = (b32 *)(&tweak_vars + tweak_desc.offset);
|
||||
|
||||
Vec4 tweak_bg_color = Zi;
|
||||
if (*tweak_val)
|
||||
{
|
||||
tweak_bg_color = theme.color_positive;
|
||||
}
|
||||
else
|
||||
{
|
||||
tweak_bg_color = theme.color_negative;
|
||||
}
|
||||
|
||||
Vec4 tweak_border_color = Zi;
|
||||
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);
|
||||
|
||||
if (tweak_rep.m1.downs)
|
||||
{
|
||||
*tweak_val = !*tweak_val;
|
||||
}
|
||||
|
||||
UI_SetNext(BackgroundColor, tweak_bg_color);
|
||||
UI_SetNext(BorderColor, tweak_border_color);
|
||||
UI_SetNext(Rounding, UI_RGROW(0.5));
|
||||
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_PopCP(UI_TopCP());
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// Command hotkey buttons
|
||||
for (u64 i = 0; i < countof(item->hotkeys); ++i)
|
||||
{
|
||||
UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i));
|
||||
UI_Report hotkey_rep = UI_ReportFromKey(hotkey_key);
|
||||
|
||||
Vec4 hotkey_color = Zi;
|
||||
Vec4 hotkey_border_color = Zi;
|
||||
{
|
||||
Vec4 hovered_color = Rgb32(0x103c4c);
|
||||
Vec4 pressed_color = hovered_color;
|
||||
pressed_color.w = 0.2;
|
||||
f32 hotkey_hot = hotkey_rep.hot;
|
||||
f32 hotkey_active = hotkey_rep.active;
|
||||
f32 hotkey_hovered = hotkey_rep.hovered;
|
||||
hotkey_color = LerpSrgb(hotkey_color, hovered_color, hotkey_hot);
|
||||
hotkey_color = LerpSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
|
||||
hotkey_border_color = LerpSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot);
|
||||
}
|
||||
|
||||
V_Hotkey hotkey = item->hotkeys[i];
|
||||
if (hotkey.button == Button_None)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
UI_BuildSpacer(UI_PIX(10, 1), Axis_X);
|
||||
|
||||
String hotkey_name = V_StringFromHotkey(UI_FrameArena(), hotkey);
|
||||
UI_SetNext(BackgroundColor, hotkey_color);
|
||||
UI_SetNext(BorderColor, hotkey_border_color);
|
||||
UI_SetNext(Text, hotkey_name);
|
||||
UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1));
|
||||
UI_SetNext(Height, UI_GROW(1, 0));
|
||||
UI_SetNext(Rounding, UI_RPIX(5));
|
||||
UI_SetNext(Border, 1);
|
||||
UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
|
||||
UI_PushCP(UI_BuildRowEx(hotkey_key));
|
||||
{
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
}
|
||||
|
||||
// End spacer
|
||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
|
||||
SetAllGlobalTweakVars(&tweak_vars);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
|
||||
}
|
||||
UI_PopCP(UI_TopCP());
|
||||
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
}
|
||||
// UI_PopCP(UI_TopCP());
|
||||
UI_PopCP(palette_cp);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -1559,6 +1641,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2I32 tile_pos = S_TilePosFromWorldPos(frame->world_cursor);
|
||||
i32 tile_idx = S_TileIdxFromTilePos(tile_pos);
|
||||
{
|
||||
UI_BuildLabelF("Camera pos: %F", FmtFloat2(frame->camera_pos));
|
||||
UI_BuildLabelF("Cursor world pos: %F", FmtFloat2(frame->world_cursor));
|
||||
UI_BuildLabelF("Cursor tile pos: %F", FmtSint2(tile_pos));
|
||||
UI_BuildLabelF("Cursor tile idx: %F", FmtSint(tile_idx));
|
||||
@ -1740,7 +1823,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Process vis commands
|
||||
|
||||
for (V_CmdNode *cmd_node = first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||
for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||
{
|
||||
String cmd_name = cmd_node->cmd.name;
|
||||
V_CmdKind kind = V_CmdKind_nop;
|
||||
|
||||
@ -36,6 +36,9 @@ Struct(V_WidgetTheme)
|
||||
Vec4 button_active_color;
|
||||
Vec4 button_selected_color;
|
||||
|
||||
Vec4 color_positive;
|
||||
Vec4 color_negative;
|
||||
|
||||
f32 text_padding_x;
|
||||
f32 text_padding_y;
|
||||
};
|
||||
@ -112,41 +115,11 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_COUNT] = {
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Palette types
|
||||
|
||||
Struct(V_PaletteItemReport)
|
||||
{
|
||||
b32 pressed;
|
||||
b32 hotkey_changed;
|
||||
UI_Report ui_report;
|
||||
V_Hotkey new_hotkeys[8];
|
||||
};
|
||||
|
||||
Struct(V_PaletteItemDesc)
|
||||
{
|
||||
String display_name;
|
||||
V_Hotkey hotkeys[8];
|
||||
};
|
||||
|
||||
Struct(V_PaletteItem)
|
||||
{
|
||||
V_PaletteItem *next;
|
||||
UI_Key key;
|
||||
V_PaletteItemDesc desc;
|
||||
};
|
||||
|
||||
Struct(V_Palette)
|
||||
{
|
||||
// Persistent state
|
||||
Vec2 pos;
|
||||
UI_Key key;
|
||||
|
||||
// Per-build state
|
||||
struct
|
||||
{
|
||||
UI_Checkpoint cp;
|
||||
V_PaletteItem *first_item;
|
||||
V_PaletteItem *last_item;
|
||||
u64 num_items;
|
||||
} build;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -264,6 +237,11 @@ Struct(V_Frame)
|
||||
Rng2 draw_selection;
|
||||
Rng2 world_selection;
|
||||
|
||||
// Commands
|
||||
i64 cmds_count;
|
||||
V_CmdNode *first_cmd_node;
|
||||
V_CmdNode *last_cmd_node;
|
||||
|
||||
// Control
|
||||
Vec2 move;
|
||||
Vec2 look;
|
||||
@ -306,6 +284,7 @@ void V_Shutdown(void);
|
||||
|
||||
V_Frame *V_CurrentFrame(void);
|
||||
V_Frame *V_LastFrame(void);
|
||||
V_Cmd *V_PushVisCmd(String name);
|
||||
S_Cmd *V_PushSimCmd(S_CmdKind kind);
|
||||
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
|
||||
|
||||
@ -315,13 +294,6 @@ String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
|
||||
V_WidgetTheme V_GetWidgetTheme(void);
|
||||
void V_PushWidgetThemeStyles(V_WidgetTheme theme);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Palette
|
||||
|
||||
void V_BeginPalette(V_Palette *widget);
|
||||
V_PaletteItemReport V_PushPaletteItem(V_Palette *widget, V_PaletteItemDesc desc);
|
||||
void V_EndPalette(V_Palette *widget);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Vis tick
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user