hotkey names

This commit is contained in:
jacob 2025-11-08 21:27:32 -06:00
parent 202dc4bc1c
commit 992e8762ae
10 changed files with 300 additions and 123 deletions

109
src/base/base_controller.c Normal file
View File

@ -0,0 +1,109 @@
////////////////////////////////////////////////////////////
//~ Button helpers
String StringFromButton(Button button)
{
PERSIST Readonly String names[Button_Count] = {
[Button_M1] = CompLit("Mouse 1"),
[Button_M2] = CompLit("Mouse 2"),
[Button_M3] = CompLit("Mouse 3"),
[Button_M4] = CompLit("Mouse 4"),
[Button_M5] = CompLit("Mouse 5"),
[Button_MWheelUp] = CompLit("Wheel Up"),
[Button_MWheelDown] = CompLit("Wheel Down"),
[Button_Esc] = CompLit("Escape"),
[Button_F1] = CompLit("F1"),
[Button_F2] = CompLit("F2"),
[Button_F3] = CompLit("F3"),
[Button_F4] = CompLit("F4"),
[Button_F5] = CompLit("F5"),
[Button_F6] = CompLit("F6"),
[Button_F7] = CompLit("F7"),
[Button_F8] = CompLit("F8"),
[Button_F9] = CompLit("F9"),
[Button_F10] = CompLit("F10"),
[Button_F11] = CompLit("F11"),
[Button_F12] = CompLit("F12"),
[Button_F13] = CompLit("F13"),
[Button_F14] = CompLit("F14"),
[Button_F15] = CompLit("F15"),
[Button_F16] = CompLit("F16"),
[Button_F17] = CompLit("F17"),
[Button_F18] = CompLit("F18"),
[Button_F19] = CompLit("F19"),
[Button_F20] = CompLit("F20"),
[Button_F21] = CompLit("F21"),
[Button_F22] = CompLit("F22"),
[Button_F23] = CompLit("F23"),
[Button_F24] = CompLit("F24"),
[Button_GraveAccent] = CompLit("~"),
[Button_0] = CompLit("0"),
[Button_1] = CompLit("1"),
[Button_2] = CompLit("2"),
[Button_3] = CompLit("3"),
[Button_4] = CompLit("4"),
[Button_5] = CompLit("5"),
[Button_6] = CompLit("6"),
[Button_7] = CompLit("7"),
[Button_8] = CompLit("8"),
[Button_9] = CompLit("9"),
[Button_Minus] = CompLit("Minus"),
[Button_Equal] = CompLit("Equal"),
[Button_Backspace] = CompLit("Backspace"),
[Button_Delete] = CompLit("Delete"),
[Button_Tab] = CompLit("Tab"),
[Button_A] = CompLit("A"),
[Button_B] = CompLit("B"),
[Button_C] = CompLit("C"),
[Button_D] = CompLit("D"),
[Button_E] = CompLit("E"),
[Button_F] = CompLit("F"),
[Button_G] = CompLit("G"),
[Button_H] = CompLit("H"),
[Button_I] = CompLit("I"),
[Button_J] = CompLit("J"),
[Button_K] = CompLit("K"),
[Button_L] = CompLit("L"),
[Button_M] = CompLit("M"),
[Button_N] = CompLit("N"),
[Button_O] = CompLit("O"),
[Button_P] = CompLit("P"),
[Button_Q] = CompLit("Q"),
[Button_R] = CompLit("R"),
[Button_S] = CompLit("S"),
[Button_T] = CompLit("T"),
[Button_U] = CompLit("U"),
[Button_V] = CompLit("V"),
[Button_W] = CompLit("W"),
[Button_X] = CompLit("X"),
[Button_Y] = CompLit("Y"),
[Button_Z] = CompLit("Z"),
[Button_Space] = CompLit("Space"),
[Button_Enter] = CompLit("Enter"),
[Button_Ctrl] = CompLit("Ctrl"),
[Button_Shift] = CompLit("Shift"),
[Button_Alt] = CompLit("Alt"),
[Button_Up] = CompLit("Up"),
[Button_Left] = CompLit("Left"),
[Button_Down] = CompLit("Down"),
[Button_Right] = CompLit("Right"),
[Button_PageUp] = CompLit("PageUp"),
[Button_PageDown] = CompLit("PageDown"),
[Button_Home] = CompLit("Home"),
[Button_End] = CompLit("End"),
[Button_ForwardSlash] = CompLit("ForwardSlash"),
[Button_Period] = CompLit("Period"),
[Button_Comma] = CompLit("Comma"),
[Button_Quote] = CompLit("Quote"),
[Button_LeftBracket] = CompLit("LeftBracket"),
[Button_RightBracket] = CompLit("RightBracket"),
[Button_Insert] = CompLit("Insert"),
[Button_Semicolon] = CompLit("Semicolon"),
};
String name = Lit("None");
if (button > 0 && button < countof(names))
{
name = names[button];
}
return name;
}

View File

@ -153,3 +153,8 @@ Struct(ControllerEventsArray)
u64 count; u64 count;
ControllerEvent *events; ControllerEvent *events;
}; };
////////////////////////////////////////////////////////////
//~ Button helpers
String StringFromButton(Button button);

View File

@ -46,6 +46,7 @@
# include "base_rand.c" # include "base_rand.c"
# include "base_bitbuff.c" # include "base_bitbuff.c"
# include "base_resource.c" # include "base_resource.c"
# include "base_controller.c"
#endif #endif
//- Include base_win32 //- Include base_win32

View File

@ -141,5 +141,6 @@ void InitLogSystem(String logfile_path);
/* NOTE: Calling these functions rather than using the logging macros may result in logs that are compiled regardless of log level. */ /* NOTE: Calling these functions rather than using the logging macros may result in logs that are compiled regardless of log level. */
void LogPanic(String msg); void LogPanic(String msg);
void Log_(i32 level, String msg);
void LogF_(i32 level, String fmt, ...); void LogF_(i32 level, String fmt, ...);
LogEventsArray GetLogEvents(void); LogEventsArray GetLogEvents(void);

View File

@ -118,6 +118,11 @@ void LogPanic(String msg)
} }
} }
void Log_(i32 level, String msg)
{
W32_Log(level, msg);
}
void LogF_(i32 level, String fmt, ...) void LogF_(i32 level, String fmt, ...)
{ {
W32_SharedLogState *g = &W32_shared_log_state; W32_SharedLogState *g = &W32_shared_log_state;

View File

@ -100,103 +100,6 @@ JobDef(PP_SimWorker, sig, job_id)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Vis worker //~ Vis worker
/* TODO: Remove this */
#define PP_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
Struct(PP_Hotkey)
{
Button button;
b32 ctrl;
b32 shift;
b32 alt;
};
Struct(PP_Shortcut)
{
PP_Shortcut *next_in_bin;
PP_Shortcut *prev_in_bin;
u64 hotkey_hash;
PP_Hotkey hotkey;
String cmd_name;
};
Struct(PP_ShortcutBin)
{
PP_Shortcut *first;
PP_Shortcut *last;
};
Enum(PP_VisCmdDescFlag)
{
PP_VisCmdDescFlag_None = 0,
PP_VisCmdDescFlag_HideFromPalette = (1 << 0),
};
Struct(PP_VisCmdDesc)
{
String name;
String display_name;
PP_VisCmdDescFlag flags;
PP_Hotkey default_hotkeys[8];
};
Struct(PP_VisCmd)
{
String name;
};
Struct(PP_VisCmdNode)
{
PP_VisCmdNode *next;
PP_VisCmd cmd;
};
#define PP_VisCmdsTableXMacro(X) \
X(nop, NOP, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY(0), ) \
X(exit_program, Exit Program, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_Esc ) ) \
X(toggle_command_palette, Toggle Command Palette, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
X(toggle_ui_debug, Toggle UI Debug, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F5 ), ) \
X(toggle_console, Toggle Developer Console, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_GraveAccent ), ) \
X(toggle_fullscreen, Toggle Fullscreen Mode, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_Enter, .alt = 1 ), PP_HOTKEY( Button_F11 ) ) \
X(toggle_window_topmost, Toggle Window Topmost, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F4 ), ) \
X(spawn, Spawn, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_S, .ctrl = 1 ), ) \
/* -------------------------------------------------------------------------------------------------------------------- */
Enum(PP_VisCmdKind)
{
#define X(name, ...) PP_VisCmdKind_##name,
PP_VisCmdsTableXMacro(X)
#undef X
PP_VisCmdKind_Count,
};
Readonly PP_VisCmdDesc PP_vis_cmd_descs[PP_VisCmdKind_Count] = {
#define X(_name, _display_name, _flags, ...) { .name = CompLit(#_name), .display_name = CompLit(#_display_name), .flags = _flags, .default_hotkeys = { __VA_ARGS__ } },
PP_VisCmdsTableXMacro(X)
#undef X
};
// Struct(PP_VisCmd)
// {
// String name;
// };
// Struct(PP_VisCmdNode)
// {
// }
JobDef(PP_VisWorker, sig, job_id) JobDef(PP_VisWorker, sig, job_id)
{ {
PP_SharedState *shared = &PP_shared_state; PP_SharedState *shared = &PP_shared_state;
@ -360,7 +263,11 @@ JobDef(PP_VisWorker, sig, job_id)
PP_VisCmdDesc desc = PP_vis_cmd_descs[i]; PP_VisCmdDesc desc = PP_vis_cmd_descs[i];
if (!desc.flags & PP_VisCmdDescFlag_HideFromPalette) if (!desc.flags & PP_VisCmdDescFlag_HideFromPalette)
{ {
if (PP_PushCommandsWidgetItem(&persist.commands_widget, desc.display_name).m1_presses > 0) PP_CommandsWidgetItemDesc item_desc = ZI;
item_desc.display_name = desc.display_name;
/* FIXME: Search active shortcuts instead of default hotkeys */
CopyStructs(item_desc.hotkeys, desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(desc.default_hotkeys)));
if (PP_PushCommandsWidgetItem(&persist.commands_widget, item_desc).pressed > 0)
{ {
PP_VisCmdNode *cmd_node = PushStruct(frame_arena, PP_VisCmdNode); PP_VisCmdNode *cmd_node = PushStruct(frame_arena, PP_VisCmdNode);
cmd_node->cmd.name = desc.name; cmd_node->cmd.name = desc.name;
@ -378,7 +285,7 @@ JobDef(PP_VisWorker, sig, job_id)
if (persist.show_console) if (persist.show_console)
{ {
b32 minimized = 1; b32 minimized = 0;
PP_BuildConsoleWidget(minimized); PP_BuildConsoleWidget(minimized);
} }

View File

@ -13,6 +13,78 @@ Struct(PP_SimCmd)
PP_SimCmd *next; PP_SimCmd *next;
}; };
////////////////////////////////////////////////////////////
//~ Vis command table
#define PP_VisCmdsTableXMacro(X) \
X(nop, NOP, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY(0), ) \
X(exit_program, Exit Program, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY( Button_Esc ) ) \
X(toggle_command_palette, Toggle Command Palette, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
X(toggle_ui_debug, Toggle UI Debug, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F5 ), ) \
X(toggle_console, Toggle Developer Console, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_GraveAccent ), ) \
X(toggle_fullscreen, Toggle Fullscreen Mode, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_Enter, .alt = 1 ), PP_HOTKEY( Button_F11 ) ) \
X(toggle_window_topmost, Toggle Window Topmost, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F4 ), ) \
X(spawn, Spawn, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_S, .ctrl = 1 ), ) \
/* -------------------------------------------------------------------------------------------------------------------- */
////////////////////////////////////////////////////////////
//~ Vis command types
Struct(PP_Shortcut)
{
PP_Shortcut *next_in_bin;
PP_Shortcut *prev_in_bin;
u64 hotkey_hash;
PP_Hotkey hotkey;
String cmd_name;
};
Struct(PP_ShortcutBin)
{
PP_Shortcut *first;
PP_Shortcut *last;
};
Enum(PP_VisCmdDescFlag)
{
PP_VisCmdDescFlag_None = 0,
PP_VisCmdDescFlag_HideFromPalette = (1 << 0),
};
Struct(PP_VisCmdDesc)
{
String name;
String display_name;
PP_VisCmdDescFlag flags;
PP_Hotkey default_hotkeys[8];
};
Struct(PP_VisCmd)
{
String name;
};
Struct(PP_VisCmdNode)
{
PP_VisCmdNode *next;
PP_VisCmd cmd;
};
Enum(PP_VisCmdKind)
{
#define X(name, ...) PP_VisCmdKind_##name,
PP_VisCmdsTableXMacro(X)
#undef X
PP_VisCmdKind_Count,
};
Global Readonly PP_VisCmdDesc PP_vis_cmd_descs[PP_VisCmdKind_Count] = {
#define X(_name, _display_name, _flags, ...) { .name = CompLit(#_name), .display_name = CompLit(#_display_name), .flags = _flags, .default_hotkeys = { __VA_ARGS__ } },
PP_VisCmdsTableXMacro(X)
#undef X
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
@ -44,6 +116,11 @@ Struct(PP_SharedState)
void PP_Startup(void); void PP_Startup(void);
void PP_Shutdown(void); void PP_Shutdown(void);
////////////////////////////////////////////////////////////
//~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Sim worker //~ Sim worker

View File

@ -8,7 +8,7 @@ PP_WidgetTheme PP_GetWidgetTheme(void)
theme.window_background_color = Rgb32(0xff1a1d1e); theme.window_background_color = Rgb32(0xff1a1d1e);
theme.window_border_color = Rgb32(0xff343a3b); theme.window_border_color = Rgb32(0xff343a3b);
theme.window_border = 1; theme.window_border = 1;
theme.window_width = 300; theme.window_width = 1000;
theme.window_padding = theme.window_border - 1; theme.window_padding = theme.window_border - 1;
theme.divider_color = theme.window_border_color; theme.divider_color = theme.window_border_color;
@ -26,6 +26,29 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
UI_Push(FontSize, theme.font_size); UI_Push(FontSize, theme.font_size);
} }
////////////////////////////////////////////////////////////
//~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_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));
return StringFromList(arena, parts, Lit(" + "));
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget //~ Commands widget
@ -36,18 +59,25 @@ void PP_BeginCommandsWidget(PP_CommandsWidget *widget)
UI_Push(Tag, HashF("commands widget")); UI_Push(Tag, HashF("commands widget"));
} }
UI_Report PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, String name) PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, PP_CommandsWidgetItemDesc desc)
{ {
Arena *frame_arena = UI_FrameArena(); Arena *frame_arena = UI_FrameArena();
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
PP_CommandsWidgetItem *item = PushStruct(frame_arena, PP_CommandsWidgetItem); {
item->name = name; PP_CommandsWidgetItem *item = PushStruct(frame_arena, PP_CommandsWidgetItem);
item->key = key; item->key = key;
QueuePush(widget->build.first_item, widget->build.last_item, item); item->desc = desc;
QueuePush(widget->build.first_item, widget->build.last_item, item);
++widget->build.num_items;
}
++widget->build.num_items; PP_CommandsWidgetItemReport result = ZI;
return UI_ReportFromKey(key); 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 PP_EndCommandsWidget(PP_CommandsWidget *widget) void PP_EndCommandsWidget(PP_CommandsWidget *widget)
@ -168,25 +198,37 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_BuildSpacer(UI_PIX(20, 1), Axis_X); UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
/* Command label */ /* Command label */
UI_BuildLabel(item->name); UI_BuildLabel(item->desc.display_name);
/* Middle spacer */ /* Middle spacer */
UI_BuildSpacer(UI_GROW(1, 0), Axis_X); UI_BuildSpacer(UI_GROW(1, 0), Axis_X);
/* Command hotkey button */ /* Command hotkey buttons */
UI_SetNext(Text, UI_StringF("Test")); for (u64 i = 0; i < countof(item->desc.hotkeys); ++i)
UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1));
UI_SetNext(Height, UI_GROW(1, 0));
UI_SetNext(Rounding, UI_RPIX(0));
UI_SetNext(Border, 0);
UI_SetNext(BackgroundColor, Color_Cyan);
UI_SetNext(ChildAlignment, UI_Alignment_Center);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRow());
{ {
PP_Hotkey hotkey = item->desc.hotkeys[i];
if (hotkey.button == Button_None)
{
break;
}
else
{
String hotkey_name = PP_StringFromHotkey(UI_FrameArena(), hotkey);
UI_SetNext(Text, hotkey_name);
UI_SetNext(Width, UI_SHRINK(theme.text_padding_x + 5, 1));
UI_SetNext(Height, UI_GROW(1, 0));
UI_SetNext(Rounding, UI_RGROW(1));
UI_SetNext(Border, 1);
// UI_SetNext(BackgroundColor, Color_Cyan);
UI_SetNext(ChildAlignment, UI_Alignment_Center);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRow());
{
}
UI_PopCP(UI_TopCP());
}
} }
UI_PopCP(UI_TopCP());
/* End spacer */ /* End spacer */
UI_BuildSpacer(UI_PIX(20, 1), Axis_X); UI_BuildSpacer(UI_PIX(20, 1), Axis_X);

View File

@ -18,14 +18,40 @@ Struct(PP_WidgetTheme)
f32 text_padding_y; f32 text_padding_y;
}; };
////////////////////////////////////////////////////////////
//~ Hotkey types
#define PP_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
Struct(PP_Hotkey)
{
Button button;
b32 ctrl;
b32 alt;
b32 shift;
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget types //~ Commands widget types
Struct(PP_CommandsWidgetItemReport)
{
b32 pressed;
b32 hotkey_changed;
UI_Report ui_report;
PP_Hotkey new_hotkeys[8];
};
Struct(PP_CommandsWidgetItemDesc)
{
String display_name;
PP_Hotkey hotkeys[8];
};
Struct(PP_CommandsWidgetItem) Struct(PP_CommandsWidgetItem)
{ {
PP_CommandsWidgetItem *next; PP_CommandsWidgetItem *next;
String name;
UI_Key key; UI_Key key;
PP_CommandsWidgetItemDesc desc;
}; };
Struct(PP_CommandsWidget) Struct(PP_CommandsWidget)
@ -41,7 +67,6 @@ Struct(PP_CommandsWidget)
PP_CommandsWidgetItem *last_item; PP_CommandsWidgetItem *last_item;
u64 num_items; u64 num_items;
} build; } build;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -50,11 +75,16 @@ Struct(PP_CommandsWidget)
PP_WidgetTheme PP_GetWidgetThemeStyles(void); PP_WidgetTheme PP_GetWidgetThemeStyles(void);
void PP_PushWidgetTheme(PP_WidgetTheme theme); void PP_PushWidgetTheme(PP_WidgetTheme theme);
////////////////////////////////////////////////////////////
//~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget //~ Commands widget
void PP_BeginCommandsWidget(PP_CommandsWidget *widget); void PP_BeginCommandsWidget(PP_CommandsWidget *widget);
UI_Report PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, String name); PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, PP_CommandsWidgetItemDesc desc);
void PP_EndCommandsWidget(PP_CommandsWidget *widget); void PP_EndCommandsWidget(PP_CommandsWidget *widget);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -439,7 +439,7 @@ UI_Style UI_PopStyle(UI_StyleDesc desc);
#define UI_ROUND(_kind, _v) (UI_Round) { .kind = (_kind), .v = (_v)} #define UI_ROUND(_kind, _v) (UI_Round) { .kind = (_kind), .v = (_v)}
#define UI_RPIX(_v) UI_ROUND(UI_RoundKind_Pixel, (_v)) #define UI_RPIX(_v) UI_ROUND(UI_RoundKind_Pixel, (_v))
#define UI_RGROW(_v) UI_ROUND(UI_RoundKind_Fill, (_v)) #define UI_RGROW(_v) UI_ROUND(UI_RoundKind_Grow, (_v))
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Command helpers //~ Command helpers