sokol icon indicating copy to clipboard operation
sokol copied to clipboard

made sokol_imgui event functions that were sapp agnostic public

Open benjitrosch opened this issue 1 year ago • 4 comments

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:

  1. _simgui_add_sapp_key_event
  2. _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.

benjitrosch avatar Jul 08 '23 19:07 benjitrosch

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.

floooh avatar Jul 09 '23 16:07 floooh

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).

floooh avatar Jul 09 '23 16:07 floooh

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.

benjitrosch avatar Jul 09 '23 18:07 benjitrosch

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 call ImGui::GetIO() in the C++ part, and igGetIO() 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

floooh avatar Jul 10 '23 10:07 floooh

Ok merged, many thanks!

floooh avatar Jul 12 '23 15:07 floooh

@floooh thanks so much! Hope others find it helpful 😄

benjitrosch avatar Jul 12 '23 22:07 benjitrosch