Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_glfw.cpp
#	backends/imgui_impl_sdl.cpp
#	backends/imgui_impl_win32.cpp
#	imgui_demo.cpp
#	imgui_internal.h
This commit is contained in:
ocornut 2022-01-17 18:16:55 +01:00
commit 8567a4cca3
16 changed files with 466 additions and 246 deletions

View File

@ -17,6 +17,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events. // 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
@ -328,12 +330,12 @@ static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
case ALLEGRO_KEY_PAD_PLUS: return ImGuiKey_KeypadAdd; case ALLEGRO_KEY_PAD_PLUS: return ImGuiKey_KeypadAdd;
case ALLEGRO_KEY_PAD_ENTER: return ImGuiKey_KeypadEnter; case ALLEGRO_KEY_PAD_ENTER: return ImGuiKey_KeypadEnter;
case ALLEGRO_KEY_PAD_EQUALS: return ImGuiKey_KeypadEqual; case ALLEGRO_KEY_PAD_EQUALS: return ImGuiKey_KeypadEqual;
case ALLEGRO_KEY_LCTRL: return ImGuiKey_LeftCtrl;
case ALLEGRO_KEY_LSHIFT: return ImGuiKey_LeftShift; case ALLEGRO_KEY_LSHIFT: return ImGuiKey_LeftShift;
case ALLEGRO_KEY_LCTRL: return ImGuiKey_LeftControl;
case ALLEGRO_KEY_ALT: return ImGuiKey_LeftAlt; case ALLEGRO_KEY_ALT: return ImGuiKey_LeftAlt;
case ALLEGRO_KEY_LWIN: return ImGuiKey_LeftSuper; case ALLEGRO_KEY_LWIN: return ImGuiKey_LeftSuper;
case ALLEGRO_KEY_RCTRL: return ImGuiKey_RightCtrl;
case ALLEGRO_KEY_RSHIFT: return ImGuiKey_RightShift; case ALLEGRO_KEY_RSHIFT: return ImGuiKey_RightShift;
case ALLEGRO_KEY_RCTRL: return ImGuiKey_RightControl;
case ALLEGRO_KEY_ALTGR: return ImGuiKey_RightAlt; case ALLEGRO_KEY_ALTGR: return ImGuiKey_RightAlt;
case ALLEGRO_KEY_RWIN: return ImGuiKey_RightSuper; case ALLEGRO_KEY_RWIN: return ImGuiKey_RightSuper;
case ALLEGRO_KEY_MENU: return ImGuiKey_Menu; case ALLEGRO_KEY_MENU: return ImGuiKey_Menu;
@ -440,6 +442,20 @@ void ImGui_ImplAllegro5_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
// ev->keyboard.modifiers seems always zero so using that...
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
{
ImGuiIO& io = ImGui::GetIO();
ALLEGRO_KEYBOARD_STATE keys;
al_get_keyboard_state(&keys);
ImGuiKeyModFlags key_mods =
((al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL)) ? ImGuiKeyModFlags_Ctrl : 0) |
((al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) |
((al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR)) ? ImGuiKeyModFlags_Alt : 0) |
((al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN)) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // 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.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. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
@ -454,29 +470,28 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
case ALLEGRO_EVENT_MOUSE_AXES: case ALLEGRO_EVENT_MOUSE_AXES:
if (ev->mouse.display == bd->Display) if (ev->mouse.display == bd->Display)
{ {
io.MouseWheel += ev->mouse.dz; io.AddMousePosEvent(ev->mouse.x, ev->mouse.y);
io.MouseWheelH -= ev->mouse.dw; io.AddMouseWheelEvent(-ev->mouse.dw, ev->mouse.dz);
io.MousePos = ImVec2(ev->mouse.x, ev->mouse.y);
} }
return true; return true;
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
case ALLEGRO_EVENT_MOUSE_BUTTON_UP: case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
if (ev->mouse.display == bd->Display && ev->mouse.button <= 5) if (ev->mouse.display == bd->Display && ev->mouse.button > 0 && ev->mouse.button <= 5)
io.MouseDown[ev->mouse.button - 1] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN); io.AddMouseButtonEvent(ev->mouse.button - 1, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
return true; return true;
case ALLEGRO_EVENT_TOUCH_MOVE: case ALLEGRO_EVENT_TOUCH_MOVE:
if (ev->touch.display == bd->Display) if (ev->touch.display == bd->Display)
io.MousePos = ImVec2(ev->touch.x, ev->touch.y); io.AddMousePosEvent(ev->touch.x, ev->touch.y);
return true; return true;
case ALLEGRO_EVENT_TOUCH_BEGIN: case ALLEGRO_EVENT_TOUCH_BEGIN:
case ALLEGRO_EVENT_TOUCH_END: case ALLEGRO_EVENT_TOUCH_END:
case ALLEGRO_EVENT_TOUCH_CANCEL: case ALLEGRO_EVENT_TOUCH_CANCEL:
if (ev->touch.display == bd->Display && ev->touch.primary) if (ev->touch.display == bd->Display && ev->touch.primary)
io.MouseDown[0] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN); io.AddMouseButtonEvent(0, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
return true; return true;
case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
if (ev->mouse.display == bd->Display) if (ev->mouse.display == bd->Display)
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
return true; return true;
case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_CHAR:
if (ev->keyboard.display == bd->Display) if (ev->keyboard.display == bd->Display)
@ -487,6 +502,7 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
case ALLEGRO_EVENT_KEY_UP: case ALLEGRO_EVENT_KEY_UP:
if (ev->keyboard.display == bd->Display) if (ev->keyboard.display == bd->Display)
{ {
ImGui_ImplAllegro5_UpdateKeyModifiers();
ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode); ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode);
io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN)); io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN));
io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code) io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code)
@ -560,15 +576,6 @@ void ImGui_ImplAllegro5_NewFrame()
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
// Setup inputs // Setup mouse cursor shape
ALLEGRO_KEYBOARD_STATE keys;
al_get_keyboard_state(&keys);
ImGuiKeyModFlags key_mods =
((al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL)) ? ImGuiKeyModFlags_Ctrl : 0) |
((al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) |
((al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR)) ? ImGuiKeyModFlags_Alt : 0) |
((al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN)) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
ImGui_ImplAllegro5_UpdateMouseCursor(); ImGui_ImplAllegro5_UpdateMouseCursor();
} }

View File

@ -19,6 +19,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-03-04: Initial version. // 2021-03-04: Initial version.
@ -101,12 +102,12 @@ static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd; case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd;
case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter; case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter;
case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual; case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual;
case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftCtrl;
case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift; case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift;
case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftControl;
case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt; case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt;
case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper; case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper;
case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightCtrl;
case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift; case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift;
case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightControl;
case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt; case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt;
case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper; case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper;
case AKEYCODE_MENU: return ImGuiKey_Menu; case AKEYCODE_MENU: return ImGuiKey_Menu;
@ -227,26 +228,25 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER) if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER)
|| (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)) || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN))
{ {
io.MouseDown[0] = (event_action == AMOTION_EVENT_ACTION_DOWN); io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
} }
break; break;
case AMOTION_EVENT_ACTION_BUTTON_PRESS: case AMOTION_EVENT_ACTION_BUTTON_PRESS:
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
{ {
int32_t button_state = AMotionEvent_getButtonState(input_event); int32_t button_state = AMotionEvent_getButtonState(input_event);
io.MouseDown[0] = ((button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
io.MouseDown[1] = ((button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
io.MouseDown[2] = ((button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
} }
break; break;
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse) case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
break; break;
case AMOTION_EVENT_ACTION_SCROLL: case AMOTION_EVENT_ACTION_SCROLL:
io.MouseWheel = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index); io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index));
io.MouseWheelH = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index);
break; break;
default: default:
break; break;

View File

@ -21,6 +21,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback(). // 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback().
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API. // 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API.
@ -104,7 +106,6 @@ struct ImGui_ImplGlfw_Data
GlfwClientApi ClientApi; GlfwClientApi ClientApi;
double Time; double Time;
GLFWwindow* MouseWindow; GLFWwindow* MouseWindow;
bool MouseJustPressed[ImGuiMouseButton_COUNT];
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
bool InstalledCallbacks; bool InstalledCallbacks;
@ -204,11 +205,11 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter; case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter;
case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual; case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual;
case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift; case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift;
case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftControl; case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl;
case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt; case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt;
case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper; case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper;
case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift; case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift;
case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightControl; case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightCtrl;
case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt; case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt;
case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper; case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper;
case GLFW_KEY_MENU: return ImGuiKey_Menu; case GLFW_KEY_MENU: return ImGuiKey_Menu;
@ -264,14 +265,28 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
} }
} }
static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiKeyModFlags key_mods =
((mods & GLFW_MOD_CONTROL) ? ImGuiKeyModFlags_Ctrl : 0) |
((mods & GLFW_MOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) |
((mods & GLFW_MOD_ALT) ? ImGuiKeyModFlags_Alt : 0) |
((mods & GLFW_MOD_SUPER) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
}
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{ {
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackMousebutton != NULL && window == bd->Window) if (bd->PrevUserCallbackMousebutton != NULL && window == bd->Window)
bd->PrevUserCallbackMousebutton(window, button, action, mods); bd->PrevUserCallbackMousebutton(window, button, action, mods);
if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(bd->MouseJustPressed)) ImGui_ImplGlfw_UpdateKeyModifiers(mods);
bd->MouseJustPressed[button] = true;
ImGuiIO& io = ImGui::GetIO();
if (button >= 0 && button < ImGuiMouseButton_COUNT)
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
} }
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
@ -281,13 +296,12 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
bd->PrevUserCallbackScroll(window, xoffset, yoffset); bd->PrevUserCallbackScroll(window, xoffset, yoffset);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MouseWheelH += (float)xoffset; io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
io.MouseWheel += (float)yoffset;
} }
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode) static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
{ {
#if GLFW_HAS_GET_KEY_NAME #if GLFW_HAS_GET_KEY_NAME && !defined(__EMSCRIPTEN__)
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult. // GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently) // (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
// See https://github.com/glfw/glfw/issues/1502 for details. // See https://github.com/glfw/glfw/issues/1502 for details.
@ -304,6 +318,8 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; } else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; }
} }
// if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name); // if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name);
#else
IM_UNUSED(scancode);
#endif #endif
return key; return key;
} }
@ -317,6 +333,8 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
if (action != GLFW_PRESS && action != GLFW_RELEASE) if (action != GLFW_PRESS && action != GLFW_RELEASE)
return; return;
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows)) if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : NULL; bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : NULL;
@ -352,7 +370,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
x += window_x; x += window_x;
y += window_y; y += window_y;
} }
io.MousePos = ImVec2((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
} }
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
@ -367,7 +385,7 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
if (!entered && bd->MouseWindow == window) if (!entered && bd->MouseWindow == window)
{ {
bd->MouseWindow = NULL; bd->MouseWindow = NULL;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
} }
} }
@ -524,7 +542,6 @@ static void ImGui_ImplGlfw_UpdateMouseData()
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
const ImVec2 mouse_pos_prev = io.MousePos; const ImVec2 mouse_pos_prev = io.MousePos;
int mouse_buttons_mask = 0x00;
for (int n = 0; n < platform_io.Viewports.Size; n++) for (int n = 0; n < platform_io.Viewports.Size; n++)
{ {
ImGuiViewport* viewport = platform_io.Viewports[n]; ImGuiViewport* viewport = platform_io.Viewports[n];
@ -537,11 +554,6 @@ static void ImGui_ImplGlfw_UpdateMouseData()
#endif #endif
if (is_window_focused) if (is_window_focused)
{ {
// Update mouse button mask (applied below)
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
if (glfwGetMouseButton(window, i) != 0)
mouse_buttons_mask |= (1 << i);
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions. // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
if (io.WantSetMousePos) if (io.WantSetMousePos)
@ -561,7 +573,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
mouse_x += window_x; mouse_x += window_x;
mouse_y += window_y; mouse_y += window_y;
} }
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
} }
} }
@ -582,14 +594,6 @@ static void ImGui_ImplGlfw_UpdateMouseData()
io.MouseHoveredViewport = viewport->ID; io.MouseHoveredViewport = viewport->ID;
#endif #endif
} }
// Update mouse buttons
// (if a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame)
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
io.MouseDown[i] = bd->MouseJustPressed[i] || (mouse_buttons_mask & (1 << i)) != 0;
bd->MouseJustPressed[i] = false;
}
} }
static void ImGui_ImplGlfw_UpdateMouseCursor() static void ImGui_ImplGlfw_UpdateMouseCursor()
@ -691,18 +695,6 @@ static void ImGui_ImplGlfw_UpdateMonitors()
bd->WantUpdateMonitors = false; bd->WantUpdateMonitors = false;
} }
static void ImGui_ImplGlfw_UpdateKeyModifiers()
{
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
ImGuiKeyModFlags key_mods =
(((glfwGetKey(bd->Window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)) ? ImGuiKeyModFlags_Ctrl : 0) |
(((glfwGetKey(bd->Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS)) ? ImGuiKeyModFlags_Shift : 0) |
(((glfwGetKey(bd->Window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS)) ? ImGuiKeyModFlags_Alt : 0) |
(((glfwGetKey(bd->Window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS)) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
}
void ImGui_ImplGlfw_NewFrame() void ImGui_ImplGlfw_NewFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -725,7 +717,6 @@ void ImGui_ImplGlfw_NewFrame()
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
ImGui_ImplGlfw_UpdateKeyModifiers();
ImGui_ImplGlfw_UpdateMouseData(); ImGui_ImplGlfw_UpdateMouseData();
ImGui_ImplGlfw_UpdateMouseCursor(); ImGui_ImplGlfw_UpdateMouseCursor();

View File

@ -20,6 +20,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. // 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h.
// 2019-03-25: Misc: Made io.DeltaTime always above zero. // 2019-03-25: Misc: Made io.DeltaTime always above zero.
@ -93,12 +94,12 @@ static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
case 43: return ImGuiKey_KeypadAdd; case 43: return ImGuiKey_KeypadAdd;
//case 13: return ImGuiKey_KeypadEnter; //case 13: return ImGuiKey_KeypadEnter;
//case 0: return ImGuiKey_KeypadEqual; //case 0: return ImGuiKey_KeypadEqual;
case 256 + 0x0072: return ImGuiKey_LeftCtrl;
case 256 + 0x0070: return ImGuiKey_LeftShift; case 256 + 0x0070: return ImGuiKey_LeftShift;
case 256 + 0x0072: return ImGuiKey_LeftControl;
case 256 + 0x0074: return ImGuiKey_LeftAlt; case 256 + 0x0074: return ImGuiKey_LeftAlt;
//case 0: return ImGuiKey_LeftSuper; //case 0: return ImGuiKey_LeftSuper;
case 256 + 0x0073: return ImGuiKey_RightCtrl;
case 256 + 0x0071: return ImGuiKey_RightShift; case 256 + 0x0071: return ImGuiKey_RightShift;
case 256 + 0x0073: return ImGuiKey_RightControl;
case 256 + 0x0075: return ImGuiKey_RightAlt; case 256 + 0x0075: return ImGuiKey_RightAlt;
//case 0: return ImGuiKey_RightSuper; //case 0: return ImGuiKey_RightSuper;
//case 0: return ImGuiKey_Menu; //case 0: return ImGuiKey_Menu;
@ -202,7 +203,7 @@ void ImGui_ImplGLUT_NewFrame()
ImGui::NewFrame(); ImGui::NewFrame();
} }
static void ImGui_ImplGLUT_UpdateKeyboardMods() static void ImGui_ImplGLUT_UpdateKeyModifiers()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
int glut_key_mods = glutGetModifiers(); int glut_key_mods = glutGetModifiers();
@ -230,7 +231,7 @@ void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y)
ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c);
ImGui_ImplGLUT_AddKeyEvent(key, true, c); ImGui_ImplGLUT_AddKeyEvent(key, true, c);
ImGui_ImplGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyModifiers();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
@ -239,7 +240,7 @@ void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y)
//printf("char_up_func %d '%c'\n", c, c); //printf("char_up_func %d '%c'\n", c, c);
ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c);
ImGui_ImplGLUT_AddKeyEvent(key, false, c); ImGui_ImplGLUT_AddKeyEvent(key, false, c);
ImGui_ImplGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyModifiers();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
@ -248,7 +249,7 @@ void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y)
//printf("key_down_func %d\n", key); //printf("key_down_func %d\n", key);
ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256);
ImGui_ImplGLUT_AddKeyEvent(imgui_key, true, key + 256); ImGui_ImplGLUT_AddKeyEvent(imgui_key, true, key + 256);
ImGui_ImplGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyModifiers();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
@ -257,33 +258,29 @@ void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y)
//printf("key_up_func %d\n", key); //printf("key_up_func %d\n", key);
ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256);
ImGui_ImplGLUT_AddKeyEvent(imgui_key, false, key + 256); ImGui_ImplGLUT_AddKeyEvent(imgui_key, false, key + 256);
ImGui_ImplGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyModifiers();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y) void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
int button = -1; int button = -1;
if (glut_button == GLUT_LEFT_BUTTON) button = 0; if (glut_button == GLUT_LEFT_BUTTON) button = 0;
if (glut_button == GLUT_RIGHT_BUTTON) button = 1; if (glut_button == GLUT_RIGHT_BUTTON) button = 1;
if (glut_button == GLUT_MIDDLE_BUTTON) button = 2; if (glut_button == GLUT_MIDDLE_BUTTON) button = 2;
if (button != -1 && state == GLUT_DOWN) if (button != -1 && state == GLUT_DOWN || state == GLUT_UP)
io.MouseDown[button] = true; io.AddMouseButtonEvent(button, state == GLUT_DOWN);
if (button != -1 && state == GLUT_UP)
io.MouseDown[button] = false;
} }
#ifdef __FREEGLUT_EXT_H__ #ifdef __FREEGLUT_EXT_H__
void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y) void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
if (dir > 0) if (dir != 0)
io.MouseWheel += 1.0; io.AddMouseWheelEvent(0.0f, dir > 0 ? 1.0f : -1.0f);
else if (dir < 0)
io.MouseWheel -= 1.0;
(void)button; // Unused (void)button; // Unused
} }
#endif #endif
@ -297,5 +294,5 @@ void ImGui_ImplGLUT_ReshapeFunc(int w, int h)
void ImGui_ImplGLUT_MotionFunc(int x, int y) void ImGui_ImplGLUT_MotionFunc(int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
} }

View File

@ -25,6 +25,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function. // 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys. // 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys.
@ -53,9 +54,6 @@ static double g_HostClockPeriod = 0.0;
static double g_Time = 0.0; static double g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_MouseCursorHidden = false; static bool g_MouseCursorHidden = false;
static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
static ImGuiKeyModFlags g_KeyModifiers = ImGuiKeyModFlags_None;
static ImFocusObserver* g_FocusObserver = nil; static ImFocusObserver* g_FocusObserver = nil;
static KeyEventResponder* g_KeyEventResponder = nil; static KeyEventResponder* g_KeyEventResponder = nil;
static NSTextInputContext* g_InputContext = nil; static NSTextInputContext* g_InputContext = nil;
@ -304,15 +302,15 @@ static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
case kVK_Space: return ImGuiKey_Space; case kVK_Space: return ImGuiKey_Space;
case kVK_Delete: return ImGuiKey_Backspace; case kVK_Delete: return ImGuiKey_Backspace;
case kVK_Escape: return ImGuiKey_Escape; case kVK_Escape: return ImGuiKey_Escape;
case kVK_Command: return ImGuiKey_LeftSuper;
case kVK_Shift: return ImGuiKey_LeftShift;
case kVK_CapsLock: return ImGuiKey_CapsLock; case kVK_CapsLock: return ImGuiKey_CapsLock;
case kVK_Control: return ImGuiKey_LeftCtrl;
case kVK_Shift: return ImGuiKey_LeftShift;
case kVK_Option: return ImGuiKey_LeftAlt; case kVK_Option: return ImGuiKey_LeftAlt;
case kVK_Control: return ImGuiKey_LeftControl; case kVK_Command: return ImGuiKey_LeftSuper;
case kVK_RightCommand: return ImGuiKey_RightSuper; case kVK_RightControl: return ImGuiKey_RightCtrl;
case kVK_RightShift: return ImGuiKey_RightShift; case kVK_RightShift: return ImGuiKey_RightShift;
case kVK_RightOption: return ImGuiKey_RightAlt; case kVK_RightOption: return ImGuiKey_RightAlt;
case kVK_RightControl: return ImGuiKey_RightControl; case kVK_RightCommand: return ImGuiKey_RightSuper;
// case kVK_Function: return ImGuiKey_; // case kVK_Function: return ImGuiKey_;
// case kVK_F17: return ImGuiKey_; // case kVK_F17: return ImGuiKey_;
// case kVK_VolumeUp: return ImGuiKey_; // case kVK_VolumeUp: return ImGuiKey_;
@ -453,17 +451,9 @@ void ImGui_ImplOSX_Shutdown()
g_FocusObserver = NULL; g_FocusObserver = NULL;
} }
static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() static void ImGui_ImplOSX_UpdateMouseCursor()
{ {
// Update buttons
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[i] = g_MouseJustPressed[i] || g_MouseDown[i];
g_MouseJustPressed[i] = false;
}
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return; return;
@ -525,8 +515,8 @@ static void ImGui_ImplOSX_UpdateGamepads()
MAP_BUTTON(ImGuiNavInput_DpadDown, dpad.down); MAP_BUTTON(ImGuiNavInput_DpadDown, dpad.down);
MAP_BUTTON(ImGuiNavInput_FocusPrev, leftShoulder); MAP_BUTTON(ImGuiNavInput_FocusPrev, leftShoulder);
MAP_BUTTON(ImGuiNavInput_FocusNext, rightShoulder); MAP_BUTTON(ImGuiNavInput_FocusNext, rightShoulder);
MAP_BUTTON(ImGuiNavInput_TweakSlow, leftTrigger); MAP_BUTTON(ImGuiNavInput_TweakSlow, leftShoulder);
MAP_BUTTON(ImGuiNavInput_TweakFast, rightTrigger); MAP_BUTTON(ImGuiNavInput_TweakFast, rightShoulder);
#undef MAP_BUTTON #undef MAP_BUTTON
io.NavInputs[ImGuiNavInput_LStickLeft] = gp.leftThumbstick.left.value; io.NavInputs[ImGuiNavInput_LStickLeft] = gp.leftThumbstick.left.value;
@ -537,12 +527,6 @@ static void ImGui_ImplOSX_UpdateGamepads()
io.BackendFlags |= ImGuiBackendFlags_HasGamepad; io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
} }
static void ImGui_ImplOSX_UpdateKeyModifiers()
{
ImGuiIO& io = ImGui::GetIO();
io.AddKeyModsEvent(g_KeyModifiers);
}
static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view) static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -571,8 +555,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
io.DeltaTime = (float)(current_time - g_Time); io.DeltaTime = (float)(current_time - g_Time);
g_Time = current_time; g_Time = current_time;
ImGui_ImplOSX_UpdateKeyModifiers(); ImGui_ImplOSX_UpdateMouseCursor();
ImGui_ImplOSX_UpdateMouseCursorAndButtons();
ImGui_ImplOSX_UpdateGamepads(); ImGui_ImplOSX_UpdateGamepads();
ImGui_ImplOSX_UpdateImePosWithView(view); ImGui_ImplOSX_UpdateImePosWithView(view);
} }
@ -584,16 +567,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
{ {
int button = (int)[event buttonNumber]; int button = (int)[event buttonNumber];
if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) if (button >= 0 && button < ImGuiMouseButton_COUNT)
g_MouseDown[button] = g_MouseJustPressed[button] = true; io.AddMouseButtonEvent(button, true);
return io.WantCaptureMouse; return io.WantCaptureMouse;
} }
if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp) if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp)
{ {
int button = (int)[event buttonNumber]; int button = (int)[event buttonNumber];
if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) if (button >= 0 && button < ImGuiMouseButton_COUNT)
g_MouseDown[button] = false; io.AddMouseButtonEvent(button, false);
return io.WantCaptureMouse; return io.WantCaptureMouse;
} }
@ -602,7 +585,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
NSPoint mousePoint = event.locationInWindow; NSPoint mousePoint = event.locationInWindow;
mousePoint = [view convertPoint:mousePoint fromView:nil]; mousePoint = [view convertPoint:mousePoint fromView:nil];
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y); mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
io.MousePos = ImVec2((float)mousePoint.x, (float)mousePoint.y); io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
} }
if (event.type == NSEventTypeScrollWheel) if (event.type == NSEventTypeScrollWheel)
@ -642,11 +625,9 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
wheel_dx = [event deltaX]; wheel_dx = [event deltaX];
wheel_dy = [event deltaY]; wheel_dy = [event deltaY];
} }
if (wheel_dx != 0.0 || wheel_dx != 0.0)
io.AddMouseWheelEvent((float)wheel_dx * 0.1f, (float)wheel_dy * 0.1f);
if (fabs(wheel_dx) > 0.0)
io.MouseWheelH += (float)wheel_dx * 0.1f;
if (fabs(wheel_dy) > 0.0)
io.MouseWheel += (float)wheel_dy * 0.1f;
return io.WantCaptureMouse; return io.WantCaptureMouse;
} }
@ -668,17 +649,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
unsigned short key_code = [event keyCode]; unsigned short key_code = [event keyCode];
unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask; unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
ImGuiKeyModFlags imgui_flags = ImGuiKeyModFlags_None; ImGuiKeyModFlags imgui_key_mods = ImGuiKeyModFlags_None;
if (flags & NSEventModifierFlagShift) if (flags & NSEventModifierFlagShift)
imgui_flags |= ImGuiKeyModFlags_Shift; imgui_key_mods |= ImGuiKeyModFlags_Shift;
if (flags & NSEventModifierFlagControl) if (flags & NSEventModifierFlagControl)
imgui_flags |= ImGuiKeyModFlags_Ctrl; imgui_key_mods |= ImGuiKeyModFlags_Ctrl;
if (flags & NSEventModifierFlagOption) if (flags & NSEventModifierFlagOption)
imgui_flags |= ImGuiKeyModFlags_Alt; imgui_key_mods |= ImGuiKeyModFlags_Alt;
if (flags & NSEventModifierFlagCommand) if (flags & NSEventModifierFlagCommand)
imgui_flags |= ImGuiKeyModFlags_Super; imgui_key_mods |= ImGuiKeyModFlags_Super;
io.AddKeyModsEvent(imgui_key_mods);
g_KeyModifiers = imgui_flags;
ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code); ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
if (key != ImGuiKey_None) if (key != ImGuiKey_None)
@ -707,7 +687,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
} }
else if (imgui_mask) else if (imgui_mask)
{ {
io.AddKeyEvent(key, (imgui_flags & imgui_mask) != 0); io.AddKeyEvent(key, (imgui_key_mods & imgui_mask) != 0);
} }
io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code) io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
} }

View File

@ -21,6 +21,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. // 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. // 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
@ -88,7 +90,6 @@ struct ImGui_ImplSDL2_Data
SDL_Window* Window; SDL_Window* Window;
Uint64 Time; Uint64 Time;
int MouseButtonsDown; int MouseButtonsDown;
bool MousePressed[3];
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
char* ClipboardTextData; char* ClipboardTextData;
bool MouseCanUseGlobalState; bool MouseCanUseGlobalState;
@ -178,12 +179,12 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd; case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter; case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual; case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
case SDLK_LSHIFT: return ImGuiKey_LeftShift; case SDLK_LSHIFT: return ImGuiKey_LeftShift;
case SDLK_LCTRL: return ImGuiKey_LeftControl;
case SDLK_LALT: return ImGuiKey_LeftAlt; case SDLK_LALT: return ImGuiKey_LeftAlt;
case SDLK_LGUI: return ImGuiKey_LeftSuper; case SDLK_LGUI: return ImGuiKey_LeftSuper;
case SDLK_RCTRL: return ImGuiKey_RightCtrl;
case SDLK_RSHIFT: return ImGuiKey_RightShift; case SDLK_RSHIFT: return ImGuiKey_RightShift;
case SDLK_RCTRL: return ImGuiKey_RightControl;
case SDLK_RALT: return ImGuiKey_RightAlt; case SDLK_RALT: return ImGuiKey_RightAlt;
case SDLK_RGUI: return ImGuiKey_RightSuper; case SDLK_RGUI: return ImGuiKey_RightSuper;
case SDLK_MENU: return ImGuiKey_Menu; case SDLK_MENU: return ImGuiKey_Menu;
@ -239,6 +240,17 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
return ImGuiKey_None; return ImGuiKey_None;
} }
static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiKeyModFlags key_mods =
((sdl_key_mods & KMOD_CTRL) ? ImGuiKeyModFlags_Ctrl : 0) |
((sdl_key_mods & KMOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) |
((sdl_key_mods & KMOD_ALT) ? ImGuiKeyModFlags_Alt : 0) |
((sdl_key_mods & KMOD_GUI) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // 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.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. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
@ -261,15 +273,14 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
mouse_pos.x += window_x; mouse_pos.x += window_x;
mouse_pos.y += window_y; mouse_pos.y += window_y;
} }
io.MousePos = mouse_pos; io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
return true; return true;
} }
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
{ {
if (event->wheel.x > 0) io.MouseWheelH += 1; float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f;
if (event->wheel.x < 0) io.MouseWheelH -= 1; float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f;
if (event->wheel.y > 0) io.MouseWheel += 1; io.AddMouseWheelEvent(wheel_x, wheel_y);
if (event->wheel.y < 0) io.MouseWheel -= 1;
return true; return true;
} }
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
@ -279,10 +290,9 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; } 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_RIGHT) { mouse_button = 1; }
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; } if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
if (mouse_button != -1) if (mouse_button == -1)
break; break;
if (event->type == SDL_MOUSEBUTTONDOWN) io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN));
bd->MousePressed[mouse_button] = true;
bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button)); bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
return true; return true;
} }
@ -294,6 +304,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
@ -303,7 +314,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
{ {
Uint8 window_event = event->window.event; Uint8 window_event = event->window.event;
if (window_event == SDL_WINDOWEVENT_LEAVE) if (window_event == SDL_WINDOWEVENT_LEAVE)
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
io.AddFocusEvent(true); io.AddFocusEvent(true);
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
@ -495,19 +506,12 @@ static void ImGui_ImplSDL2_UpdateMouseData()
mouse_x -= window_x; mouse_x -= window_x;
mouse_y -= window_y; mouse_y -= window_y;
} }
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
} }
} }
// We don't support ImGuiBackendFlags_HasMouseHoveredViewport // We don't support ImGuiBackendFlags_HasMouseHoveredViewport
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
// Update buttons
Uint32 mouse_buttons = SDL_GetMouseState(NULL, NULL);
io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false;
} }
static void ImGui_ImplSDL2_UpdateMouseCursor() static void ImGui_ImplSDL2_UpdateMouseCursor()
@ -600,18 +604,6 @@ static void ImGui_ImplSDL2_UpdateMonitors()
} }
} }
static void ImGui_ImplSDL2_UpdateKeyModifiers()
{
ImGuiIO& io = ImGui::GetIO();
SDL_Keymod sdl_key_mods = SDL_GetModState();
ImGuiKeyModFlags key_mods =
((sdl_key_mods & KMOD_CTRL) ? ImGuiKeyModFlags_Ctrl : 0) |
((sdl_key_mods & KMOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) |
((sdl_key_mods & KMOD_ALT) ? ImGuiKeyModFlags_Alt : 0) |
((sdl_key_mods & KMOD_GUI) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods);
}
void ImGui_ImplSDL2_NewFrame() void ImGui_ImplSDL2_NewFrame()
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
@ -635,7 +627,6 @@ void ImGui_ImplSDL2_NewFrame()
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
ImGui_ImplSDL2_UpdateKeyModifiers();
ImGui_ImplSDL2_UpdateMouseData(); ImGui_ImplSDL2_UpdateMouseData();
ImGui_ImplSDL2_UpdateMouseCursor(); ImGui_ImplSDL2_UpdateMouseCursor();

View File

@ -57,7 +57,7 @@ struct ImGui_ImplVulkan_InitInfo
uint32_t Subpass; uint32_t Subpass;
uint32_t MinImageCount; // >= 2 uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
const VkAllocationCallbacks* Allocator; const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err); void (*CheckVkResultFn)(VkResult err);
}; };

View File

@ -36,8 +36,10 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-12: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. // 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before a key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness. // 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages. // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
@ -251,10 +253,10 @@ static void ImGui_ImplWin32_UpdateKeyModifiers()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiKeyModFlags key_mods = ImGuiKeyModFlags key_mods =
((IsVkDown(VK_LCONTROL) || IsVkDown(VK_RCONTROL)) ? ImGuiKeyModFlags_Ctrl : 0) | ((IsVkDown(VK_CONTROL)) ? ImGuiKeyModFlags_Ctrl : 0) |
((IsVkDown(VK_LSHIFT) || IsVkDown(VK_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) | ((IsVkDown(VK_SHIFT) ) ? ImGuiKeyModFlags_Shift : 0) |
((IsVkDown(VK_LMENU) || IsVkDown(VK_RMENU)) ? ImGuiKeyModFlags_Alt : 0) | ((IsVkDown(VK_MENU)) ? ImGuiKeyModFlags_Alt : 0) |
((IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN)) ? ImGuiKeyModFlags_Super : 0); ((IsVkDown(VK_APPS)) ? ImGuiKeyModFlags_Super : 0);
io.AddKeyModsEvent(key_mods); io.AddKeyModsEvent(key_mods);
} }
@ -293,7 +295,7 @@ static void ImGui_ImplWin32_UpdateMouseData()
POINT mouse_pos = mouse_screen_pos; POINT mouse_pos = mouse_screen_pos;
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
::ScreenToClient(bd->hWnd, &mouse_pos); ::ScreenToClient(bd->hWnd, &mouse_pos);
io.MousePos = ImVec2((float)mouse_pos.x, (float)mouse_pos.y); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
} }
} }
@ -414,9 +416,6 @@ void ImGui_ImplWin32_NewFrame()
// Process workarounds for known Windows key handling issues // Process workarounds for known Windows key handling issues
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(); ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
// Update key modifiers
ImGui_ImplWin32_UpdateKeyModifiers();
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
if (bd->LastMouseCursor != mouse_cursor) if (bd->LastMouseCursor != mouse_cursor)
@ -485,11 +484,11 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
case VK_ADD: return ImGuiKey_KeypadAdd; case VK_ADD: return ImGuiKey_KeypadAdd;
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter; case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
case VK_LSHIFT: return ImGuiKey_LeftShift; case VK_LSHIFT: return ImGuiKey_LeftShift;
case VK_LCONTROL: return ImGuiKey_LeftControl; case VK_LCONTROL: return ImGuiKey_LeftCtrl;
case VK_LMENU: return ImGuiKey_LeftAlt; case VK_LMENU: return ImGuiKey_LeftAlt;
case VK_LWIN: return ImGuiKey_LeftSuper; case VK_LWIN: return ImGuiKey_LeftSuper;
case VK_RSHIFT: return ImGuiKey_RightShift; case VK_RSHIFT: return ImGuiKey_RightShift;
case VK_RCONTROL: return ImGuiKey_RightControl; case VK_RCONTROL: return ImGuiKey_RightCtrl;
case VK_RMENU: return ImGuiKey_RightAlt; case VK_RMENU: return ImGuiKey_RightAlt;
case VK_RWIN: return ImGuiKey_RightSuper; case VK_RWIN: return ImGuiKey_RightSuper;
case VK_APPS: return ImGuiKey_Menu; case VK_APPS: return ImGuiKey_Menu;
@ -588,14 +587,14 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) }; POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
::ClientToScreen(hwnd, &mouse_pos); ::ClientToScreen(hwnd, &mouse_pos);
io.MousePos = ImVec2((float)mouse_pos.x, (float)mouse_pos.y); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
break; break;
} }
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
if (bd->MouseHwnd == hwnd) if (bd->MouseHwnd == hwnd)
bd->MouseHwnd = NULL; bd->MouseHwnd = NULL;
bd->MouseTracked = false; bd->MouseTracked = false;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
break; break;
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
@ -610,7 +609,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL) if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
::SetCapture(hwnd); ::SetCapture(hwnd);
bd->MouseButtonsDown |= 1 << button; bd->MouseButtonsDown |= 1 << button;
io.MouseDown[button] = true; io.AddMouseButtonEvent(button, true);
return 0; return 0;
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
@ -626,14 +625,14 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
bd->MouseButtonsDown &= ~(1 << button); bd->MouseButtonsDown &= ~(1 << button);
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd) if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
::ReleaseCapture(); ::ReleaseCapture();
io.MouseDown[button] = false; io.AddMouseButtonEvent(button, false);
return 0; return 0;
} }
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
return 0; return 0;
case WM_MOUSEHWHEEL: case WM_MOUSEHWHEEL:
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; io.AddMouseWheelEvent((float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f);
return 0; return 0;
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_KEYUP: case WM_KEYUP:
@ -641,9 +640,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_SYSKEYUP: case WM_SYSKEYUP:
{ {
const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN); const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
if (wParam < 256) if (wParam < 256)
{ {
// Submit modifiers
ImGui_ImplWin32_UpdateKeyModifiers();
// Obtain virtual key code // Obtain virtual key code
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.) // (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
int vk = (int)wParam; int vk = (int)wParam;
@ -665,8 +666,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
} }
else if (vk == VK_CONTROL) else if (vk == VK_CONTROL)
{ {
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftControl, is_key_down, VK_LCONTROL, scancode); } if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightControl, is_key_down, VK_RCONTROL, scancode); } if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
} }
else if (vk == VK_MENU) else if (vk == VK_MENU)
{ {

View File

@ -9,7 +9,7 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc. e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR> - The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR>
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp), etc. e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc.
- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR> - For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR>
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same. e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
@ -88,7 +88,7 @@ The [example_emscripten_opengl3](https://github.com/ocornut/imgui/tree/master/ex
### Backends for third-party frameworks, graphics API or other languages ### Backends for third-party frameworks, graphics API or other languages
See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others). See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others).
### Recommended Backends ### Recommended Backends

View File

@ -104,7 +104,12 @@ Other changes:
Breaking Changes: Breaking Changes:
- Reworked IO keyboard input system. (#2625, #3724) [@thedmd, @ocornut] - Removed support for pre-C++11 compilers. We'll stop supporting VS2010. (#4537)
- Reworked IO mouse input API: (#4858) [@thedmd, @ocornut]
- Added io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions,
obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc.
- This enable input queue trickling to support low framerates. (#2787, #1992, #3383, #2525, #1320)
- Reworked IO keyboard input API: (#2625, #3724) [@thedmd, @ocornut]
- Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays. - Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays.
- Added io.AddKeyModsEvent() function, obsoleting writing directly to io.KeyCtrl, io.KeyShift etc. - Added io.AddKeyModsEvent() function, obsoleting writing directly to io.KeyCtrl, io.KeyShift etc.
- Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices. - Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices.
@ -113,13 +118,16 @@ Breaking Changes:
- Obsoleted GetKeyIndex(): it is now unnecessary and will now return the same value. - Obsoleted GetKeyIndex(): it is now unnecessary and will now return the same value.
- All keyboard related functions taking 'int user_key_index' now take 'ImGuiKey key': - All keyboard related functions taking 'int user_key_index' now take 'ImGuiKey key':
- IsKeyDown(), IsKeyPressed(), IsKeyReleased(), GetKeyPressedAmount(). - IsKeyDown(), IsKeyPressed(), IsKeyReleased(), GetKeyPressedAmount().
- All backends were updated to use io.AddKeyEvent(). - Added io.ConfigInputEventQueue (defaulting to true) to disable input queue trickling.
- Backward compatibility: - Backward compatibility:
- Old backends populating those arrays will still work! (for a while) - All backends updated to use new functions.
- Old backends populating those arrays should still work!
- Calling e.g. IsKeyPressed(MY_NATIVE_KEY_XXX) will still work! (for a while) - Calling e.g. IsKeyPressed(MY_NATIVE_KEY_XXX) will still work! (for a while)
- Those legacy arrays will only be disabled if '#define IMGUI_DISABLE_OBSOLETE_KEYIO' is set in your imconfig. - Those legacy arrays will only be disabled if '#define IMGUI_DISABLE_OBSOLETE_KEYIO' is set in your imconfig.
In a few versions, IMGUI_DISABLE_OBSOLETE_FUNCTIONS will automatically enable IMGUI_DISABLE_OBSOLETE_KEYIO, In a few versions, IMGUI_DISABLE_OBSOLETE_FUNCTIONS will automatically enable IMGUI_DISABLE_OBSOLETE_KEYIO,
so this will be moved into the regular obsolescence path. so this will be moved into the regular obsolescence path.
- BREAKING: If your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A")
this is a use case that will now assert and be breaking for your old backend.
- Transition guide: - Transition guide:
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
@ -153,6 +161,9 @@ Breaking Changes:
Other Changes: Other Changes:
- IO: Added event based input queue API, which now trickles events to support low framerates. [@thedmd, @ocornut]
Previously the most common issue case (button presses in low framerates) was handled by backend. This is now
handled by core automatically for all kind of inputs. (#4858, #2787, #1992, #3383, #2525, #1320)
- Fixed a situation where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles, - Fixed a situation where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles,
which would makes the draw operation of some backends assert (e.g. Metal with debugging). (#4857) which would makes the draw operation of some backends assert (e.g. Metal with debugging). (#4857)
- Tables, ImDrawListSplitter: Fixed erroneously stripping trailing ImDrawList::AddCallback() when submitted in - Tables, ImDrawListSplitter: Fixed erroneously stripping trailing ImDrawList::AddCallback() when submitted in
@ -166,13 +177,22 @@ Other Changes:
- Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. - Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every
other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625) other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
- Backends: GLFW: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
- Backends: GLFW: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
- Backends: GLFW: Update mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured. - Backends: GLFW: Update mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured.
- Backends: Win32: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
- Backends: Win32: Update mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured. - Backends: Win32: Update mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured.
- Backends: Win32: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
- Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. - Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. - Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
- Backends: SDL: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
- Backends: SDL: Update mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured. - Backends: SDL: Update mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured.
- Backends: SDL: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
- Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. - Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
- Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd] - Backends: Allegro5: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
- Backends: Allegro5: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
- Backends: Android, GLUT, OSX: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
- Backends: Android, GLUT, OSX: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk] - Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers. It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.
- Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz] - Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz]
@ -180,6 +200,7 @@ Other Changes:
- Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but - Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but
can theorically be created by user code manipulating a ImDrawList. (#4857) can theorically be created by user code manipulating a ImDrawList. (#4857)
- Backends: OSX: Added basic Platform IME support. (#3108, #2598) [@liuliu] - Backends: OSX: Added basic Platform IME support. (#3108, #2598) [@liuliu]
- Backends: OSX: Fix Game Controller nav mapping to use shoulder for both focusing and tweak speed. (#4759)
- Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and - Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and
wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev] wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev]

View File

@ -416,9 +416,11 @@ int main(int, char**)
init_info.Queue = g_Queue; init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator; init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount; init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount; init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);

View File

@ -408,9 +408,11 @@ int main(int, char**)
init_info.Queue = g_Queue; init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator; init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount; init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount; init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);

249
imgui.cpp
View File

@ -398,6 +398,7 @@ CODE
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
- Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() - Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent()
- one case won't work with backward compatibility: if your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A") because those values are now larger than the legacy KeyDown[] array. Will assert.
- inputs: added io.AddKeyModsEvent() instead of writing directly to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper. - inputs: added io.AddKeyModsEvent() instead of writing directly to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper.
- 2022/01/05 (1.87) - inputs: renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. - 2022/01/05 (1.87) - inputs: renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum.
- 2022/01/05 (1.87) - removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn(). Removed 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'. - 2022/01/05 (1.87) - removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn(). Removed 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.
@ -1171,6 +1172,7 @@ ImGuiIO::ImGuiIO()
#else #else
ConfigMacOSXBehaviors = false; ConfigMacOSXBehaviors = false;
#endif #endif
ConfigInputEventQueue = true;
ConfigInputTextCursorBlink = true; ConfigInputTextCursorBlink = true;
ConfigWindowsResizeFromEdges = true; ConfigWindowsResizeFromEdges = true;
ConfigWindowsMoveFromTitleBarOnly = false; ConfigWindowsMoveFromTitleBarOnly = false;
@ -1197,10 +1199,19 @@ ImGuiIO::ImGuiIO()
// Pass in translated ASCII characters for text input. // Pass in translated ASCII characters for text input.
// - with glfw you can get those from the callback set in glfwSetCharCallback() // - with glfw you can get those from the callback set in glfwSetCharCallback()
// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
// FIXME: Should in theory be called "AddCharacterEvent()" to be consistent with new API
void ImGuiIO::AddInputCharacter(unsigned int c) void ImGuiIO::AddInputCharacter(unsigned int c)
{ {
if (c != 0) ImGuiContext& g = *GImGui;
InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); IM_ASSERT(&g.IO == this && "Can only add events to current context.");
if (c == 0)
return;
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_Char;
e.Source = ImGuiInputSource_Keyboard;
e.Text.Char = c;
g.InputEventsQueue.push_back(e);
} }
// UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so
@ -1213,7 +1224,7 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
if ((c & 0xFC00) == 0xD800) // High surrogate, must save if ((c & 0xFC00) == 0xD800) // High surrogate, must save
{ {
if (InputQueueSurrogate != 0) if (InputQueueSurrogate != 0)
InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID); AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
InputQueueSurrogate = c; InputQueueSurrogate = c;
return; return;
} }
@ -1223,7 +1234,7 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
{ {
if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate
{ {
InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID); AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
} }
else else
{ {
@ -1236,7 +1247,7 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
InputQueueSurrogate = 0; InputQueueSurrogate = 0;
} }
InputQueueCharacters.push_back(cp); AddInputCharacter((unsigned)cp);
} }
void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
@ -1246,7 +1257,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
unsigned int c = 0; unsigned int c = 0;
utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL); utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
if (c != 0) if (c != 0)
InputQueueCharacters.push_back((ImWchar)c); AddInputCharacter(c);
} }
} }
@ -1275,12 +1286,13 @@ void ImGuiIO::ClearInputKeys()
// Queue a new key down/up event. // Queue a new key down/up event.
// - ImGuiKey key: Translated key (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) // - ImGuiKey key: Translated key (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character)
// - bool down: Is the key down? use false to signify a key release. // - bool down: Is the key down? use false to signify a key release.
// FIXME: In the current version this is setting key data immediately. This will evolve into a trickling queue.
void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down) void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down)
{ {
//if (e->Down) { IMGUI_DEBUG_LOG("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); } //if (e->Down) { IMGUI_DEBUG_LOG("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); }
if (key == ImGuiKey_None) if (key == ImGuiKey_None)
return; return;
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
IM_ASSERT(ImGui::IsNamedKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API. IM_ASSERT(ImGui::IsNamedKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API.
// Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data. // Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data.
@ -1289,15 +1301,18 @@ void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down)
if (BackendUsingLegacyKeyArrays == -1) if (BackendUsingLegacyKeyArrays == -1)
for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++) for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
IM_ASSERT(KeyMap[n] == -1 && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); IM_ASSERT(KeyMap[n] == -1 && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
#endif
BackendUsingLegacyKeyArrays = 0; BackendUsingLegacyKeyArrays = 0;
#endif
// Write key ImGuiInputEvent e;
const int keydata_index = (key - ImGuiKey_KeysData_OFFSET); e.Type = ImGuiInputEventType_Key;
KeysData[keydata_index].Down = down; e.Source = ImGuiInputSource_Keyboard;
e.Key.Key = key;
e.Key.Down = down;
g.InputEventsQueue.push_back(e);
} }
// [Optional] Call add AddKeyEvent(). // [Optional] Call after AddKeyEvent().
// Specify native keycode, scancode + Specify index for legacy <1.87 IsKeyXXX() functions with native indices. // Specify native keycode, scancode + Specify index for legacy <1.87 IsKeyXXX() functions with native indices.
// If you are writing a backend in 2022 or don't use IsKeyXXX() with native values that are not ImGuiKey values, you can avoid calling this. // If you are writing a backend in 2022 or don't use IsKeyXXX() with native values that are not ImGuiKey values, you can avoid calling this.
void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index) void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index)
@ -1322,18 +1337,68 @@ void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native
void ImGuiIO::AddKeyModsEvent(ImGuiKeyModFlags modifiers) void ImGuiIO::AddKeyModsEvent(ImGuiKeyModFlags modifiers)
{ {
KeyMods = modifiers; ImGuiContext& g = *GImGui;
KeyCtrl = (modifiers & ImGuiKeyModFlags_Ctrl) != 0; IM_ASSERT(&g.IO == this && "Can only add events to current context.");
KeyShift = (modifiers & ImGuiKeyModFlags_Shift) != 0;
KeyAlt = (modifiers & ImGuiKeyModFlags_Alt) != 0; ImGuiInputEvent e;
KeySuper = (modifiers & ImGuiKeyModFlags_Super) != 0; e.Type = ImGuiInputEventType_KeyMods;
e.Source = ImGuiInputSource_Keyboard;
e.KeyMods.Mods = modifiers;
g.InputEventsQueue.push_back(e);
}
// Queue a mouse move event
void ImGuiIO::AddMousePosEvent(float x, float y)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_MousePos;
e.Source = ImGuiInputSource_Mouse;
e.MousePos.PosX = x;
e.MousePos.PosY = y;
g.InputEventsQueue.push_back(e);
}
void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
if (wheel_x == 0.0f && wheel_y == 0.0f)
return;
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_MouseWheel;
e.Source = ImGuiInputSource_Mouse;
e.MouseWheel.WheelX = wheel_x;
e.MouseWheel.WheelY = wheel_y;
g.InputEventsQueue.push_back(e);
}
void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT);
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_MouseButton;
e.Source = ImGuiInputSource_Mouse;
e.MouseButton.Button = mouse_button;
e.MouseButton.Down = down;
g.InputEventsQueue.push_back(e);
} }
void ImGuiIO::AddFocusEvent(bool focused) void ImGuiIO::AddFocusEvent(bool focused)
{ {
// We intentionally overwrite this and process in NewFrame(), in order to give a chance ImGuiContext& g = *GImGui;
// to multi-viewports backends to queue AddFocusEvent(false),AddFocusEvent(true) in same frame. IM_ASSERT(&g.IO == this && "Can only add events to current context.");
AppFocusLost = !focused;
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_Focus;
e.AppFocused.Focused = focused;
g.InputEventsQueue.push_back(e);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -4014,7 +4079,7 @@ static void ImGui::UpdateMouseInputs()
// Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
if (IsMousePosValid(&io.MousePos)) if (IsMousePosValid(&io.MousePos))
io.MousePos = g.MouseLastValidPos = ImFloor(io.MousePos); io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos);
// If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev)) if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev))
@ -4375,13 +4440,9 @@ void ImGui::NewFrame()
//if (g.IO.AppFocusLost) //if (g.IO.AppFocusLost)
// ClosePopupsExceptModals(); // ClosePopupsExceptModals();
// Clear buttons state when focus is lost // Process input queue (trickle as many events as possible)
// (this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle) g.InputEventsTrail.resize(0);
if (g.IO.AppFocusLost) UpdateInputEvents(g.IO.ConfigInputEventQueue);
{
g.IO.ClearInputKeys();
g.IO.AppFocusLost = false;
}
// Update keyboard input state // Update keyboard input state
UpdateKeyboardInputs(); UpdateKeyboardInputs();
@ -7998,8 +8059,8 @@ static const char* const GKeyNames[] =
"Backslash", "RightBracket", "GraveAccent", "CapsLock", "ScrollLock", "NumLock", "PrintScreen", "Backslash", "RightBracket", "GraveAccent", "CapsLock", "ScrollLock", "NumLock", "PrintScreen",
"Pause", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", "Pause", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6",
"Keypad7", "Keypad8", "Keypad9", "KeypadDecimal", "KeypadDivide", "KeypadMultiply", "Keypad7", "Keypad8", "Keypad9", "KeypadDecimal", "KeypadDivide", "KeypadMultiply",
"KeypadSubtract", "KeypadAdd", "KeypadEnter", "KeypadEqual", "LeftShift", "LeftControl", "KeypadSubtract", "KeypadAdd", "KeypadEnter", "KeypadEqual", "LeftCtrl", "LeftShift",
"LeftAlt", "LeftSuper", "RightShift", "RightControl", "RightAlt", "RightSuper", "Menu", "LeftAlt", "LeftSuper", "RightCtrl", "RightShift", "RightAlt", "RightSuper", "Menu",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12" "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"
@ -8238,6 +8299,134 @@ static const char* GetInputSourceName(ImGuiInputSource source)
} }
// Process input queue
// - trickle_fast_inputs = false : process all events, turn into flattened input state (e.g. successive down/up/down/up will be lost)
// - trickle_fast_inputs = true : process as many events as possible (successive down/up/down/up will be trickled over several frames so nothing is lost) (new feature in 1.87)
void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
{
ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO;
bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputed = false;
int mouse_button_changed = 0x00, key_mods_changed = 0x00;
ImBitArray<ImGuiKey_KeysData_SIZE> key_changed_mask;
int event_n = 0;
for (; event_n < g.InputEventsQueue.Size; event_n++)
{
const ImGuiInputEvent* e = &g.InputEventsQueue[event_n];
if (e->Type == ImGuiInputEventType_MousePos)
{
ImVec2 event_pos(e->MousePos.PosX, e->MousePos.PosY);
if (IsMousePosValid(&event_pos))
event_pos = ImVec2(ImFloorSigned(event_pos.x), ImFloorSigned(event_pos.y)); // Apply same flooring as UpdateMouseInputs()
if (io.MousePos.x != event_pos.x || io.MousePos.y != event_pos.y)
{
// Trickling Rule: Stop processing queued events if we already handled a mouse button change
if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || key_mods_changed || text_inputed))
break;
io.MousePos = event_pos;
mouse_moved = true;
}
}
else if (e->Type == ImGuiInputEventType_MouseButton)
{
const ImGuiMouseButton button = e->MouseButton.Button;
IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT);
if (io.MouseDown[button] != e->MouseButton.Down)
{
// Trickling Rule: Stop processing queued events if we got multiple action on the same button
if (trickle_fast_inputs && ((mouse_button_changed & (1 << button)) || mouse_wheeled))
break;
io.MouseDown[button] = e->MouseButton.Down;
mouse_button_changed |= (1 << button);
}
}
else if (e->Type == ImGuiInputEventType_MouseWheel)
{
if (e->MouseWheel.WheelX != 0.0f || e->MouseWheel.WheelY != 0.0f)
{
// Trickling Rule: Stop processing queued events if we got multiple action on the event
if (trickle_fast_inputs && (mouse_wheeled || mouse_button_changed != 0))
break;
io.MouseWheelH += e->MouseWheel.WheelX;
io.MouseWheel += e->MouseWheel.WheelY;
mouse_wheeled = true;
}
}
else if (e->Type == ImGuiInputEventType_Key)
{
IM_ASSERT(e->Key.Key != ImGuiKey_None);
const int keydata_index = (e->Key.Key - ImGuiKey_KeysData_OFFSET);
ImGuiKeyData* keydata = &io.KeysData[keydata_index];
if (keydata->Down != e->Key.Down)
{
// Trickling Rule: Stop processing queued events if we got multiple action on the same button
if (trickle_fast_inputs && (key_changed_mask.TestBit(keydata_index) || text_inputed || mouse_button_changed != 0))
break;
keydata->Down = e->Key.Down;
key_changed = true;
key_changed_mask.SetBit(keydata_index);
}
}
else if (e->Type == ImGuiInputEventType_KeyMods)
{
const ImGuiKeyModFlags modifiers = e->KeyMods.Mods;
if (io.KeyMods != modifiers)
{
// Trickling Rule: Stop processing queued events if we got multiple action on the same button
ImGuiKeyModFlags modifiers_that_are_changing = (io.KeyMods ^ modifiers);
if (trickle_fast_inputs && (key_mods_changed & modifiers_that_are_changing) != 0)
break;
io.KeyMods = modifiers;
io.KeyCtrl = (modifiers & ImGuiKeyModFlags_Ctrl) != 0;
io.KeyShift = (modifiers & ImGuiKeyModFlags_Shift) != 0;
io.KeyAlt = (modifiers & ImGuiKeyModFlags_Alt) != 0;
io.KeySuper = (modifiers & ImGuiKeyModFlags_Super) != 0;
key_mods_changed |= modifiers_that_are_changing;
}
}
else if (e->Type == ImGuiInputEventType_Char)
{
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
break;
unsigned int c = e->Text.Char;
io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
text_inputed = true;
}
else if (e->Type == ImGuiInputEventType_Focus)
{
// We intentionally overwrite this and process lower, in order to give a chance
// to multi-viewports backends to queue AddFocusEvent(false) + AddFocusEvent(true) in same frame.
io.AppFocusLost = !e->AppFocused.Focused;
}
else
{
IM_ASSERT(0 && "Unknown event!");
}
}
// Record trail (for domain-specific applications wanting to access a precise trail)
for (int n = 0; n < event_n; n++)
g.InputEventsTrail.push_back(g.InputEventsQueue[n]);
// Remaining events will be processed on the next frame
if (event_n == g.InputEventsQueue.Size)
g.InputEventsQueue.resize(0);
else
g.InputEventsQueue.erase(g.InputEventsQueue.Data, g.InputEventsQueue.Data + event_n);
// Clear buttons state when focus is lost
// (this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle)
if (g.IO.AppFocusLost)
{
g.IO.ClearInputKeys();
g.IO.AppFocusLost = false;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ERROR CHECKING // [SECTION] ERROR CHECKING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

28
imgui.h
View File

@ -65,7 +65,7 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.87 WIP" #define IMGUI_VERSION "1.87 WIP"
#define IMGUI_VERSION_NUM 18605 #define IMGUI_VERSION_NUM 18608
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -88,11 +88,7 @@ Index of this file:
#endif #endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11 #define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
#else
#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro.
#endif
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__) #if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__)
@ -234,17 +230,8 @@ typedef signed short ImS16; // 16-bit signed integer
typedef unsigned short ImU16; // 16-bit unsigned integer typedef unsigned short ImU16; // 16-bit unsigned integer
typedef signed int ImS32; // 32-bit signed integer == int typedef signed int ImS32; // 32-bit signed integer == int
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
#if defined(_MSC_VER) && !defined(__clang__) typedef signed long long ImS64; // 64-bit signed integer (C++11)
typedef signed __int64 ImS64; // 64-bit signed integer (pre and post C++11 with Visual Studio) typedef unsigned long long ImU64; // 64-bit unsigned integer (C++11)
typedef unsigned __int64 ImU64; // 64-bit unsigned integer (pre and post C++11 with Visual Studio)
#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100)
#include <stdint.h>
typedef int64_t ImS64; // 64-bit signed integer (pre C++11)
typedef uint64_t ImU64; // 64-bit unsigned integer (pre C++11)
#else
typedef signed long long ImS64; // 64-bit signed integer (post C++11)
typedef unsigned long long ImU64; // 64-bit unsigned integer (post C++11)
#endif
// Character types // Character types
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) // (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
@ -1466,12 +1453,12 @@ enum ImGuiKey_
ImGuiKey_KeypadAdd, ImGuiKey_KeypadAdd,
ImGuiKey_KeypadEnter, ImGuiKey_KeypadEnter,
ImGuiKey_KeypadEqual, ImGuiKey_KeypadEqual,
ImGuiKey_LeftCtrl,
ImGuiKey_LeftShift, ImGuiKey_LeftShift,
ImGuiKey_LeftControl,
ImGuiKey_LeftAlt, ImGuiKey_LeftAlt,
ImGuiKey_LeftSuper, ImGuiKey_LeftSuper,
ImGuiKey_RightCtrl,
ImGuiKey_RightShift, ImGuiKey_RightShift,
ImGuiKey_RightControl,
ImGuiKey_RightAlt, ImGuiKey_RightAlt,
ImGuiKey_RightSuper, ImGuiKey_RightSuper,
ImGuiKey_Menu, ImGuiKey_Menu,
@ -2047,6 +2034,7 @@ struct ImGuiIO
// Miscellaneous options // Miscellaneous options
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations.
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
bool ConfigInputEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
@ -2098,10 +2086,14 @@ struct ImGuiIO
// Input Functions // Input Functions
IMGUI_API void AddKeyEvent(ImGuiKey key, bool down); // Queue a new key down/up event. Key should be "translated" (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) IMGUI_API void AddKeyEvent(ImGuiKey key, bool down); // Queue a new key down/up event. Key should be "translated" (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character)
IMGUI_API void AddKeyModsEvent(ImGuiKeyModFlags modifiers);// Queue a change of Ctrl/Shift/Alt/Super modifiers IMGUI_API void AddKeyModsEvent(ImGuiKeyModFlags modifiers);// Queue a change of Ctrl/Shift/Alt/Super modifiers
IMGUI_API void AddMousePosEvent(float x, float y); // Queue a mouse position update. Use -FLT_MAX,-FLT_MAX to signify no mouse (e.g. app not focused and not hovered)
IMGUI_API void AddMouseButtonEvent(int button, bool down); // Queue a mouse button change
IMGUI_API void AddMouseWheelEvent(float wh_x, float wh_y); // Queue a mouse wheel update
IMGUI_API void AddFocusEvent(bool focused); // Queue an hosting application/platform windows gain or loss of focus IMGUI_API void AddFocusEvent(bool focused); // Queue an hosting application/platform windows gain or loss of focus
IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input
IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate
IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue new characters input from an UTF-8 string IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue new characters input from an UTF-8 string
IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually
IMGUI_API void ClearInputKeys(); // [Internal] Release all keys IMGUI_API void ClearInputKeys(); // [Internal] Release all keys
IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode. IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode.

View File

@ -93,6 +93,7 @@ Index of this file:
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4127) // condition expression is constant
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). #pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#endif #endif
@ -513,8 +514,10 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Unindent(); ImGui::Unindent();
} }
ImGui::Checkbox("io.ConfigInputEventQueue", &io.ConfigInputEventQueue);
ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)"); ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText); ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving)."); ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);

View File

@ -207,19 +207,17 @@ namespace ImStb
// Debug Logging for selected systems. Remove the '((void)0) //' to enable. // Debug Logging for selected systems. Remove the '((void)0) //' to enable.
//#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log
//#define IMGUI_DEBUG_LOG_NAV IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_NAV IMGUI_DEBUG_LOG // Enable log
//#define IMGUI_DEBUG_LOG_IO IMGUI_DEBUG_LOG // Enable log
//#define IMGUI_DEBUG_LOG_VIEWPORT IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_VIEWPORT IMGUI_DEBUG_LOG // Enable log
//#define IMGUI_DEBUG_LOG_DOCKING IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_DOCKING IMGUI_DEBUG_LOG // Enable log
#define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log #define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log
#define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log #define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log
#define IMGUI_DEBUG_LOG_IO(...) ((void)0) // Disable log
#define IMGUI_DEBUG_LOG_VIEWPORT(...) ((void)0) // Disable log #define IMGUI_DEBUG_LOG_VIEWPORT(...) ((void)0) // Disable log
#define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log #define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log
// Static Asserts // Static Asserts
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "") #define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
#else
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
#endif
// "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much. // "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much.
// We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code. // We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code.
@ -455,6 +453,7 @@ static inline float ImInvLength(const ImVec2& lhs, float fail_value)
static inline float ImFloor(float f) { return (float)(int)(f); } static inline float ImFloor(float f) { return (float)(int)(f); }
static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline ImVec2 ImFloorSigned(const ImVec2& v) { return ImVec2(ImFloorSigned(v.x), ImFloorSigned(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
@ -912,6 +911,19 @@ enum ImGuiPlotType
ImGuiPlotType_Histogram ImGuiPlotType_Histogram
}; };
enum ImGuiInputEventType
{
ImGuiInputEventType_None = 0,
ImGuiInputEventType_MousePos,
ImGuiInputEventType_MouseWheel,
ImGuiInputEventType_MouseButton,
ImGuiInputEventType_Key,
ImGuiInputEventType_KeyMods,
ImGuiInputEventType_Char,
ImGuiInputEventType_Focus,
ImGuiInputEventType_COUNT
};
enum ImGuiInputSource enum ImGuiInputSource
{ {
ImGuiInputSource_None = 0, ImGuiInputSource_None = 0,
@ -923,6 +935,35 @@ enum ImGuiInputSource
ImGuiInputSource_COUNT ImGuiInputSource_COUNT
}; };
// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension?
// Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor'
struct ImGuiInputEventMousePos { float PosX, PosY; };
struct ImGuiInputEventMouseWheel { float WheelX, WheelY; };
struct ImGuiInputEventMouseButton { int Button; bool Down; };
struct ImGuiInputEventKey { ImGuiKey Key; bool Down; };
struct ImGuiInputEventKeyMods { ImGuiKeyModFlags Mods; };
struct ImGuiInputEventText { unsigned int Char; };
struct ImGuiInputEventAppFocused { bool Focused; };
struct ImGuiInputEvent
{
ImGuiInputEventType Type;
ImGuiInputSource Source;
bool SubmittedByTestEngine;
union
{
ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos
ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel
ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton
ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key
ImGuiInputEventKeyMods KeyMods; // if Type == ImGuiInputEventType_Modifiers
ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text
ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus
};
ImGuiInputEvent() { memset(this, 0, sizeof(*this)); }
};
// FIXME-NAV: Clarify/expose various repeat delay/rate // FIXME-NAV: Clarify/expose various repeat delay/rate
enum ImGuiInputReadMode enum ImGuiInputReadMode
{ {
@ -1676,6 +1717,8 @@ struct ImGuiContext
bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it. bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
ImGuiIO IO; ImGuiIO IO;
ImGuiPlatformIO PlatformIO; ImGuiPlatformIO PlatformIO;
ImVector<ImGuiInputEvent> InputEventsQueue; // Input events which will be tricked/written into IO structure.
ImVector<ImGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail.
ImGuiStyle Style; ImGuiStyle Style;
ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame() ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
ImGuiConfigFlags ConfigFlagsLastFrame; ImGuiConfigFlags ConfigFlagsLastFrame;
@ -2682,6 +2725,7 @@ namespace ImGui
IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
// NewFrame // NewFrame
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock_floating_node); IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock_floating_node);