sokol
sokol copied to clipboard
made sokol_imgui event functions that were sapp agnostic public
I was adding sokol_imgui
with cimgui
to my sokol_gfx
and SDL2
project when I came across this comment:
The sokol_app.h dependency is optional and used for input event handling. If you only use sokol_gfx.h but not sokol_app.h in your application, define SOKOL_IMGUI_NO_SOKOL_APP before including the implementation of sokol_imgui.h, this will remove any dependency to sokol_app.h, but you must feed input events into Dear ImGui yourself.
I took a look and realized that almost all of the internal functions for event handling were platform agnostic between sokol_app
and SDL2
, with only two exceptions:
-
_simgui_add_sapp_key_event
-
_simgui_update_modifiers
I made the rest of them public and available even when SOKOL_IMGUI_NO_SOKOL_APP
is defined, and added a new function called simgui_add_key_event
which works like _simgui_add_sapp_key_event
but takes in a function pointer that allows the user to map the keycodes to imgui themselves.
Doing this saves a lot of boilerplate. Here's how you can make sokol_imgui
work with SDL2
pretty easily by exposing these functions:
static int imgui_sdl2_map_keycode(int key)
{
switch (key)
{
case SDLK_SPACE: return ImGuiKey_Space;
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
case SDLK_COMMA: return ImGuiKey_Comma;
// etc...
default: return ImGuiKey_None;
}
}
static void imgui_sdl2_update_modifiers(ImGuiIO* io, uint16_t mod)
{
simgui_add_imgui_key_event(io, ImGuiMod_Ctrl, (mod & KMOD_CTRL) != 0);
simgui_add_imgui_key_event(io, ImGuiMod_Shift, (mod & KMOD_SHIFT) != 0);
simgui_add_imgui_key_event(io, ImGuiMod_Alt, (mod & KMOD_ALT) != 0);
simgui_add_imgui_key_event(io, ImGuiMod_Super, (mod & KMOD_GUI) != 0);
}
void imgui_handle_events(const SDL_Event* event)
{
#ifdef __cplusplus
ImGuiIO* io = &ImGui::GetIO();
#else
ImGuiIO* io = igGetIO();
#endif
int mouse_button = -1;
if (event->button.button == SDL_BUTTON_LEFT) mouse_button = 0;
if (event->button.button == SDL_BUTTON_RIGHT) mouse_button = 1;
if (event->button.button == SDL_BUTTON_MIDDLE) mouse_button = 2;
if (event->button.button == SDL_BUTTON_X1) mouse_button = 3;
if (event->button.button == SDL_BUTTON_X2) mouse_button = 4;
switch (event->type)
{
case SDL_WINDOWEVENT_FOCUS_GAINED:
simgui_add_focus_event(io, true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
simgui_add_focus_event(io, false);
break;
case SDL_MOUSEBUTTONDOWN:
if (mouse_button == -1) break;
simgui_add_mouse_pos_event(io, (float)event->button.x, (float)event->button.y);
simgui_add_mouse_button_event(io, mouse_button, true);
imgui_sdl2_update_modifiers(io, event->key.keysym.mod);
break;
case SDL_MOUSEBUTTONUP:
if (mouse_button == -1) break;
simgui_add_mouse_pos_event(io, (float)event->button.x, (float)event->button.y);
simgui_add_mouse_button_event(io, mouse_button, false);
imgui_sdl2_update_modifiers(io, event->key.keysym.mod);
break;
case SDL_MOUSEMOTION:
simgui_add_mouse_pos_event(io, (float)event->motion.x, (float)event->motion.y);
break;
case SDL_MOUSEWHEEL:
simgui_add_mouse_wheel_event(io, event->wheel.x, event->wheel.y);
break;
case SDL_KEYDOWN:
imgui_sdl2_update_modifiers(io, event->key.keysym.mod);
simgui_add_key_event(io, imgui_sdl2_map_keycode, (int)event->key.keysym.sym, true);
break;
case SDL_KEYUP:
imgui_sdl2_update_modifiers(io, event->key.keysym.mod);
simgui_add_key_event(io, imgui_sdl2_map_keycode, (int)event->key.keysym.sym, false);
break;
case SDL_TEXTINPUT:
simgui_add_input_characters_utf8(io, event->text.text);
break;
}
}
Let me know if you think this would be a good addition or if you'd rather leave it out for people to implement themselves.
Looks like a good idea, but I need to roll this around in the back of my head for a bit ;) All those 'event' functions are actually fairly recent and it didn't occur to me that it might make sense to make them public.
Can you have a look at the CI errors? Looks like some places still call the old _simgui_...
version (probably in sokol-app specific code paths).
Can you have a look at the CI errors? Looks like some places still call the old
_simgui_...
version (probably in sokol-app specific code paths).
Good catch sorry for missing that earlier! Pushed up a fix and reran test_macos.sh
locally (since that's what I'm developing on) and it's passing now, hopefully should mean the others pass as well.
A couple more changes needed, sorry that I missed this earlier:
- the
ImGuiIO* io
parameter needs to be removed, because the public API functions cannot have any Dear ImGui types in their signature (just callImGui::GetIO()
in the C++ part, andigGetIO()
in the C part) - you also need to add the function prototypes in the declaration part here (before the simgui_shutdown() function): https://github.com/floooh/sokol/blob/da8466d9a968a91e4b1bc9e1a049d0ac9771ed3f/util/sokol_imgui.h#L332-L339
- also please add a short documentation blurb similar to the 'MEMORY ALLOCATION OVERRIDE' block, just some info when those functions might be useful: https://github.com/floooh/sokol/blob/da8466d9a968a91e4b1bc9e1a049d0ac9771ed3f/util/sokol_imgui.h#L212-L239
Ok merged, many thanks!
@floooh thanks so much! Hope others find it helpful 😄