Skip to content

Commit

Permalink
Merge branch 'master' into docking
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornut committed Sep 1, 2022
2 parents 71a0701 + 5867a43 commit bc2002a
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 79 deletions.
11 changes: 11 additions & 0 deletions backends/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// CHANGELOG
// (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-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
Expand Down Expand Up @@ -394,6 +395,8 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorPos != NULL && window == bd->Window)
bd->PrevUserCallbackCursorPos(window, x, y);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;

ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
Expand All @@ -414,6 +417,8 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorEnter != NULL && window == bd->Window)
bd->PrevUserCallbackCursorEnter(window, entered);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;

ImGuiIO& io = ImGui::GetIO();
if (entered)
Expand Down Expand Up @@ -597,6 +602,12 @@ static void ImGui_ImplGlfw_UpdateMouseData()
ImGuiIO& io = ImGui::GetIO();
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();

if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
{
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
return;
}

ImGuiID mouse_viewport_id = 0;
const ImVec2 mouse_pos_prev = io.MousePos;
for (int n = 0; n < platform_io.Viewports.Size; n++)
Expand Down
15 changes: 15 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,36 @@ Other Changes:
Enter keep the input active and select all text.
- InputText: numerical fields automatically accept full-width characters (U+FF01..U+FF5E)
by converting them to half-width (U+0021..U+007E).
- IsItemHovered: Added ImGuiHoveredFlags_DelayNormal and ImGuiHoveredFlags_DelayShort flags,
allowing to introduce a shared delay for tooltip idioms. The delays are respectively
io.HoverDelayNormal (default to 0.30f) and io.HoverDelayFast (default to 0.10f). (#1485)
- IsItemHovered: Added ImGuiHoveredFlags_NoSharedDelay to disable sharing delays between itemm,
so moving from one item to a nearby one will requires delay to elapse again. (#1485)
- Tables,Columns: fixed a layout issue where SameLine() prior to a row change would set the
next row in such state where subsequent SameLine() would move back to previous row.
- Tabs: Fixed a crash when closing multiple windows (possible with docking only) with an
appended TabItemButton(). (#5515, #3291) [@rokups]
- Window: Fixed a potential crash when appending to a child window. (#5515, #3496, #4797) [@rokups]
- IO: Added ImGuiKey_MouseXXX aliases for mouse buttons/wheel so all operations done on ImGuiKey
can apply to mouse data as well. (#4921)
- Menus: Fixed incorrect sub-menu parent association when opening a menu by closing another.
Among other things, it would accidentally break part of the closing heuristic logic when moving
towards a sub-menu. (#2517, #5614). [@rokups]
- Menus: Fixed gaps in closing logic which would make child-menu erroneously close when crossing
the gap between a menu item inside a window and a child-menu in a secondary viewport. (#5614)
- Nav: Fixed moving/resizing window with gamepad or keyboard when running at very high framerate.
- Nav: Pressing Space/GamepadFaceDown on a repeating button uses the same repeating rate as a mouse hold.
- Nav: Fixed an issue opening a menu with Right key from a non-menu window.
- Platform IME: [Windows] Removed call to ImmAssociateContextEx() leading to freeze on some setups.
(#2589, #5535, #5264, #4972)
- Misc: better error reporting for PopStyleColor()/PopStyleVar() + easier to recover. (#1651)
- Misc: io.Framerate moving average now converge in 60 frames instead of 120. (#5236, #4138)
- Debug Tools: Debug Log: Added 'IO' and 'Clipper' events logging.
- Debug Tools: Item Picker: Mouse button can be changed by holding Ctrl+Shift, making it easier
to use the Item Picker in e.g. menus. (#2673)
- Demo: Improved "Constrained-resizing window" example, more clearly showcase aspect-ratio. (#5627)
- Demo: Added more explicit "Center window" mode to "Overlay example". (#5618)
- Backends: GLFW: Honor GLFW_CURSOR_DISABLED by not setting mouse position. (#5625) [@scorpion-26]
- Backends: Metal: Use __bridge for ARC based systems. (#5403) [@stack]
- Backends: Metal: Add dispatch synchronization. (#5447) [@luigifcruz]
- Backends: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'. (#5603) [@dcvz]
Expand Down
69 changes: 64 additions & 5 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,8 @@ ImGuiIO::ImGuiIO()
#endif
KeyRepeatDelay = 0.275f;
KeyRepeatRate = 0.050f;
HoverDelayNormal = 0.30f;
HoverDelayShort = 0.10f;
UserData = NULL;

Fonts = NULL;
Expand Down Expand Up @@ -2907,6 +2909,11 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
void ImGui::PopStyleColor(int count)
{
ImGuiContext& g = *GImGui;
if (g.ColorStack.Size < count)
{
IM_ASSERT_USER_ERROR(g.ColorStack.Size > count, "Calling PopStyleColor() too many times: stack underflow.");
count = g.ColorStack.Size;
}
while (count > 0)
{
ImGuiColorMod& backup = g.ColorStack.back();
Expand Down Expand Up @@ -2996,6 +3003,11 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
void ImGui::PopStyleVar(int count)
{
ImGuiContext& g = *GImGui;
if (g.StyleVarStack.Size < count)
{
IM_ASSERT_USER_ERROR(g.StyleVarStack.Size > count, "Calling PopStyleVar() too many times: stack underflow.");
count = g.StyleVarStack.Size;
}
while (count > 0)
{
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
Expand Down Expand Up @@ -3643,6 +3655,24 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false;
}

// Handle hover delay
// (some ideas: https://www.nngroup.com/articles/timing-exposing-content)
float delay;
if (flags & ImGuiHoveredFlags_DelayNormal)
delay = g.IO.HoverDelayNormal;
else if (flags & ImGuiHoveredFlags_DelayShort)
delay = g.IO.HoverDelayShort;
else
delay = 0.0f;
if (delay > 0.0f)
{
ImGuiID hover_delay_id = (g.LastItemData.ID != 0) ? g.LastItemData.ID : window->GetIDFromRectangle(g.LastItemData.Rect);
if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (g.HoverDelayIdPreviousFrame != hover_delay_id))
g.HoverDelayTimer = 0.0f;
g.HoverDelayId = hover_delay_id;
return g.HoverDelayTimer >= delay;
}

return true;
}

Expand Down Expand Up @@ -4631,6 +4661,23 @@ void ImGui::NewFrame()
}
#endif

// Update hover delay for IsItemHovered() with delays and tooltips
g.HoverDelayIdPreviousFrame = g.HoverDelayId;
if (g.HoverDelayId != 0)
{
//if (g.IO.MouseDelta.x == 0.0f && g.IO.MouseDelta.y == 0.0f) // Need design/flags
g.HoverDelayTimer += g.IO.DeltaTime;
g.HoverDelayClearTimer = 0.0f;
g.HoverDelayId = 0;
}
else if (g.HoverDelayTimer > 0.0f)
{
// This gives a little bit of leeway before clearing the hover timer, allowing mouse to cross gaps
g.HoverDelayClearTimer += g.IO.DeltaTime;
if (g.HoverDelayClearTimer >= ImMax(0.20f, g.IO.DeltaTime * 2.0f)) // ~6 frames at 30 Hz + allow for low framerate
g.HoverDelayTimer = g.HoverDelayClearTimer = 0.0f; // May want a decaying timer, in which case need to clamp at max first, based on max of caller last requested timer.
}

// Drag and drop
g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr;
g.DragDropAcceptIdCurr = 0;
Expand Down Expand Up @@ -8378,6 +8425,8 @@ int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_ra
{
ImGuiContext& g = *GImGui;
const ImGuiKeyData* key_data = GetKeyData(key);
if (!key_data->Down) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitate eating mechanism (until we finish work on input ownership)
return 0;
const float t = key_data->DownDuration;
return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate);
}
Expand Down Expand Up @@ -8410,6 +8459,8 @@ bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat)
bool ImGui::IsKeyPressedEx(ImGuiKey key, ImGuiInputFlags flags)
{
const ImGuiKeyData* key_data = GetKeyData(key);
if (!key_data->Down) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitate eating mechanism (until we finish work on input ownership)
return false;
const float t = key_data->DownDuration;
if (t < 0.0f)
return false;
Expand Down Expand Up @@ -8446,6 +8497,8 @@ bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
if (!g.IO.MouseDown[button]) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitate eating mechanism (until we finish work on input ownership)
return false;
const float t = g.IO.MouseDownDuration[button];
if (t == 0.0f)
return true;
Expand Down Expand Up @@ -9925,7 +9978,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
popup_ref.PopupId = id;
popup_ref.Window = NULL;
popup_ref.SourceWindow = g.NavWindow;
popup_ref.BackupNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type).
popup_ref.OpenFrameCount = g.FrameCount;
popup_ref.OpenParentId = parent_window->IDStack.back();
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
Expand Down Expand Up @@ -10028,12 +10081,13 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);

// Trim open popup stack
ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
ImGuiWindow* popup_backup_nav_window = g.OpenPopupStack[remaining].BackupNavWindow;
g.OpenPopupStack.resize(remaining);

if (restore_focus_to_window_under_popup)
{
ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window;
if (focus_window && !focus_window->WasActive && popup_window)
{
// Fallback
Expand Down Expand Up @@ -17842,7 +17896,7 @@ void ImGui::DebugTextEncoding(const char* str)
static void MetricsHelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort))
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
Expand Down Expand Up @@ -18133,8 +18187,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
{
for (int i = 0; i < g.OpenPopupStack.Size; i++)
{
ImGuiWindow* window = g.OpenPopupStack[i].Window;
BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : "");
// As it's difficult to interact with tree nodes while popups are open, we display everything inline.
const ImGuiPopupData* popup_data = &g.OpenPopupStack[i];
ImGuiWindow* window = popup_data->Window;
BulletText("PopupID: %08x, Window: '%s' (%s%s), BackupNavWindow '%s', ParentWindow '%s'",
popup_data->PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? "Child;" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? "Menu;" : "",
popup_data->BackupNavWindow ? popup_data->BackupNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL");
}
TreePop();
}
Expand Down Expand Up @@ -18289,6 +18347,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
Text("ActiveIdUsing: NavDirMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingNavDirMask, active_id_using_key_input_count);
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
Text("HoverDelayId: 0x%08X, Timer: %.2f, ClearTimer: %.2f", g.HoverDelayId, g.HoverDelayTimer, g.HoverDelayClearTimer);
Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize);
Unindent();

Expand Down
Loading

0 comments on commit bc2002a

Please sign in to comment.