Skip to content

Commit

Permalink
Backends: SDL2: Update to use io.AddEventKey() will full key map (2625)
Browse files Browse the repository at this point in the history
  • Loading branch information
thedmd authored and ocornut committed Jan 3, 2022
1 parent 09b03a6 commit 8224095
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 39 deletions.
170 changes: 133 additions & 37 deletions backends/imgui_impl_sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
// (Prefer SDL 2.0.5+ for full feature support.)

// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.

Expand All @@ -18,6 +18,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-01-XX: Inputs: calling new io.AddKeyEvent() API (1.87+), support for full keys range.
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
Expand Down Expand Up @@ -105,6 +106,119 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
SDL_SetClipboardText(text);
}

static ImGuiKey ImGui_ImplSDL2_ScancodeToImGuiKey(int scancode)
{
switch (scancode)
{
case SDL_SCANCODE_TAB: return ImGuiKey_Tab;
case SDL_SCANCODE_LEFT: return ImGuiKey_LeftArrow;
case SDL_SCANCODE_RIGHT: return ImGuiKey_RightArrow;
case SDL_SCANCODE_UP: return ImGuiKey_UpArrow;
case SDL_SCANCODE_DOWN: return ImGuiKey_DownArrow;
case SDL_SCANCODE_PAGEUP: return ImGuiKey_PageUp;
case SDL_SCANCODE_PAGEDOWN: return ImGuiKey_PageDown;
case SDL_SCANCODE_HOME: return ImGuiKey_Home;
case SDL_SCANCODE_END: return ImGuiKey_End;
case SDL_SCANCODE_INSERT: return ImGuiKey_Insert;
case SDL_SCANCODE_DELETE: return ImGuiKey_Delete;
case SDL_SCANCODE_BACKSPACE: return ImGuiKey_Backspace;
case SDL_SCANCODE_SPACE: return ImGuiKey_Space;
case SDL_SCANCODE_RETURN: return ImGuiKey_Enter;
case SDL_SCANCODE_ESCAPE: return ImGuiKey_Escape;
case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
case SDL_SCANCODE_CAPSLOCK: return ImGuiKey_CapsLock;
case SDL_SCANCODE_SCROLLLOCK: return ImGuiKey_ScrollLock;
case SDL_SCANCODE_NUMLOCKCLEAR: return ImGuiKey_NumLock;
case SDL_SCANCODE_PRINTSCREEN: return ImGuiKey_PrintScreen;
case SDL_SCANCODE_PAUSE: return ImGuiKey_Pause;
case SDL_SCANCODE_KP_0: return ImGuiKey_Keypad0;
case SDL_SCANCODE_KP_1: return ImGuiKey_Keypad1;
case SDL_SCANCODE_KP_2: return ImGuiKey_Keypad2;
case SDL_SCANCODE_KP_3: return ImGuiKey_Keypad3;
case SDL_SCANCODE_KP_4: return ImGuiKey_Keypad4;
case SDL_SCANCODE_KP_5: return ImGuiKey_Keypad5;
case SDL_SCANCODE_KP_6: return ImGuiKey_Keypad6;
case SDL_SCANCODE_KP_7: return ImGuiKey_Keypad7;
case SDL_SCANCODE_KP_8: return ImGuiKey_Keypad8;
case SDL_SCANCODE_KP_9: return ImGuiKey_Keypad9;
case SDL_SCANCODE_KP_PERIOD: return ImGuiKey_KeypadDecimal;
case SDL_SCANCODE_KP_DIVIDE: return ImGuiKey_KeypadDivide;
case SDL_SCANCODE_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
case SDL_SCANCODE_KP_MINUS: return ImGuiKey_KeypadSubtract;
case SDL_SCANCODE_KP_PLUS: return ImGuiKey_KeypadAdd;
case SDL_SCANCODE_KP_ENTER: return ImGuiKey_KeypadEnter;
case SDL_SCANCODE_KP_EQUALS: return ImGuiKey_KeypadEqual;
case SDL_SCANCODE_LSHIFT: return ImGuiKey_LeftShift;
case SDL_SCANCODE_LCTRL: return ImGuiKey_LeftControl;
case SDL_SCANCODE_LALT: return ImGuiKey_LeftAlt;
case SDL_SCANCODE_LGUI: return ImGuiKey_LeftSuper;
case SDL_SCANCODE_RSHIFT: return ImGuiKey_RightShift;
case SDL_SCANCODE_RCTRL: return ImGuiKey_RightControl;
case SDL_SCANCODE_RALT: return ImGuiKey_RightAlt;
case SDL_SCANCODE_RGUI: return ImGuiKey_RightSuper;
case SDL_SCANCODE_MENU: return ImGuiKey_Menu;
case SDL_SCANCODE_0: return ImGuiKey_0;
case SDL_SCANCODE_1: return ImGuiKey_1;
case SDL_SCANCODE_2: return ImGuiKey_2;
case SDL_SCANCODE_3: return ImGuiKey_3;
case SDL_SCANCODE_4: return ImGuiKey_4;
case SDL_SCANCODE_5: return ImGuiKey_5;
case SDL_SCANCODE_6: return ImGuiKey_6;
case SDL_SCANCODE_7: return ImGuiKey_7;
case SDL_SCANCODE_8: return ImGuiKey_8;
case SDL_SCANCODE_9: return ImGuiKey_9;
case SDL_SCANCODE_A: return ImGuiKey_A;
case SDL_SCANCODE_B: return ImGuiKey_B;
case SDL_SCANCODE_C: return ImGuiKey_C;
case SDL_SCANCODE_D: return ImGuiKey_D;
case SDL_SCANCODE_E: return ImGuiKey_E;
case SDL_SCANCODE_F: return ImGuiKey_F;
case SDL_SCANCODE_G: return ImGuiKey_G;
case SDL_SCANCODE_H: return ImGuiKey_H;
case SDL_SCANCODE_I: return ImGuiKey_I;
case SDL_SCANCODE_J: return ImGuiKey_J;
case SDL_SCANCODE_K: return ImGuiKey_K;
case SDL_SCANCODE_L: return ImGuiKey_L;
case SDL_SCANCODE_M: return ImGuiKey_M;
case SDL_SCANCODE_N: return ImGuiKey_N;
case SDL_SCANCODE_O: return ImGuiKey_O;
case SDL_SCANCODE_P: return ImGuiKey_P;
case SDL_SCANCODE_Q: return ImGuiKey_Q;
case SDL_SCANCODE_R: return ImGuiKey_R;
case SDL_SCANCODE_S: return ImGuiKey_S;
case SDL_SCANCODE_T: return ImGuiKey_T;
case SDL_SCANCODE_U: return ImGuiKey_U;
case SDL_SCANCODE_V: return ImGuiKey_V;
case SDL_SCANCODE_W: return ImGuiKey_W;
case SDL_SCANCODE_X: return ImGuiKey_X;
case SDL_SCANCODE_Y: return ImGuiKey_Y;
case SDL_SCANCODE_Z: return ImGuiKey_Z;
case SDL_SCANCODE_F1: return ImGuiKey_F1;
case SDL_SCANCODE_F2: return ImGuiKey_F2;
case SDL_SCANCODE_F3: return ImGuiKey_F3;
case SDL_SCANCODE_F4: return ImGuiKey_F4;
case SDL_SCANCODE_F5: return ImGuiKey_F5;
case SDL_SCANCODE_F6: return ImGuiKey_F6;
case SDL_SCANCODE_F7: return ImGuiKey_F7;
case SDL_SCANCODE_F8: return ImGuiKey_F8;
case SDL_SCANCODE_F9: return ImGuiKey_F9;
case SDL_SCANCODE_F10: return ImGuiKey_F10;
case SDL_SCANCODE_F11: return ImGuiKey_F11;
case SDL_SCANCODE_F12: return ImGuiKey_F12;
default: return ImGuiKey_None;
}
}

// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
Expand Down Expand Up @@ -140,17 +254,9 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
case SDL_KEYDOWN:
case SDL_KEYUP:
{
int key = event->key.keysym.scancode;
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
#ifdef _WIN32
io.KeySuper = false;
#else
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
#endif
ImGuiKey key = ImGui_ImplSDL2_ScancodeToImGuiKey(event->key.keysym.scancode);
if (key != ImGuiKey_None)
io.AddKeyEvent(key, event->type == SDL_KEYDOWN, event->key.keysym.sym, event->key.keysym.scancode);
return true;
}
case SDL_WINDOWEVENT:
Expand Down Expand Up @@ -191,30 +297,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
bd->Window = window;
bd->MouseCanUseGlobalState = mouse_can_use_global_state;

// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
io.KeyMap[ImGuiKey_KeypadEnter] = SDL_SCANCODE_KP_ENTER;
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;

io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
io.ClipboardUserData = NULL;
Expand Down Expand Up @@ -418,6 +500,17 @@ static void ImGui_ImplSDL2_UpdateGamepads()
#undef MAP_ANALOG
}

static void ImGui_ImplSDL2_UpdateKeyModifiers()
{
SDL_Keymod keymod = SDL_GetModState();

ImGuiIO& io = ImGui::GetIO();
io.KeyShift = (keymod & KMOD_SHIFT) != 0;
io.KeyCtrl = (keymod & KMOD_CTRL) != 0;
io.KeyAlt = (keymod & KMOD_ALT) != 0;
io.KeySuper = (keymod & KMOD_GUI) != 0;
}

void ImGui_ImplSDL2_NewFrame()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
Expand All @@ -441,6 +534,9 @@ void ImGui_ImplSDL2_NewFrame()
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time;

// Update key modifiers
ImGui_ImplSDL2_UpdateKeyModifiers();

ImGui_ImplSDL2_UpdateMousePosAndButtons();
ImGui_ImplSDL2_UpdateMouseCursor();

Expand Down
4 changes: 2 additions & 2 deletions backends/imgui_impl_sdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)

// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.

Expand Down

0 comments on commit 8224095

Please sign in to comment.