add global menu

This commit is contained in:
2026-02-22 18:42:14 -05:00
parent 2d08a1dd54
commit ace71a6725
3 changed files with 138 additions and 14 deletions

View File

@@ -11,8 +11,22 @@ struct PlatformWindowDesc {
int32_t height = 720;
};
struct PlatformMenuItem {
const char *label; // nullptr = separator
int32_t id; // command ID (ignored for separators)
};
struct PlatformMenu {
const char *label;
PlatformMenuItem *items;
int32_t item_count;
};
PlatformWindow *platform_create_window(PlatformWindowDesc *desc);
void platform_destroy_window(PlatformWindow *window);
bool platform_poll_events(PlatformWindow *window);
void platform_get_size(PlatformWindow *window, int32_t *w, int32_t *h);
void *platform_get_native_handle(PlatformWindow *window);
void platform_set_menu(PlatformWindow *window, PlatformMenu *menus, int32_t menu_count);
int32_t platform_poll_menu_command(PlatformWindow *window);

View File

@@ -15,6 +15,7 @@ struct PlatformWindow {
bool should_close;
int32_t width;
int32_t height;
int32_t pending_menu_cmd;
};
static PlatformWindow *g_current_window = nullptr;
@@ -31,6 +32,10 @@ static LRESULT CALLBACK win32_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
g_current_window->height = (int32_t)HIWORD(lparam);
}
return 0;
case WM_COMMAND:
if (g_current_window && HIWORD(wparam) == 0)
g_current_window->pending_menu_cmd = (int32_t)LOWORD(wparam);
return 0;
case WM_CLOSE:
if (g_current_window)
g_current_window->should_close = true;
@@ -133,3 +138,40 @@ void *platform_get_native_handle(PlatformWindow *window)
{
return (void *)window->hwnd;
}
void platform_set_menu(PlatformWindow *window, PlatformMenu *menus, int32_t menu_count)
{
HMENU menu_bar = CreateMenu();
for (int32_t i = 0; i < menu_count; i++) {
HMENU submenu = CreatePopupMenu();
for (int32_t j = 0; j < menus[i].item_count; j++) {
PlatformMenuItem *item = &menus[i].items[j];
if (!item->label) {
AppendMenuW(submenu, MF_SEPARATOR, 0, nullptr);
} else {
int wchar_count = MultiByteToWideChar(CP_UTF8, 0, item->label, -1, nullptr, 0);
wchar_t *wlabel = (wchar_t *)_malloca(wchar_count * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, item->label, -1, wlabel, wchar_count);
AppendMenuW(submenu, MF_STRING, (UINT_PTR)item->id, wlabel);
_freea(wlabel);
}
}
int wchar_count = MultiByteToWideChar(CP_UTF8, 0, menus[i].label, -1, nullptr, 0);
wchar_t *wlabel = (wchar_t *)_malloca(wchar_count * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, menus[i].label, -1, wlabel, wchar_count);
AppendMenuW(menu_bar, MF_POPUP, (UINT_PTR)submenu, wlabel);
_freea(wlabel);
}
SetMenu(window->hwnd, menu_bar);
}
int32_t platform_poll_menu_command(PlatformWindow *window)
{
int32_t cmd = window->pending_menu_cmd;
window->pending_menu_cmd = 0;
return cmd;
}