merge vis widgets w/ core
This commit is contained in:
parent
ec0f11d220
commit
7531e18245
@ -26,7 +26,6 @@
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Api
|
//- Api
|
||||||
|
|
||||||
@IncludeC pp_vis_widgets.h
|
|
||||||
@IncludeC pp_vis_shaders.cgh
|
@IncludeC pp_vis_shaders.cgh
|
||||||
@IncludeC pp_vis_draw.h
|
@IncludeC pp_vis_draw.h
|
||||||
@IncludeC pp_vis_core.h
|
@IncludeC pp_vis_core.h
|
||||||
@ -39,7 +38,6 @@
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Impl
|
//- Impl
|
||||||
|
|
||||||
@IncludeC pp_vis_widgets.c
|
|
||||||
@IncludeC pp_vis_draw.c
|
@IncludeC pp_vis_draw.c
|
||||||
@IncludeC pp_vis_core.c
|
@IncludeC pp_vis_core.c
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,287 @@ S_Cmd *V_PushSimCmd(S_CmdKind kind)
|
|||||||
return &n->cmd;
|
return &n->cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey)
|
||||||
|
{
|
||||||
|
TempArena scratch = BeginScratch(arena);
|
||||||
|
StringList parts = Zi;
|
||||||
|
if (hotkey.ctrl)
|
||||||
|
{
|
||||||
|
PushStringToList(scratch.arena, &parts, Lit("Ctrl"));
|
||||||
|
}
|
||||||
|
if (hotkey.alt)
|
||||||
|
{
|
||||||
|
PushStringToList(scratch.arena, &parts, Lit("Alt"));
|
||||||
|
}
|
||||||
|
if (hotkey.shift)
|
||||||
|
{
|
||||||
|
PushStringToList(scratch.arena, &parts, Lit("Shift"));
|
||||||
|
}
|
||||||
|
PushStringToList(scratch.arena, &parts, StringFromButton(hotkey.button));
|
||||||
|
EndScratch(scratch);
|
||||||
|
return StringFromList(arena, parts, Lit(" + "));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Theme
|
||||||
|
|
||||||
|
V_WidgetTheme V_GetWidgetTheme(void)
|
||||||
|
{
|
||||||
|
V_WidgetTheme theme = Zi;
|
||||||
|
|
||||||
|
theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")));
|
||||||
|
theme.font_size = 16;
|
||||||
|
|
||||||
|
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")));
|
||||||
|
// theme.font_size = 64;
|
||||||
|
|
||||||
|
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/roboto-med.ttf")));
|
||||||
|
// theme.font_size = 100;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
theme.window_title_font_size = 16;
|
||||||
|
theme.text_padding_x = 3;
|
||||||
|
theme.text_padding_y = 3;
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V_PushWidgetThemeStyles(V_WidgetTheme theme)
|
||||||
|
{
|
||||||
|
UI_Push(Font, theme.font);
|
||||||
|
UI_Push(FontSize, theme.font_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Commands widget
|
||||||
|
|
||||||
|
void V_BeginCommandsWidget(V_CommandsWidget *widget)
|
||||||
|
{
|
||||||
|
ZeroStruct(&widget->build);
|
||||||
|
widget->build.cp = UI_PushCP(UI_NilKey);
|
||||||
|
UI_Push(Tag, HashF("commands widget"));
|
||||||
|
}
|
||||||
|
|
||||||
|
V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc)
|
||||||
|
{
|
||||||
|
Arena *frame_arena = UI_FrameArena();
|
||||||
|
|
||||||
|
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
|
||||||
|
{
|
||||||
|
V_CommandsWidgetItem *item = PushStruct(frame_arena, V_CommandsWidgetItem);
|
||||||
|
item->key = key;
|
||||||
|
item->desc = desc;
|
||||||
|
SllQueuePush(widget->build.first_item, widget->build.last_item, item);
|
||||||
|
++widget->build.num_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_CommandsWidgetItemReport 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_EndCommandsWidget(V_CommandsWidget *widget)
|
||||||
|
{
|
||||||
|
V_WidgetTheme theme = V_GetWidgetTheme();
|
||||||
|
Vec2 cursor_pos = UI_CursorPos();
|
||||||
|
|
||||||
|
UI_Push(Tag, HashF("commands widget"));
|
||||||
|
|
||||||
|
UI_Key titlebar_key = UI_KeyF("title bar");
|
||||||
|
|
||||||
|
Vec4 window_background_color = theme.window_background_color;
|
||||||
|
Vec4 window_border_color = theme.window_border_color;
|
||||||
|
Vec4 titlebar_color = Zi;
|
||||||
|
Vec4 titlebar_border_color = Zi;
|
||||||
|
Vec4 divider_color = theme.divider_color;
|
||||||
|
{
|
||||||
|
UI_Report rep = UI_ReportFromKey(titlebar_key);
|
||||||
|
if (rep.m1_held)
|
||||||
|
{
|
||||||
|
widget->pos = SubVec2(cursor_pos, rep.last_m1_offset);
|
||||||
|
}
|
||||||
|
// window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot);
|
||||||
|
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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, widget->pos);
|
||||||
|
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
||||||
|
UI_PushCP(UI_BuildBoxEx(UI_KeyF("titlebar")));
|
||||||
|
{
|
||||||
|
/* 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("Commands"));
|
||||||
|
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_CommandsWidgetItem *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;
|
||||||
|
Vec4 btn_border_color = Zi;
|
||||||
|
{
|
||||||
|
Vec4 hovered_color = Rgb32(0x103c4c);
|
||||||
|
Vec4 pressed_color = hovered_color;
|
||||||
|
pressed_color.w = 0.2;
|
||||||
|
f32 btn_hot = btn_rep.hot;
|
||||||
|
f32 btn_active = btn_rep.active;
|
||||||
|
f32 btn_hovered = btn_rep.hovered;
|
||||||
|
btn_color = BlendSrgb(btn_color, hovered_color, btn_hot);
|
||||||
|
btn_color = BlendSrgb(btn_color, pressed_color, btn_active * btn_hovered);
|
||||||
|
btn_border_color = BlendSrgb(btn_border_color, Rgb32(0x0078a6), btn_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_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 = BlendSrgb(hotkey_color, hovered_color, hotkey_hot);
|
||||||
|
hotkey_color = BlendSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
|
||||||
|
hotkey_border_color = BlendSrgb(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
|
//~ Vis tick
|
||||||
|
|
||||||
@ -43,8 +324,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
const i32 world_size = S_WorldSize;
|
const i32 world_size = S_WorldSize;
|
||||||
const f32 zoom_rate = 1.50;
|
const f32 zoom_rate = 1.50;
|
||||||
const f32 min_zoom = 0.03;
|
const f32 min_zoom = 0.03;
|
||||||
const f32 max_zoom = 10.0;
|
const f32 max_zoom = 15.0;
|
||||||
const f32 meters_per_draw_width = 20;
|
const f32 meters_per_draw_width = 18;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Init vis state
|
//- Init vis state
|
||||||
@ -205,7 +486,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
ent->local_shape = S_ShapeFromDesc(
|
ent->local_shape = S_ShapeFromDesc(
|
||||||
.mass = 10,
|
.mass = 10,
|
||||||
.count = 1,
|
.count = 1,
|
||||||
.radius = 0.4,
|
.radius = 0.3,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// ent->local_xf = XformFromPos(VEC2(200, 200));
|
// ent->local_xf = XformFromPos(VEC2(200, 200));
|
||||||
@ -508,6 +789,21 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Build editor UI
|
||||||
|
|
||||||
|
// if (frame->is_editing)
|
||||||
|
// {
|
||||||
|
// UI_SetNext(BackgroundColor, VEC4(0, 0, 0, 1));
|
||||||
|
// UI_SetNext(Width, UI_SHRINK(0, 1));
|
||||||
|
// UI_SetNext(Height, UI_SHRINK(0, 1));
|
||||||
|
// UI_PushCP(UI_BuildRow());
|
||||||
|
// {
|
||||||
|
// UI_BuildLabelF("Tiles");
|
||||||
|
// }
|
||||||
|
// UI_PopCP(UI_TopCP());
|
||||||
|
// }
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Build command palette
|
//- Build command palette
|
||||||
|
|
||||||
@ -540,10 +836,143 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Build console UI
|
//- Build console UI
|
||||||
|
|
||||||
|
/* TODO: Remove this whole thing */
|
||||||
if (frame->show_console)
|
if (frame->show_console)
|
||||||
{
|
{
|
||||||
b32 minimized = 0;
|
b32 minimized = 0;
|
||||||
V_BuildConsoleWidget(minimized);
|
|
||||||
|
// i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug;
|
||||||
|
i32 console_level = LogLevel_Debug;
|
||||||
|
|
||||||
|
Vec4 colors[LogLevel_Count][2] = Zi;
|
||||||
|
SetBytes(colors, 0xFF, sizeof(colors));
|
||||||
|
/* Debug colors */
|
||||||
|
colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4);
|
||||||
|
colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5);
|
||||||
|
/* Info colors */
|
||||||
|
colors[LogLevel_Info][0] = Rgb(0.4, 0.4, 0.4);
|
||||||
|
colors[LogLevel_Info][1] = Rgb(0.5, 0.5, 0.5);
|
||||||
|
/* Success colors */
|
||||||
|
colors[LogLevel_Success][0] = Rgb(0.1, 0.3, 0.1);
|
||||||
|
colors[LogLevel_Success][1] = Rgb(0.2, 0.4, 0.2);
|
||||||
|
/* Warning colors */
|
||||||
|
colors[LogLevel_Warning][0] = Rgb(0.4, 0.4, 0.1);
|
||||||
|
colors[LogLevel_Warning][1] = Rgb(0.5, 0.5, 0.2);
|
||||||
|
/* Error colors */
|
||||||
|
colors[LogLevel_Error][0] = Rgb(0.4, 0.1, 0.1);
|
||||||
|
colors[LogLevel_Error][1] = Rgb(0.5, 0.2, 0.2);
|
||||||
|
|
||||||
|
i64 max_time_ns = I64Max;
|
||||||
|
i64 fade_time_ns = max_time_ns;
|
||||||
|
if (minimized)
|
||||||
|
{
|
||||||
|
max_time_ns = NsFromSeconds(10);
|
||||||
|
fade_time_ns = max_time_ns;
|
||||||
|
}
|
||||||
|
f32 fade_curve = 0.5;
|
||||||
|
|
||||||
|
i64 now_ns = TimeNs();
|
||||||
|
UI_Key console_box = Zi;
|
||||||
|
{
|
||||||
|
UI_Push(FloatingPos, VEC2(0, 0));
|
||||||
|
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
||||||
|
UI_SetNext(Border, 0);
|
||||||
|
if (minimized)
|
||||||
|
{
|
||||||
|
UI_SetNext(BackgroundColor, 0);
|
||||||
|
UI_SetNext(Width, UI_PIX(500, 0));
|
||||||
|
UI_SetNext(Height, UI_SHRINK(0, 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UI_SetNext(BackgroundColor, Rgba(1, 1, 1, 0.02));
|
||||||
|
UI_SetNext(Width, UI_GROW(1, 0));
|
||||||
|
UI_SetNext(Height, UI_SHRINK(0, 1));
|
||||||
|
}
|
||||||
|
console_box = UI_BuildColumnEx(UI_KeyF("Console box"));
|
||||||
|
UI_PushCP(console_box);
|
||||||
|
{
|
||||||
|
/* Gather display logs */
|
||||||
|
u64 max = 20;
|
||||||
|
u64 display_count = 0;
|
||||||
|
LogEvent *display_logs = PushStructs(frame->arena, LogEvent, max);
|
||||||
|
{
|
||||||
|
b32 done = 0;
|
||||||
|
if (minimized)
|
||||||
|
{
|
||||||
|
max = 5;
|
||||||
|
}
|
||||||
|
LogEventsArray logs = GetLogEvents();
|
||||||
|
for (u64 i = logs.count; i-- > 0 && display_count < max && !done;)
|
||||||
|
{
|
||||||
|
LogEvent ev = logs.logs[i];
|
||||||
|
if (ev.time_ns > (now_ns - max_time_ns))
|
||||||
|
{
|
||||||
|
if (ev.level <= console_level)
|
||||||
|
{
|
||||||
|
display_logs[display_count] = ev;
|
||||||
|
++display_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Display logs in reverse */
|
||||||
|
for (u64 i = display_count; i-- > 0;)
|
||||||
|
{
|
||||||
|
LogEvent log = display_logs[i];
|
||||||
|
f32 opacity = 0.75;
|
||||||
|
f32 lin = 1.0 - ClampF64((f64)(now_ns - log.time_ns) / (f64)fade_time_ns, 0, 1);
|
||||||
|
opacity *= PowF32(lin, fade_curve);
|
||||||
|
String text = log.msg;
|
||||||
|
if (!minimized)
|
||||||
|
{
|
||||||
|
DateTime datetime = log.datetime;
|
||||||
|
text = StringF(
|
||||||
|
frame->arena,
|
||||||
|
"[%F:%F:%F.%F] %F",
|
||||||
|
FmtUint(datetime.hour, .z = 2),
|
||||||
|
FmtUint(datetime.minute, .z = 2),
|
||||||
|
FmtUint(datetime.second, .z = 2),
|
||||||
|
FmtUint(datetime.milliseconds, .z = 3),
|
||||||
|
FmtString(text));
|
||||||
|
}
|
||||||
|
UI_PushCP(UI_NilKey);
|
||||||
|
{
|
||||||
|
Vec4 tint = VEC4(1, 1, 1, opacity);
|
||||||
|
UI_Push(Tint, tint);
|
||||||
|
{
|
||||||
|
Vec4 color = colors[log.level][log.level_id % 2];
|
||||||
|
UI_Push(BackgroundColor, color);
|
||||||
|
UI_Push(Width, UI_GROW(1, 0));
|
||||||
|
UI_Push(Height, UI_FNT(1.5, 1));
|
||||||
|
UI_Push(BorderColor, Rgb(0.25, 0.25, 0.25));
|
||||||
|
UI_Push(Rounding, UI_RPIX(0));
|
||||||
|
UI_Push(Border, 1);
|
||||||
|
UI_Push(ChildAlignment, UI_Alignment_Left);
|
||||||
|
UI_PushCP(UI_BuildRow());
|
||||||
|
{
|
||||||
|
// UI_SetNext(Height, UI_PIX(100, 0));
|
||||||
|
UI_BuildSpacer(UI_PIX(10, 0), Axis_X);
|
||||||
|
UI_Push(BackgroundColor, 0);
|
||||||
|
UI_Push(Border, 0);
|
||||||
|
UI_Push(Text, text);
|
||||||
|
UI_Push(Width, UI_GROW(1, 0));
|
||||||
|
UI_Push(Height, UI_SHRINK(0, 1));
|
||||||
|
UI_Push(Flags, UI_BoxFlag_DrawText);
|
||||||
|
UI_BuildBox();
|
||||||
|
}
|
||||||
|
UI_PopCP(UI_TopCP());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI_PopCP(UI_TopCP());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI_PopCP(UI_TopCP());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -616,13 +1045,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
UI_PopCP(UI_TopCP());
|
UI_PopCP(UI_TopCP());
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Build edit mode UI
|
|
||||||
|
|
||||||
if (frame->is_editing)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process vis commands
|
//- Process vis commands
|
||||||
|
|
||||||
@ -804,7 +1226,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
Vec4 color = Color_Cyan;
|
Vec4 color = Color_Cyan;
|
||||||
f32 width = 0.1;
|
f32 width = 0.1;
|
||||||
f32 height = 1;
|
f32 height = 0.75;
|
||||||
S_Shape local_shape = S_ShapeFromDesc(
|
S_Shape local_shape = S_ShapeFromDesc(
|
||||||
.count = 4,
|
.count = 4,
|
||||||
.points = {
|
.points = {
|
||||||
|
|||||||
@ -15,6 +15,38 @@
|
|||||||
X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \
|
X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \
|
||||||
/* -------------------------------------------------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Theme types
|
||||||
|
|
||||||
|
Struct(V_WidgetTheme)
|
||||||
|
{
|
||||||
|
GC_FontKey font;
|
||||||
|
f32 font_size;
|
||||||
|
f32 window_title_font_size;
|
||||||
|
|
||||||
|
Vec4 window_background_color;
|
||||||
|
Vec4 window_border_color;
|
||||||
|
Vec4 divider_color;
|
||||||
|
f32 window_border;
|
||||||
|
f32 window_padding;
|
||||||
|
f32 window_width;
|
||||||
|
|
||||||
|
f32 text_padding_x;
|
||||||
|
f32 text_padding_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Hotkey types
|
||||||
|
|
||||||
|
#define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
|
||||||
|
Struct(V_Hotkey)
|
||||||
|
{
|
||||||
|
Button button;
|
||||||
|
b32 ctrl;
|
||||||
|
b32 alt;
|
||||||
|
b32 shift;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Command types
|
//~ Command types
|
||||||
|
|
||||||
@ -73,6 +105,45 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_Count] = {
|
|||||||
#undef X
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Commands widget types
|
||||||
|
|
||||||
|
Struct(V_CommandsWidgetItemReport)
|
||||||
|
{
|
||||||
|
b32 pressed;
|
||||||
|
b32 hotkey_changed;
|
||||||
|
UI_Report ui_report;
|
||||||
|
V_Hotkey new_hotkeys[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(V_CommandsWidgetItemDesc)
|
||||||
|
{
|
||||||
|
String display_name;
|
||||||
|
V_Hotkey hotkeys[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(V_CommandsWidgetItem)
|
||||||
|
{
|
||||||
|
V_CommandsWidgetItem *next;
|
||||||
|
UI_Key key;
|
||||||
|
V_CommandsWidgetItemDesc desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(V_CommandsWidget)
|
||||||
|
{
|
||||||
|
/* Persistent state */
|
||||||
|
Vec2 pos;
|
||||||
|
|
||||||
|
/* Per-build state */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UI_Checkpoint cp;
|
||||||
|
V_CommandsWidgetItem *first_item;
|
||||||
|
V_CommandsWidgetItem *last_item;
|
||||||
|
u64 num_items;
|
||||||
|
} build;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Context types
|
//~ Context types
|
||||||
|
|
||||||
@ -182,6 +253,20 @@ void V_Shutdown(void);
|
|||||||
|
|
||||||
V_Frame *V_CurrentFrame(void);
|
V_Frame *V_CurrentFrame(void);
|
||||||
S_Cmd *V_PushSimCmd(S_CmdKind kind);
|
S_Cmd *V_PushSimCmd(S_CmdKind kind);
|
||||||
|
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Theme
|
||||||
|
|
||||||
|
V_WidgetTheme V_GetWidgetTheme(void);
|
||||||
|
void V_PushWidgetThemeStyles(V_WidgetTheme theme);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Commands widget
|
||||||
|
|
||||||
|
void V_BeginCommandsWidget(V_CommandsWidget *widget);
|
||||||
|
V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc);
|
||||||
|
void V_EndCommandsWidget(V_CommandsWidget *widget);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Vis tick
|
//~ Vis tick
|
||||||
|
|||||||
@ -14,22 +14,21 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1));
|
const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1));
|
||||||
const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1));
|
const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1));
|
||||||
|
|
||||||
Vec2U32 target_pos = SV_DispatchThreadID;
|
Vec2 screen_pos = Vec2(SV_DispatchThreadID) + Vec2(0.5, 0.5);
|
||||||
Vec2I32 target_size = params.target_size;
|
if (screen_pos.x < params.target_size.x && screen_pos.y < params.target_size.y)
|
||||||
if (target_pos.x < target_size.x && target_pos.y < target_size.y)
|
|
||||||
{
|
{
|
||||||
Vec4 result = Vec4(0.025, 0.025, 0.025, 1);
|
Vec4 result = Vec4(0.025, 0.025, 0.025, 1);
|
||||||
Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(target_pos, 1));
|
Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1));
|
||||||
Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos);
|
Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos);
|
||||||
|
|
||||||
f32 half_thickness = 1;
|
f32 half_thickness = 1;
|
||||||
f32 half_bounds_size = params.world_size * 0.5;
|
f32 half_bounds_size = params.world_size * 0.5;
|
||||||
Vec2 bounds_screen_p0 = mul(params.world_to_draw_xf, Vec3(-half_bounds_size, -half_bounds_size, 1));
|
Vec2 bounds_screen_p0 = mul(params.world_to_draw_xf, Vec3(-half_bounds_size, -half_bounds_size, 1));
|
||||||
Vec2 bounds_screen_p1 = mul(params.world_to_draw_xf, Vec3(half_bounds_size, half_bounds_size, 1));
|
Vec2 bounds_screen_p1 = mul(params.world_to_draw_xf, Vec3(half_bounds_size, half_bounds_size, 1));
|
||||||
b32 is_in_bounds = target_pos.x > (bounds_screen_p0.x - half_thickness) &&
|
b32 is_in_bounds = screen_pos.x > (bounds_screen_p0.x - half_thickness) &&
|
||||||
target_pos.y > (bounds_screen_p0.y - half_thickness) &&
|
screen_pos.y > (bounds_screen_p0.y - half_thickness) &&
|
||||||
target_pos.x < (bounds_screen_p1.x + half_thickness) &&
|
screen_pos.x < (bounds_screen_p1.x + half_thickness) &&
|
||||||
target_pos.y < (bounds_screen_p1.y + half_thickness);
|
screen_pos.y < (bounds_screen_p1.y + half_thickness);
|
||||||
if (is_in_bounds)
|
if (is_in_bounds)
|
||||||
{
|
{
|
||||||
/* Grid checker */
|
/* Grid checker */
|
||||||
@ -64,10 +63,10 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
Vec2 grid_screen_p0 = mul(params.world_to_draw_xf, Vec3(floor(world_pos), 1));
|
Vec2 grid_screen_p0 = mul(params.world_to_draw_xf, Vec3(floor(world_pos), 1));
|
||||||
Vec2 grid_screen_p1 = mul(params.world_to_draw_xf, Vec3(ceil(world_pos), 1));
|
Vec2 grid_screen_p1 = mul(params.world_to_draw_xf, Vec3(ceil(world_pos), 1));
|
||||||
f32 grid_dist = 100000;
|
f32 grid_dist = 100000;
|
||||||
grid_dist = min(grid_dist, abs(target_pos.x - grid_screen_p0.x));
|
grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p0.x));
|
||||||
grid_dist = min(grid_dist, abs(target_pos.x - grid_screen_p1.x));
|
grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p1.x));
|
||||||
grid_dist = min(grid_dist, abs(target_pos.y - grid_screen_p0.y));
|
grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p0.y));
|
||||||
grid_dist = min(grid_dist, abs(target_pos.y - grid_screen_p1.y));
|
grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p1.y));
|
||||||
if (grid_dist <= half_thickness)
|
if (grid_dist <= half_thickness)
|
||||||
{
|
{
|
||||||
result = grid_color;
|
result = grid_color;
|
||||||
@ -93,10 +92,9 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
}
|
}
|
||||||
/* Axis */
|
/* Axis */
|
||||||
{
|
{
|
||||||
f32 half_thickness = 1;
|
|
||||||
Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1));
|
Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1));
|
||||||
f32 x_dist = abs(target_pos.x - zero_screen.x);
|
f32 x_dist = abs(screen_pos.x - zero_screen.x);
|
||||||
f32 y_dist = abs(target_pos.y - zero_screen.y);
|
f32 y_dist = abs(screen_pos.y - zero_screen.y);
|
||||||
if (y_dist <= half_thickness)
|
if (y_dist <= half_thickness)
|
||||||
{
|
{
|
||||||
result = x_axis_color;
|
result = x_axis_color;
|
||||||
@ -109,10 +107,10 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
/* World bounds */
|
/* World bounds */
|
||||||
{
|
{
|
||||||
f32 bounds_dist = 100000;
|
f32 bounds_dist = 100000;
|
||||||
bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p0.x));
|
bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p0.x));
|
||||||
bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p1.x));
|
bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p1.x));
|
||||||
bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p0.y));
|
bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p0.y));
|
||||||
bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p1.y));
|
bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p1.y));
|
||||||
if (bounds_dist <= half_thickness)
|
if (bounds_dist <= half_thickness)
|
||||||
{
|
{
|
||||||
result = bounds_color;
|
result = bounds_color;
|
||||||
@ -121,7 +119,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
target[target_pos] = result;
|
target[trunc(screen_pos)] = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +246,7 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input)
|
|||||||
dist = min(dist, screen_selection.p1.y - screen_pos.y);
|
dist = min(dist, screen_selection.p1.y - screen_pos.y);
|
||||||
dist = -dist;
|
dist = -dist;
|
||||||
|
|
||||||
// if (dist > -half_thickness && dist < half_thickness)
|
// if (dist >= -half_thickness && dist <= half_thickness)
|
||||||
// {
|
// {
|
||||||
// result = border_color;
|
// result = border_color;
|
||||||
// }
|
// }
|
||||||
|
|||||||
@ -1,426 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Theme helpers
|
|
||||||
|
|
||||||
V_WidgetTheme V_GetWidgetTheme(void)
|
|
||||||
{
|
|
||||||
V_WidgetTheme theme = Zi;
|
|
||||||
|
|
||||||
theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")));
|
|
||||||
theme.font_size = 16;
|
|
||||||
|
|
||||||
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")));
|
|
||||||
// theme.font_size = 64;
|
|
||||||
|
|
||||||
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/roboto-med.ttf")));
|
|
||||||
// theme.font_size = 100;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
theme.window_title_font_size = 16;
|
|
||||||
theme.text_padding_x = 3;
|
|
||||||
theme.text_padding_y = 3;
|
|
||||||
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
void V_PushWidgetThemeStyles(V_WidgetTheme theme)
|
|
||||||
{
|
|
||||||
UI_Push(Font, theme.font);
|
|
||||||
UI_Push(FontSize, theme.font_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Hotkey helpers
|
|
||||||
|
|
||||||
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey)
|
|
||||||
{
|
|
||||||
TempArena scratch = BeginScratch(arena);
|
|
||||||
StringList parts = Zi;
|
|
||||||
if (hotkey.ctrl)
|
|
||||||
{
|
|
||||||
PushStringToList(scratch.arena, &parts, Lit("Ctrl"));
|
|
||||||
}
|
|
||||||
if (hotkey.alt)
|
|
||||||
{
|
|
||||||
PushStringToList(scratch.arena, &parts, Lit("Alt"));
|
|
||||||
}
|
|
||||||
if (hotkey.shift)
|
|
||||||
{
|
|
||||||
PushStringToList(scratch.arena, &parts, Lit("Shift"));
|
|
||||||
}
|
|
||||||
PushStringToList(scratch.arena, &parts, StringFromButton(hotkey.button));
|
|
||||||
EndScratch(scratch);
|
|
||||||
return StringFromList(arena, parts, Lit(" + "));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Commands widget
|
|
||||||
|
|
||||||
void V_BeginCommandsWidget(V_CommandsWidget *widget)
|
|
||||||
{
|
|
||||||
ZeroStruct(&widget->build);
|
|
||||||
widget->build.cp = UI_PushCP(UI_NilKey);
|
|
||||||
UI_Push(Tag, HashF("commands widget"));
|
|
||||||
}
|
|
||||||
|
|
||||||
V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc)
|
|
||||||
{
|
|
||||||
Arena *frame_arena = UI_FrameArena();
|
|
||||||
|
|
||||||
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
|
|
||||||
{
|
|
||||||
V_CommandsWidgetItem *item = PushStruct(frame_arena, V_CommandsWidgetItem);
|
|
||||||
item->key = key;
|
|
||||||
item->desc = desc;
|
|
||||||
SllQueuePush(widget->build.first_item, widget->build.last_item, item);
|
|
||||||
++widget->build.num_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
V_CommandsWidgetItemReport 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_EndCommandsWidget(V_CommandsWidget *widget)
|
|
||||||
{
|
|
||||||
V_WidgetTheme theme = V_GetWidgetTheme();
|
|
||||||
Vec2 cursor_pos = UI_CursorPos();
|
|
||||||
|
|
||||||
UI_Push(Tag, HashF("commands widget"));
|
|
||||||
|
|
||||||
UI_Key titlebar_key = UI_KeyF("title bar");
|
|
||||||
|
|
||||||
Vec4 window_background_color = theme.window_background_color;
|
|
||||||
Vec4 window_border_color = theme.window_border_color;
|
|
||||||
Vec4 titlebar_color = Zi;
|
|
||||||
Vec4 titlebar_border_color = Zi;
|
|
||||||
Vec4 divider_color = theme.divider_color;
|
|
||||||
{
|
|
||||||
UI_Report rep = UI_ReportFromKey(titlebar_key);
|
|
||||||
if (rep.m1_held)
|
|
||||||
{
|
|
||||||
widget->pos = SubVec2(cursor_pos, rep.last_m1_offset);
|
|
||||||
}
|
|
||||||
// window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot);
|
|
||||||
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(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, widget->pos);
|
|
||||||
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
|
||||||
UI_PushCP(UI_BuildBoxEx(UI_KeyF("titlebar")));
|
|
||||||
{
|
|
||||||
/* 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("Commands"));
|
|
||||||
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_CommandsWidgetItem *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;
|
|
||||||
Vec4 btn_border_color = Zi;
|
|
||||||
{
|
|
||||||
Vec4 hovered_color = Rgb32(0x103c4c);
|
|
||||||
Vec4 pressed_color = hovered_color;
|
|
||||||
pressed_color.w = 0.2;
|
|
||||||
f32 btn_hot = btn_rep.hot;
|
|
||||||
f32 btn_active = btn_rep.active;
|
|
||||||
f32 btn_hovered = btn_rep.hovered;
|
|
||||||
btn_color = BlendSrgb(btn_color, hovered_color, btn_hot);
|
|
||||||
btn_color = BlendSrgb(btn_color, pressed_color, btn_active * btn_hovered);
|
|
||||||
btn_border_color = BlendSrgb(btn_border_color, Rgb32(0x0078a6), btn_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_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 = BlendSrgb(hotkey_color, hovered_color, hotkey_hot);
|
|
||||||
hotkey_color = BlendSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
|
|
||||||
hotkey_border_color = BlendSrgb(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Console widget
|
|
||||||
|
|
||||||
UI_Key V_BuildConsoleWidget(b32 minimized)
|
|
||||||
{
|
|
||||||
/* TODO: Remove this whole thing */
|
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
|
||||||
|
|
||||||
// i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug;
|
|
||||||
i32 console_level = LogLevel_Debug;
|
|
||||||
|
|
||||||
Vec4 colors[LogLevel_Count][2] = Zi;
|
|
||||||
SetBytes(colors, 0xFF, sizeof(colors));
|
|
||||||
/* Debug colors */
|
|
||||||
colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4);
|
|
||||||
colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5);
|
|
||||||
/* Info colors */
|
|
||||||
colors[LogLevel_Info][0] = Rgb(0.4, 0.4, 0.4);
|
|
||||||
colors[LogLevel_Info][1] = Rgb(0.5, 0.5, 0.5);
|
|
||||||
/* Success colors */
|
|
||||||
colors[LogLevel_Success][0] = Rgb(0.1, 0.3, 0.1);
|
|
||||||
colors[LogLevel_Success][1] = Rgb(0.2, 0.4, 0.2);
|
|
||||||
/* Warning colors */
|
|
||||||
colors[LogLevel_Warning][0] = Rgb(0.4, 0.4, 0.1);
|
|
||||||
colors[LogLevel_Warning][1] = Rgb(0.5, 0.5, 0.2);
|
|
||||||
/* Error colors */
|
|
||||||
colors[LogLevel_Error][0] = Rgb(0.4, 0.1, 0.1);
|
|
||||||
colors[LogLevel_Error][1] = Rgb(0.5, 0.2, 0.2);
|
|
||||||
|
|
||||||
i64 max_time_ns = I64Max;
|
|
||||||
i64 fade_time_ns = max_time_ns;
|
|
||||||
if (minimized)
|
|
||||||
{
|
|
||||||
max_time_ns = NsFromSeconds(10);
|
|
||||||
fade_time_ns = max_time_ns;
|
|
||||||
}
|
|
||||||
f32 fade_curve = 0.5;
|
|
||||||
|
|
||||||
i64 now_ns = TimeNs();
|
|
||||||
UI_Key console_box = Zi;
|
|
||||||
{
|
|
||||||
UI_SetNext(Border, 0);
|
|
||||||
if (minimized)
|
|
||||||
{
|
|
||||||
UI_SetNext(BackgroundColor, 0);
|
|
||||||
UI_SetNext(Width, UI_PIX(500, 0));
|
|
||||||
UI_SetNext(Height, UI_SHRINK(0, 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UI_SetNext(BackgroundColor, Rgba(1, 1, 1, 0.02));
|
|
||||||
UI_SetNext(Width, UI_GROW(1, 0));
|
|
||||||
UI_SetNext(Height, UI_SHRINK(0, 1));
|
|
||||||
}
|
|
||||||
console_box = UI_BuildColumnEx(UI_KeyF("Console box"));
|
|
||||||
UI_PushCP(console_box);
|
|
||||||
{
|
|
||||||
/* Gather display logs */
|
|
||||||
u64 max = 20;
|
|
||||||
u64 display_count = 0;
|
|
||||||
LogEvent *display_logs = PushStructs(scratch.arena, LogEvent, max);
|
|
||||||
{
|
|
||||||
b32 done = 0;
|
|
||||||
if (minimized)
|
|
||||||
{
|
|
||||||
max = 5;
|
|
||||||
}
|
|
||||||
LogEventsArray logs = GetLogEvents();
|
|
||||||
for (u64 i = logs.count; i-- > 0 && display_count < max && !done;)
|
|
||||||
{
|
|
||||||
LogEvent ev = logs.logs[i];
|
|
||||||
if (ev.time_ns > (now_ns - max_time_ns))
|
|
||||||
{
|
|
||||||
if (ev.level <= console_level)
|
|
||||||
{
|
|
||||||
display_logs[display_count] = ev;
|
|
||||||
++display_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Display logs in reverse */
|
|
||||||
for (u64 i = display_count; i-- > 0;)
|
|
||||||
{
|
|
||||||
LogEvent log = display_logs[i];
|
|
||||||
f32 opacity = 0.75;
|
|
||||||
f32 lin = 1.0 - ClampF64((f64)(now_ns - log.time_ns) / (f64)fade_time_ns, 0, 1);
|
|
||||||
opacity *= PowF32(lin, fade_curve);
|
|
||||||
String text = log.msg;
|
|
||||||
if (!minimized)
|
|
||||||
{
|
|
||||||
DateTime datetime = log.datetime;
|
|
||||||
text = StringF(
|
|
||||||
scratch.arena,
|
|
||||||
"[%F:%F:%F.%F] %F",
|
|
||||||
FmtUint(datetime.hour, .z = 2),
|
|
||||||
FmtUint(datetime.minute, .z = 2),
|
|
||||||
FmtUint(datetime.second, .z = 2),
|
|
||||||
FmtUint(datetime.milliseconds, .z = 3),
|
|
||||||
FmtString(text));
|
|
||||||
}
|
|
||||||
UI_PushCP(UI_NilKey);
|
|
||||||
{
|
|
||||||
Vec4 tint = VEC4(1, 1, 1, opacity);
|
|
||||||
UI_Push(Tint, tint);
|
|
||||||
{
|
|
||||||
Vec4 color = colors[log.level][log.level_id % 2];
|
|
||||||
UI_Push(BackgroundColor, color);
|
|
||||||
UI_Push(Width, UI_GROW(1, 0));
|
|
||||||
UI_Push(Height, UI_FNT(1.5, 1));
|
|
||||||
UI_Push(BorderColor, Rgb(0.25, 0.25, 0.25));
|
|
||||||
UI_Push(Rounding, UI_RPIX(0));
|
|
||||||
UI_Push(Border, 1);
|
|
||||||
UI_Push(ChildAlignment, UI_Alignment_Left);
|
|
||||||
UI_PushCP(UI_BuildRow());
|
|
||||||
{
|
|
||||||
// UI_SetNext(Height, UI_PIX(100, 0));
|
|
||||||
UI_BuildSpacer(UI_PIX(10, 0), Axis_X);
|
|
||||||
UI_Push(BackgroundColor, 0);
|
|
||||||
UI_Push(Border, 0);
|
|
||||||
UI_Push(Text, text);
|
|
||||||
UI_Push(Width, UI_GROW(1, 0));
|
|
||||||
UI_Push(Height, UI_SHRINK(0, 1));
|
|
||||||
UI_Push(Flags, UI_BoxFlag_DrawText);
|
|
||||||
UI_BuildBox();
|
|
||||||
}
|
|
||||||
UI_PopCP(UI_TopCP());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UI_PopCP(UI_TopCP());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UI_PopCP(UI_TopCP());
|
|
||||||
}
|
|
||||||
|
|
||||||
EndScratch(scratch);
|
|
||||||
return console_box;
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Theme types
|
|
||||||
|
|
||||||
Struct(V_WidgetTheme)
|
|
||||||
{
|
|
||||||
GC_FontKey font;
|
|
||||||
f32 font_size;
|
|
||||||
f32 window_title_font_size;
|
|
||||||
|
|
||||||
Vec4 window_background_color;
|
|
||||||
Vec4 window_border_color;
|
|
||||||
Vec4 divider_color;
|
|
||||||
f32 window_border;
|
|
||||||
f32 window_padding;
|
|
||||||
f32 window_width;
|
|
||||||
|
|
||||||
f32 text_padding_x;
|
|
||||||
f32 text_padding_y;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Hotkey types
|
|
||||||
|
|
||||||
#define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
|
|
||||||
Struct(V_Hotkey)
|
|
||||||
{
|
|
||||||
Button button;
|
|
||||||
b32 ctrl;
|
|
||||||
b32 alt;
|
|
||||||
b32 shift;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Commands widget types
|
|
||||||
|
|
||||||
Struct(V_CommandsWidgetItemReport)
|
|
||||||
{
|
|
||||||
b32 pressed;
|
|
||||||
b32 hotkey_changed;
|
|
||||||
UI_Report ui_report;
|
|
||||||
V_Hotkey new_hotkeys[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(V_CommandsWidgetItemDesc)
|
|
||||||
{
|
|
||||||
String display_name;
|
|
||||||
V_Hotkey hotkeys[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(V_CommandsWidgetItem)
|
|
||||||
{
|
|
||||||
V_CommandsWidgetItem *next;
|
|
||||||
UI_Key key;
|
|
||||||
V_CommandsWidgetItemDesc desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(V_CommandsWidget)
|
|
||||||
{
|
|
||||||
/* Persistent state */
|
|
||||||
Vec2 pos;
|
|
||||||
|
|
||||||
/* Per-build state */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UI_Checkpoint cp;
|
|
||||||
V_CommandsWidgetItem *first_item;
|
|
||||||
V_CommandsWidgetItem *last_item;
|
|
||||||
u64 num_items;
|
|
||||||
} build;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Theme helpers
|
|
||||||
|
|
||||||
V_WidgetTheme V_GetWidgetThemeStyles(void);
|
|
||||||
void V_PushWidgetTheme(V_WidgetTheme theme);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Hotkey helpers
|
|
||||||
|
|
||||||
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Commands widget
|
|
||||||
|
|
||||||
void V_BeginCommandsWidget(V_CommandsWidget *widget);
|
|
||||||
V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc);
|
|
||||||
void V_EndCommandsWidget(V_CommandsWidget *widget);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Console widget
|
|
||||||
|
|
||||||
UI_Key V_BuildConsoleWidget(b32 minimized);
|
|
||||||
Loading…
Reference in New Issue
Block a user