Merge branch 'master' into docking (will need further for io.AddFocusEvent)

# Conflicts:
#	backends/imgui_impl_glfw.cpp
#	backends/imgui_impl_opengl3.cpp
#	backends/imgui_impl_sdl.cpp
#	backends/imgui_impl_win32.cpp
#	imgui.cpp
This commit is contained in:
ocornut
2021-08-19 17:25:12 +02:00
39 changed files with 1030 additions and 7561 deletions

View File

@ -1214,6 +1214,22 @@ void ImGuiIO::ClearInputCharacters()
InputQueueCharacters.resize(0);
}
void ImGuiIO::AddFocusEvent(bool focused)
{
if (focused)
return;
// 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)
memset(KeysDown, 0, sizeof(KeysDown));
for (int n = 0; n < IM_ARRAYSIZE(KeysDownDuration); n++)
KeysDownDuration[n] = KeysDownDurationPrev[n] = -1.0f;
KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
KeyMods = KeyModsPrev = ImGuiKeyModFlags_None;
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
}
//-----------------------------------------------------------------------------
// [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
//-----------------------------------------------------------------------------
@ -4717,6 +4733,7 @@ void ImGui::EndFrame()
// Clear Input data for next frame
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
g.IO.InputQueueCharacters.resize(0);
g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
@ -9755,16 +9772,6 @@ static void ImGui::NavUpdate()
io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
if (io.KeyShift)
io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
// AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl)
// But also even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
if (io.KeyAlt && !io.KeyCtrl)
io.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f;
// We automatically cancel toggling nav layer when any text has been typed while holding Alt. (See #370)
if (io.KeyAlt && !io.KeyCtrl && g.NavWindowingToggleLayer && io.InputQueueCharacters.Size > 0)
g.NavWindowingToggleLayer = false;
#undef NAV_MAP_KEY
}
memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
@ -10257,6 +10264,8 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
static void ImGui::NavUpdateWindowing()
{
ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO;
ImGuiWindow* apply_focus_window = NULL;
bool apply_toggle_layer = false;
@ -10268,25 +10277,25 @@ static void ImGui::NavUpdateWindowing()
// Fade out
if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL)
{
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - g.IO.DeltaTime * 10.0f, 0.0f);
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - io.DeltaTime * 10.0f, 0.0f);
if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f)
g.NavWindowingTargetAnim = NULL;
}
// Start CTRL-TAB or Square+L/R window selection
bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
{
g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow;
g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true;
g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer
g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
}
// Gamepad update
g.NavWindowingTimer += g.IO.DeltaTime;
g.NavWindowingTimer += io.DeltaTime;
if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad)
{
// Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise
@ -10318,31 +10327,49 @@ static void ImGui::NavUpdateWindowing()
// Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
if (IsKeyPressedMap(ImGuiKey_Tab, true))
NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1);
if (!g.IO.KeyCtrl)
NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1);
if (!io.KeyCtrl)
apply_focus_window = g.NavWindowingTarget;
}
// Keyboard: Press and Release ALT to toggle menu layer
// FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of backend clearing releases all keys on ALT-TAB
if (IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Pressed))
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
if (io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
{
g.NavWindowingToggleLayer = true;
if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
apply_toggle_layer = true;
g.NavInputSource = ImGuiInputSource_Keyboard;
}
if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard)
{
// We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370)
// We cancel toggling nav layer when other modifiers are pressed. (See #4439)
if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper)
g.NavWindowingToggleLayer = false;
// Apply layer toggle on release
// Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
// Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer)
if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
apply_toggle_layer = true;
if (!io.KeyAlt)
g.NavWindowingToggleLayer = false;
}
// Move window
if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
{
ImVec2 move_delta;
if (g.NavInputSource == ImGuiInputSource_Keyboard && !g.IO.KeyShift)
if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down);
if (g.NavInputSource == ImGuiInputSource_Gamepad)
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
{
const float NAV_MOVE_SPEED = 800.0f;
const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
const float move_speed = ImFloor(NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindowDockTree;
SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always);
MarkIniSettingsDirty(moving_window);
@ -10579,7 +10606,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
{
ImGuiWindow* tooltip_window = g.CurrentWindow;
tooltip_window->SkipItems = true;
tooltip_window->Hidden = tooltip_window->SkipItems = true;
tooltip_window->HiddenFramesCanSkipItems = 1;
}
}
@ -16915,16 +16942,17 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb)
{
IM_ASSERT(show_mesh || show_aabb);
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset;
// Draw wire-frame version of all triangles
ImRect clip_rect = draw_cmd->ClipRect;
ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
ImDrawListFlags backup_flags = out_draw_list->Flags;
out_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
for (unsigned int idx_n = draw_cmd->IdxOffset; idx_n < draw_cmd->IdxOffset + draw_cmd->ElemCount; )
for (unsigned int idx_n = draw_cmd->IdxOffset, idx_end = draw_cmd->IdxOffset + draw_cmd->ElemCount; idx_n < idx_end; )
{
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; // We don't hold on those pointers past iterations as ->AddPolyline() may invalidate them if out_draw_list==draw_list
ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset;
ImVec2 triangle[3];
for (int n = 0; n < 3; n++, idx_n++)
vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos));