|
|
@@ -1,4 +1,4 @@
|
|
|
-// dear imgui, v1.89.6 WIP
|
|
|
+// dear imgui, v1.89.7 WIP
|
|
|
// (main code and documentation)
|
|
|
|
|
|
// Help:
|
|
|
@@ -11,7 +11,7 @@
|
|
|
// - FAQ http://dearimgui.com/faq
|
|
|
// - Homepage & latest https://github.com/ocornut/imgui
|
|
|
// - Releases & changelog https://github.com/ocornut/imgui/releases
|
|
|
-// - Gallery https://github.com/ocornut/imgui/issues/5886 (please post your screenshots/video there!)
|
|
|
+// - Gallery https://github.com/ocornut/imgui/issues/6478 (please post your screenshots/video there!)
|
|
|
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
|
|
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
|
|
// - Issues & support https://github.com/ocornut/imgui/issues
|
|
|
@@ -397,8 +397,12 @@ CODE
|
|
|
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
|
|
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
|
|
|
|
|
-
|
|
|
- - 2023/05/15 (1.86.6) - clipper: commented out obsolete redirection constructor 'ImGuiListClipper(int items_count, float items_height = -1.0f)' that was marked obsolete in 1.79. Use default constructor + clipper.Begin().
|
|
|
+ - 2023/06/20 (1.89.7) - moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal. As the fields were added in 1.89 and expected to be left unchanged by most users, or only tweaked once during app initialization, we are exceptionally accepting the breakage.
|
|
|
+ - 2023/05/30 (1.89.6) - backends: renamed "imgui_impl_sdlrenderer.cpp" to "imgui_impl_sdlrenderer2.cpp" and "imgui_impl_sdlrenderer.h" to "imgui_impl_sdlrenderer2.h". This is in prevision for the future release of SDL3.
|
|
|
+ - 2023/05/22 (1.89.6) - listbox: commented out obsolete/redirecting functions that were marked obsolete more than two years ago:
|
|
|
+ - ListBoxHeader() -> use BeginListBox() (note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for reference)
|
|
|
+ - ListBoxFooter() -> use EndListBox()
|
|
|
+ - 2023/05/15 (1.89.6) - clipper: commented out obsolete redirection constructor 'ImGuiListClipper(int items_count, float items_height = -1.0f)' that was marked obsolete in 1.79. Use default constructor + clipper.Begin().
|
|
|
- 2023/05/15 (1.89.6) - clipper: renamed ImGuiListClipper::ForceDisplayRangeByIndices() to ImGuiListClipper::IncludeRangeByIndices().
|
|
|
- 2023/03/14 (1.89.4) - commented out redirecting enums/functions names that were marked obsolete two years ago:
|
|
|
- ImGuiSliderFlags_ClampOnInput -> use ImGuiSliderFlags_AlwaysClamp
|
|
|
@@ -982,7 +986,6 @@ CODE
|
|
|
// Debug options
|
|
|
#define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Display last moving direction matches when holding CTRL
|
|
|
#define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window
|
|
|
-#define IMGUI_DEBUG_INI_SETTINGS 0 // Save additional comments in .ini file (particularly helps for Docking, but makes saving slower)
|
|
|
|
|
|
// When using CTRL+TAB (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch.
|
|
|
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
|
|
|
@@ -993,6 +996,9 @@ static const float WINDOWS_HOVER_PADDING = 4.0f; // Exten
|
|
|
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
|
|
|
static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved.
|
|
|
|
|
|
+// Tooltip offset
|
|
|
+static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale
|
|
|
+
|
|
|
//-------------------------------------------------------------------------
|
|
|
// [SECTION] FORWARD DECLARATIONS
|
|
|
//-------------------------------------------------------------------------
|
|
|
@@ -1159,6 +1165,13 @@ ImGuiStyle::ImGuiStyle()
|
|
|
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
|
|
CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
|
|
|
|
|
|
+ // Behaviors
|
|
|
+ HoverStationaryDelay = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary.
|
|
|
+ HoverDelayShort = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay.
|
|
|
+ HoverDelayNormal = 0.40f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). "
|
|
|
+ HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
|
|
|
+ HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
|
|
|
+
|
|
|
// Default theme
|
|
|
ImGui::StyleColorsDark(this);
|
|
|
}
|
|
|
@@ -1207,16 +1220,10 @@ ImGuiIO::ImGuiIO()
|
|
|
IniSavingRate = 5.0f;
|
|
|
IniFilename = "imgui.ini"; // Important: "imgui.ini" is relative to current working dir, most apps will want to lock this to an absolute path (e.g. same path as executables).
|
|
|
LogFilename = "imgui_log.txt";
|
|
|
- MouseDoubleClickTime = 0.30f;
|
|
|
- MouseDoubleClickMaxDist = 6.0f;
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
for (int i = 0; i < ImGuiKey_COUNT; i++)
|
|
|
KeyMap[i] = -1;
|
|
|
#endif
|
|
|
- KeyRepeatDelay = 0.275f;
|
|
|
- KeyRepeatRate = 0.050f;
|
|
|
- HoverDelayNormal = 0.30f;
|
|
|
- HoverDelayShort = 0.10f;
|
|
|
UserData = NULL;
|
|
|
|
|
|
Fonts = NULL;
|
|
|
@@ -1225,6 +1232,12 @@ ImGuiIO::ImGuiIO()
|
|
|
FontAllowUserScaling = false;
|
|
|
DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
|
|
|
|
|
+ MouseDoubleClickTime = 0.30f;
|
|
|
+ MouseDoubleClickMaxDist = 6.0f;
|
|
|
+ MouseDragThreshold = 6.0f;
|
|
|
+ KeyRepeatDelay = 0.275f;
|
|
|
+ KeyRepeatRate = 0.050f;
|
|
|
+
|
|
|
// Miscellaneous options
|
|
|
MouseDrawCursor = false;
|
|
|
#ifdef __APPLE__
|
|
|
@@ -1251,7 +1264,6 @@ ImGuiIO::ImGuiIO()
|
|
|
MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
|
MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
|
MouseSource = ImGuiMouseSource_Mouse;
|
|
|
- MouseDragThreshold = 6.0f;
|
|
|
for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
|
|
|
for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
|
|
|
AppAcceptingEvents = true;
|
|
|
@@ -2750,9 +2762,6 @@ static void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* clipper, int it
|
|
|
ImGuiListClipper::ImGuiListClipper()
|
|
|
{
|
|
|
memset(this, 0, sizeof(*this));
|
|
|
- Ctx = ImGui::GetCurrentContext();
|
|
|
- IM_ASSERT(Ctx != NULL);
|
|
|
- ItemsCount = -1;
|
|
|
}
|
|
|
|
|
|
ImGuiListClipper::~ImGuiListClipper()
|
|
|
@@ -2762,6 +2771,9 @@ ImGuiListClipper::~ImGuiListClipper()
|
|
|
|
|
|
void ImGuiListClipper::Begin(int items_count, float items_height)
|
|
|
{
|
|
|
+ if (Ctx == NULL)
|
|
|
+ Ctx = ImGui::GetCurrentContext();
|
|
|
+
|
|
|
ImGuiContext& g = *Ctx;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
IMGUI_DEBUG_LOG_CLIPPER("Clipper: Begin(%d,%.2f) in '%s'\n", items_count, items_height, window->Name);
|
|
|
@@ -2787,10 +2799,10 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
|
|
|
|
|
|
void ImGuiListClipper::End()
|
|
|
{
|
|
|
- ImGuiContext& g = *Ctx;
|
|
|
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
|
|
|
{
|
|
|
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
|
|
|
+ ImGuiContext& g = *Ctx;
|
|
|
IMGUI_DEBUG_LOG_CLIPPER("Clipper: End() in '%s'\n", g.CurrentWindow->Name);
|
|
|
if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
|
|
|
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
|
|
|
@@ -3509,6 +3521,7 @@ void ImGui::DestroyContext(ImGuiContext* ctx)
|
|
|
// IMPORTANT: ###xxx suffixes must be same in ALL languages
|
|
|
static const ImGuiLocEntry GLocalizationEntriesEnUS[] =
|
|
|
{
|
|
|
+ { ImGuiLocKey_VersionStr, "Dear ImGui " IMGUI_VERSION " (" IM_STRINGIFY(IMGUI_VERSION_NUM) ")" },
|
|
|
{ ImGuiLocKey_TableSizeOne, "Size column to fit###SizeOne" },
|
|
|
{ ImGuiLocKey_TableSizeAllFit, "Size all columns to fit###SizeAll" },
|
|
|
{ ImGuiLocKey_TableSizeAllDefault, "Size all columns to default###SizeAll" },
|
|
|
@@ -3922,6 +3935,16 @@ bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flag
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ if (flags & ImGuiHoveredFlags_DelayShort)
|
|
|
+ return g.Style.HoverDelayShort;
|
|
|
+ if (flags & ImGuiHoveredFlags_DelayNormal)
|
|
|
+ return g.Style.HoverDelayNormal;
|
|
|
+ return 0.0f;
|
|
|
+}
|
|
|
+
|
|
|
// This is roughly matching the behavior of internal-facing ItemHoverable()
|
|
|
// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
|
|
|
// - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
|
|
|
@@ -3929,12 +3952,17 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
+ IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0 && "Invalid flags for IsItemHovered()!");
|
|
|
+
|
|
|
if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
|
|
|
{
|
|
|
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
|
|
return false;
|
|
|
if (!IsItemFocused())
|
|
|
return false;
|
|
|
+
|
|
|
+ if (flags & ImGuiHoveredFlags_ForTooltip)
|
|
|
+ flags |= g.Style.HoverFlagsForTooltipNav;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -3942,6 +3970,10 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
|
|
ImGuiItemStatusFlags status_flags = g.LastItemData.StatusFlags;
|
|
|
if (!(status_flags & ImGuiItemStatusFlags_HoveredRect))
|
|
|
return false;
|
|
|
+
|
|
|
+ if (flags & ImGuiHoveredFlags_ForTooltip)
|
|
|
+ flags |= g.Style.HoverFlagsForTooltipMouse;
|
|
|
+
|
|
|
IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function
|
|
|
|
|
|
// Done with rectangle culling so we can perform heavier checks now
|
|
|
@@ -3976,20 +4008,22 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
|
|
|
|
|
// 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)
|
|
|
+ const float delay = CalcDelayFromHoveredFlags(flags);
|
|
|
+ if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary))
|
|
|
{
|
|
|
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;
|
|
|
+ if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (g.HoverItemDelayIdPreviousFrame != hover_delay_id))
|
|
|
+ g.HoverItemDelayTimer = 0.0f;
|
|
|
+ g.HoverItemDelayId = hover_delay_id;
|
|
|
+
|
|
|
+ // When changing hovered item we requires a bit of stationary delay before activating hover timer,
|
|
|
+ // but once unlocked on a given item we also moving.
|
|
|
+ //if (g.HoverDelayTimer >= delay && (g.HoverDelayTimer - g.IO.DeltaTime < delay || g.MouseStationaryTimer - g.IO.DeltaTime < g.Style.HoverStationaryDelay)) { IMGUI_DEBUG_LOG("HoverDelayTimer = %f/%f, MouseStationaryTimer = %f\n", g.HoverDelayTimer, delay, g.MouseStationaryTimer); }
|
|
|
+ if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverItemUnlockedStationaryId != hover_delay_id)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (g.HoverItemDelayTimer < delay)
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
@@ -4533,21 +4567,33 @@ void ImGui::NewFrame()
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ // Record when we have been stationary as this state is preserved while over same item.
|
|
|
+ // FIXME: The way this is expressed means user cannot alter HoverStationaryDelay during the frame to use varying values.
|
|
|
+ // To allow this we should store HoverItemMaxStationaryTime+ID and perform the >= check in IsItemHovered() function.
|
|
|
+ if (g.HoverItemDelayId != 0 && g.MouseStationaryTimer >= g.Style.HoverStationaryDelay)
|
|
|
+ g.HoverItemUnlockedStationaryId = g.HoverItemDelayId;
|
|
|
+ else if (g.HoverItemDelayId == 0)
|
|
|
+ g.HoverItemUnlockedStationaryId = 0;
|
|
|
+ if (g.HoveredWindow != NULL && g.MouseStationaryTimer >= g.Style.HoverStationaryDelay)
|
|
|
+ g.HoverWindowUnlockedStationaryId = g.HoveredWindow->ID;
|
|
|
+ else if (g.HoveredWindow == NULL)
|
|
|
+ g.HoverWindowUnlockedStationaryId = 0;
|
|
|
+
|
|
|
// Update hover delay for IsItemHovered() with delays and tooltips
|
|
|
- g.HoverDelayIdPreviousFrame = g.HoverDelayId;
|
|
|
- if (g.HoverDelayId != 0)
|
|
|
+ g.HoverItemDelayIdPreviousFrame = g.HoverItemDelayId;
|
|
|
+ if (g.HoverItemDelayId != 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;
|
|
|
+ g.HoverItemDelayTimer += g.IO.DeltaTime;
|
|
|
+ g.HoverItemDelayClearTimer = 0.0f;
|
|
|
+ g.HoverItemDelayId = 0;
|
|
|
}
|
|
|
- else if (g.HoverDelayTimer > 0.0f)
|
|
|
+ else if (g.HoverItemDelayTimer > 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.
|
|
|
+ // We could expose 0.25f as style.HoverClearDelay but I am not sure of the logic yet, this is particularly subtle.
|
|
|
+ g.HoverItemDelayClearTimer += g.IO.DeltaTime;
|
|
|
+ if (g.HoverItemDelayClearTimer >= ImMax(0.25f, g.IO.DeltaTime * 2.0f)) // ~7 frames at 30 Hz + allow for low framerate
|
|
|
+ g.HoverItemDelayTimer = g.HoverItemDelayClearTimer = 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
|
|
|
@@ -4915,7 +4961,7 @@ void ImGui::EndFrame()
|
|
|
ImGuiPlatformImeData* ime_data = &g.PlatformImeData;
|
|
|
if (g.IO.SetPlatformImeDataFn && memcmp(ime_data, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0)
|
|
|
{
|
|
|
- IMGUI_DEBUG_LOG_IO("Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f)\n", ime_data->WantVisible, ime_data->InputPos.x, ime_data->InputPos.y);
|
|
|
+ IMGUI_DEBUG_LOG_IO("[io] Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f)\n", ime_data->WantVisible, ime_data->InputPos.x, ime_data->InputPos.y);
|
|
|
ImGuiViewport* viewport = GetMainViewport();
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
|
if (viewport->PlatformHandleRaw == NULL && g.IO.ImeWindowHandle != NULL)
|
|
|
@@ -5321,11 +5367,14 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
|
|
|
|
|
// Process navigation-in immediately so NavInit can run on first frame
|
|
|
// Can enter a child if (A) it has navigatable items or (B) it can be scrolled.
|
|
|
+ const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
|
|
|
+ if (g.ActiveId == temp_id_for_activation)
|
|
|
+ ClearActiveID();
|
|
|
if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
|
|
|
{
|
|
|
FocusWindow(child_window);
|
|
|
NavInitWindow(child_window, false);
|
|
|
- SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
|
|
|
+ SetActiveID(temp_id_for_activation, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
|
|
|
g.ActiveIdSource = g.NavInputSource;
|
|
|
}
|
|
|
return ret;
|
|
|
@@ -5725,6 +5774,11 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
|
const float grip_hover_inner_size = IM_FLOOR(grip_draw_size * 0.75f);
|
|
|
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
|
|
|
|
|
+ ImRect clamp_rect = visibility_rect;
|
|
|
+ const bool window_move_from_title_bar = g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar);
|
|
|
+ if (window_move_from_title_bar)
|
|
|
+ clamp_rect.Min.y -= window->TitleBarHeight();
|
|
|
+
|
|
|
ImVec2 pos_target(FLT_MAX, FLT_MAX);
|
|
|
ImVec2 size_target(FLT_MAX, FLT_MAX);
|
|
|
|
|
|
@@ -5761,8 +5815,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
|
{
|
|
|
// Resize from any of the four corners
|
|
|
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
|
|
|
- ImVec2 clamp_min = ImVec2(def.CornerPosN.x == 1.0f ? visibility_rect.Min.x : -FLT_MAX, def.CornerPosN.y == 1.0f ? visibility_rect.Min.y : -FLT_MAX);
|
|
|
- ImVec2 clamp_max = ImVec2(def.CornerPosN.x == 0.0f ? visibility_rect.Max.x : +FLT_MAX, def.CornerPosN.y == 0.0f ? visibility_rect.Max.y : +FLT_MAX);
|
|
|
+ ImVec2 clamp_min = ImVec2(def.CornerPosN.x == 1.0f ? clamp_rect.Min.x : -FLT_MAX, (def.CornerPosN.y == 1.0f || (def.CornerPosN.y == 0.0f && window_move_from_title_bar)) ? clamp_rect.Min.y : -FLT_MAX);
|
|
|
+ ImVec2 clamp_max = ImVec2(def.CornerPosN.x == 0.0f ? clamp_rect.Max.x : +FLT_MAX, def.CornerPosN.y == 0.0f ? clamp_rect.Max.y : +FLT_MAX);
|
|
|
ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(def.InnerDir * grip_hover_outer_size, def.InnerDir * -grip_hover_inner_size, def.CornerPosN); // Corner of the window corresponding to our corner grip
|
|
|
corner_target = ImClamp(corner_target, clamp_min, clamp_max);
|
|
|
CalcResizePosSizeFromAnyCorner(window, corner_target, def.CornerPosN, &pos_target, &size_target);
|
|
|
@@ -5791,8 +5845,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
|
}
|
|
|
if (held)
|
|
|
{
|
|
|
- ImVec2 clamp_min(border_n == ImGuiDir_Right ? visibility_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down ? visibility_rect.Min.y : -FLT_MAX);
|
|
|
- ImVec2 clamp_max(border_n == ImGuiDir_Left ? visibility_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? visibility_rect.Max.y : +FLT_MAX);
|
|
|
+ ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX);
|
|
|
+ ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX);
|
|
|
ImVec2 border_target = window->Pos;
|
|
|
border_target[axis] = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING;
|
|
|
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
|
|
@@ -5819,7 +5873,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
|
const float NAV_RESIZE_SPEED = 600.0f;
|
|
|
const float resize_step = NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y);
|
|
|
g.NavWindowingAccumDeltaSize += nav_resize_dir * resize_step;
|
|
|
- g.NavWindowingAccumDeltaSize = ImMax(g.NavWindowingAccumDeltaSize, visibility_rect.Min - window->Pos - window->Size); // We need Pos+Size >= visibility_rect.Min, so Size >= visibility_rect.Min - Pos, so size_delta >= visibility_rect.Min - window->Pos - window->Size
|
|
|
+ g.NavWindowingAccumDeltaSize = ImMax(g.NavWindowingAccumDeltaSize, clamp_rect.Min - window->Pos - window->Size); // We need Pos+Size >= clmap_rect.Min, so Size >= clmap_rect.Min - Pos, so size_delta >= clmap_rect.Min - window->Pos - window->Size
|
|
|
g.NavWindowingToggleLayer = false;
|
|
|
g.NavDisableMouseHover = true;
|
|
|
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
|
|
|
@@ -6080,12 +6134,13 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags
|
|
|
// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing)
|
|
|
// should be positioned behind that modal window, unless the window was created inside the modal begin-stack.
|
|
|
// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent.
|
|
|
-// - Window // FindBlockingModal() returns Modal1
|
|
|
-// - Window // .. returns Modal1
|
|
|
+// - WindowA // FindBlockingModal() returns Modal1
|
|
|
+// - WindowB // .. returns Modal1
|
|
|
// - Modal1 // .. returns Modal2
|
|
|
-// - Window // .. returns Modal2
|
|
|
-// - Window // .. returns Modal2
|
|
|
+// - WindowC // .. returns Modal2
|
|
|
+// - WindowD // .. returns Modal2
|
|
|
// - Modal2 // .. returns Modal2
|
|
|
+// - WindowE // .. returns NULL
|
|
|
// Notes:
|
|
|
// - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL.
|
|
|
// Only difference is here we check for ->Active/WasActive but it may be unecessary.
|
|
|
@@ -6096,7 +6151,7 @@ ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
|
|
|
return NULL;
|
|
|
|
|
|
// Find a modal that has common parent with specified window. Specified window should be positioned behind that modal.
|
|
|
- for (int i = g.OpenPopupStack.Size - 1; i >= 0; i--)
|
|
|
+ for (int i = 0; i < g.OpenPopupStack.Size; i++)
|
|
|
{
|
|
|
ImGuiWindow* popup_window = g.OpenPopupStack.Data[i].Window;
|
|
|
if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal))
|
|
|
@@ -6105,11 +6160,9 @@ ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
|
|
|
continue;
|
|
|
if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click.
|
|
|
return popup_window;
|
|
|
- if (IsWindowWithinBeginStackOf(window, popup_window)) // Window is rendered over last modal, no render order change needed.
|
|
|
- break;
|
|
|
- for (ImGuiWindow* parent = popup_window->ParentWindowInBeginStack->RootWindow; parent != NULL; parent = parent->ParentWindowInBeginStack->RootWindow)
|
|
|
- if (IsWindowWithinBeginStackOf(window, parent))
|
|
|
- return popup_window; // Place window above its begin stack parent.
|
|
|
+ if (IsWindowWithinBeginStackOf(window, popup_window)) // Window may be over modal
|
|
|
+ continue;
|
|
|
+ return popup_window; // Place window right below first block modal
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
@@ -7203,7 +7256,8 @@ bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_b
|
|
|
|
|
|
bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
|
|
|
{
|
|
|
- IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled)) == 0); // Flags not supported by this function
|
|
|
+ IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsWindowHovered) == 0 && "Invalid flags for IsWindowHovered()!");
|
|
|
+
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* ref_window = g.HoveredWindow;
|
|
|
ImGuiWindow* cur_window = g.CurrentWindow;
|
|
|
@@ -7231,6 +7285,17 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
|
|
|
if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
|
|
|
if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != ref_window->MoveId)
|
|
|
return false;
|
|
|
+
|
|
|
+ // When changing hovered window we requires a bit of stationary delay before activating hover timer.
|
|
|
+ // FIXME: We don't support delay other than stationary one for now, other delay would need a way
|
|
|
+ // to fullfill the possibility that multiple IsWindowHovered() with varying flag could return true
|
|
|
+ // for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache.
|
|
|
+ // We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow.
|
|
|
+ if (flags & ImGuiHoveredFlags_ForTooltip)
|
|
|
+ flags |= g.Style.HoverFlagsForTooltipMouse;
|
|
|
+ if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverWindowUnlockedStationaryId != ref_window->ID)
|
|
|
+ return false;
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -7521,13 +7586,6 @@ void ImGui::SetWindowFontScale(float scale)
|
|
|
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
|
|
|
}
|
|
|
|
|
|
-void ImGui::ActivateItem(ImGuiID id)
|
|
|
-{
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
- g.NavNextActivateId = id;
|
|
|
- g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
|
|
-}
|
|
|
-
|
|
|
void ImGui::PushFocusScope(ImGuiID id)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
@@ -7543,13 +7601,40 @@ void ImGui::PopFocusScope()
|
|
|
g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back() : 0;
|
|
|
}
|
|
|
|
|
|
+// Focus = move navigation cursor, set scrolling, set focus window.
|
|
|
+void ImGui::FocusItem()
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+ IMGUI_DEBUG_LOG_FOCUS("FocusItem(0x%08x) in window \"%s\"\n", g.LastItemData.ID, window->Name);
|
|
|
+ if (g.DragDropActive || g.MovingWindow != NULL) // FIXME: Opt-in flags for this?
|
|
|
+ {
|
|
|
+ IMGUI_DEBUG_LOG_FOCUS("FocusItem() ignored while DragDropActive!\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSelect;
|
|
|
+ ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
|
|
+ SetNavWindow(window);
|
|
|
+ NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags);
|
|
|
+ NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal);
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui::ActivateItemByID(ImGuiID id)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ g.NavNextActivateId = id;
|
|
|
+ g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
|
|
+}
|
|
|
+
|
|
|
// Note: this will likely be called ActivateItem() once we rework our Focus/Activation system!
|
|
|
+// But ActivateItem() should function without altering scroll/focus?
|
|
|
void ImGui::SetKeyboardFocusHere(int offset)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
IM_ASSERT(offset >= -1); // -1 is allowed but not below
|
|
|
- IMGUI_DEBUG_LOG_ACTIVEID("SetKeyboardFocusHere(%d) in window \"%s\"\n", offset, window->Name);
|
|
|
+ IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere(%d) in window \"%s\"\n", offset, window->Name);
|
|
|
|
|
|
// It makes sense in the vast majority of cases to never interrupt a drag and drop.
|
|
|
// When we refactor this function into ActivateItem() we may want to make this an option.
|
|
|
@@ -7557,14 +7642,15 @@ void ImGui::SetKeyboardFocusHere(int offset)
|
|
|
// is also automatically dropped in the event g.ActiveId is stolen.
|
|
|
if (g.DragDropActive || g.MovingWindow != NULL)
|
|
|
{
|
|
|
- IMGUI_DEBUG_LOG_ACTIVEID("SetKeyboardFocusHere() ignored while DragDropActive!\n");
|
|
|
+ IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere() ignored while DragDropActive!\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
SetNavWindow(window);
|
|
|
|
|
|
+ ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi;
|
|
|
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
|
|
- NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
|
|
+ NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
|
|
if (offset == -1)
|
|
|
{
|
|
|
NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal);
|
|
|
@@ -7582,12 +7668,11 @@ void ImGui::SetItemDefaultFocus()
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
if (!window->Appearing)
|
|
|
return;
|
|
|
- if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResultId == 0) || g.NavLayer != window->DC.NavLayerCurrent)
|
|
|
+ if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResult.ID == 0) || g.NavLayer != window->DC.NavLayerCurrent)
|
|
|
return;
|
|
|
|
|
|
g.NavInitRequest = false;
|
|
|
- g.NavInitResultId = g.LastItemData.ID;
|
|
|
- g.NavInitResultRectRel = WindowRectAbsToRel(window, g.LastItemData.Rect);
|
|
|
+ NavApplyItemToResult(&g.NavInitResult);
|
|
|
NavUpdateAnyRequestFlag();
|
|
|
|
|
|
// Scroll could be done in NavInitRequestApplyResult() via an opt-in flag (we however don't want regular init requests to scroll)
|
|
|
@@ -7828,7 +7913,7 @@ const char* ImGui::GetKeyName(ImGuiKey key)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
- IM_ASSERT((IsNamedKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code.");
|
|
|
+ IM_ASSERT((IsNamedKeyOrModKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code.");
|
|
|
#else
|
|
|
if (IsLegacyKey(key))
|
|
|
{
|
|
|
@@ -8496,6 +8581,15 @@ static void ImGui::UpdateMouseInputs()
|
|
|
else
|
|
|
io.MouseDelta = ImVec2(0.0f, 0.0f);
|
|
|
|
|
|
+ // Update stationary timer. Only reset on 2 successive moving frames.
|
|
|
+ // FIXME: May need to expose threshold or treat touch inputs differently.
|
|
|
+ const float mouse_stationary_threshold = (io.MouseSource == ImGuiMouseSource_Mouse) ? 2.0f : 3.0f; // Slightly higher threshold for ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen, may need rework.
|
|
|
+ g.MouseMovingFrames = (ImLengthSqr(io.MouseDelta) >= mouse_stationary_threshold * mouse_stationary_threshold) ? (g.MouseMovingFrames + 1) : 0;
|
|
|
+ if (g.MouseMovingFrames == 0)
|
|
|
+ g.MouseStationaryTimer += io.DeltaTime;
|
|
|
+ else if (g.MouseMovingFrames > 1)
|
|
|
+ g.MouseStationaryTimer = 0.0f;
|
|
|
+
|
|
|
// If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
|
|
|
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)
|
|
|
g.NavDisableMouseHover = false;
|
|
|
@@ -8551,7 +8645,7 @@ static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
|
|
g.WheelingWindowReleaseTimer = 0.0f;
|
|
|
if (g.WheelingWindow == window)
|
|
|
return;
|
|
|
- IMGUI_DEBUG_LOG_IO("LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL");
|
|
|
+ IMGUI_DEBUG_LOG_IO("[io] LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL");
|
|
|
g.WheelingWindow = window;
|
|
|
g.WheelingWindowRefMousePos = g.IO.MousePos;
|
|
|
if (window == NULL)
|
|
|
@@ -8715,12 +8809,12 @@ static const char* GetMouseSourceName(ImGuiMouseSource source)
|
|
|
static void DebugPrintInputEvent(const char* prefix, const ImGuiInputEvent* e)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("%s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("%s: MousePos (%.1f, %.1f) (%s)\n", prefix, e->MousePos.PosX, e->MousePos.PosY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
- if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("%s: MouseButton %d %s (%s)\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up", GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
- if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("%s: MouseWheel (%.3f, %.3f) (%s)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
- if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG_IO("%s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; }
|
|
|
- if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG_IO("%s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; }
|
|
|
- if (e->Type == ImGuiInputEventType_Focus) { IMGUI_DEBUG_LOG_IO("%s: AppFocused %d\n", prefix, e->AppFocused.Focused); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("[io] %s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("[io] %s: MousePos (%.1f, %.1f) (%s)\n", prefix, e->MousePos.PosX, e->MousePos.PosY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("[io] %s: MouseButton %d %s (%s)\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up", GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("[io] %s: MouseWheel (%.3f, %.3f) (%s)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG_IO("[io] %s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG_IO("[io] %s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; }
|
|
|
+ if (e->Type == ImGuiInputEventType_Focus) { IMGUI_DEBUG_LOG_IO("[io] %s: AppFocused %d\n", prefix, e->AppFocused.Focused); return; }
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
@@ -10016,26 +10110,35 @@ bool ImGui::BeginTooltip()
|
|
|
return BeginTooltipEx(ImGuiTooltipFlags_None, ImGuiWindowFlags_None);
|
|
|
}
|
|
|
|
|
|
+bool ImGui::BeginItemTooltip()
|
|
|
+{
|
|
|
+ if (!IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
|
|
+ return false;
|
|
|
+ return BeginTooltipEx(ImGuiTooltipFlags_None, ImGuiWindowFlags_None);
|
|
|
+}
|
|
|
+
|
|
|
bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
if (g.DragDropWithinSource || g.DragDropWithinTarget)
|
|
|
{
|
|
|
- // The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor)
|
|
|
- // In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor.
|
|
|
- // Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do.
|
|
|
+ // Drag and Drop tooltips are positioning differently than other tooltips:
|
|
|
+ // - offset visibility to increase visibility around mouse.
|
|
|
+ // - never clamp within outer viewport boundary.
|
|
|
+ // We call SetNextWindowPos() to enforce position and disable clamping.
|
|
|
+ // See FindBestWindowPosForPopup() for positionning logic of other tooltips (not drag and drop ones).
|
|
|
//ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
|
|
|
- ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale);
|
|
|
+ ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET * g.Style.MouseCursorScale;
|
|
|
SetNextWindowPos(tooltip_pos);
|
|
|
SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
|
|
|
//PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
|
|
|
- tooltip_flags |= ImGuiTooltipFlags_OverridePreviousTooltip;
|
|
|
+ tooltip_flags |= ImGuiTooltipFlags_OverridePrevious;
|
|
|
}
|
|
|
|
|
|
char window_name[16];
|
|
|
ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount);
|
|
|
- if (tooltip_flags & ImGuiTooltipFlags_OverridePreviousTooltip)
|
|
|
+ if (tooltip_flags & ImGuiTooltipFlags_OverridePrevious)
|
|
|
if (ImGuiWindow* window = FindWindowByName(window_name))
|
|
|
if (window->Active)
|
|
|
{
|
|
|
@@ -10059,22 +10162,40 @@ void ImGui::EndTooltip()
|
|
|
End();
|
|
|
}
|
|
|
|
|
|
+void ImGui::SetTooltip(const char* fmt, ...)
|
|
|
+{
|
|
|
+ va_list args;
|
|
|
+ va_start(args, fmt);
|
|
|
+ SetTooltipV(fmt, args);
|
|
|
+ va_end(args);
|
|
|
+}
|
|
|
+
|
|
|
void ImGui::SetTooltipV(const char* fmt, va_list args)
|
|
|
{
|
|
|
- if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None))
|
|
|
+ if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
|
|
|
return;
|
|
|
TextV(fmt, args);
|
|
|
EndTooltip();
|
|
|
}
|
|
|
|
|
|
-void ImGui::SetTooltip(const char* fmt, ...)
|
|
|
+// Shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav'.
|
|
|
+// Defaults to == ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort when using the mouse.
|
|
|
+void ImGui::SetItemTooltip(const char* fmt, ...)
|
|
|
{
|
|
|
va_list args;
|
|
|
va_start(args, fmt);
|
|
|
- SetTooltipV(fmt, args);
|
|
|
+ if (IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
|
|
+ SetTooltipV(fmt, args);
|
|
|
va_end(args);
|
|
|
}
|
|
|
|
|
|
+void ImGui::SetItemTooltipV(const char* fmt, va_list args)
|
|
|
+{
|
|
|
+ if (IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
|
|
+ SetTooltipV(fmt, args);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] POPUPS
|
|
|
//-----------------------------------------------------------------------------
|
|
|
@@ -10597,15 +10718,20 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
|
|
}
|
|
|
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
|
|
{
|
|
|
- // Position tooltip (always follows mouse)
|
|
|
- float sc = g.Style.MouseCursorScale;
|
|
|
- ImVec2 ref_pos = NavCalcPreferredRefPos();
|
|
|
+ // Position tooltip (always follows mouse + clamp within outer boundaries)
|
|
|
+ // Note that drag and drop tooltips are NOT using this path: BeginTooltipEx() manually sets their position.
|
|
|
+ // In theory we could handle both cases in same location, but requires a bit of shuffling as drag and drop tooltips are calling SetWindowPos() leading to 'window_pos_set_by_api' being set in Begin()
|
|
|
+ IM_ASSERT(g.CurrentWindow == window);
|
|
|
+ const float scale = g.Style.MouseCursorScale;
|
|
|
+ const ImVec2 ref_pos = NavCalcPreferredRefPos();
|
|
|
+ const ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET * scale;
|
|
|
ImRect r_avoid;
|
|
|
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
|
|
|
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
|
|
|
else
|
|
|
- r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
|
|
|
- return FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip);
|
|
|
+ r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
|
|
|
+ //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255, 0, 255, 255));
|
|
|
+ return FindBestWindowPosForPopupEx(tooltip_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip);
|
|
|
}
|
|
|
IM_ASSERT(0);
|
|
|
return window->Pos;
|
|
|
@@ -10878,10 +11004,9 @@ static void ImGui::NavProcessItem()
|
|
|
{
|
|
|
// Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback
|
|
|
const bool candidate_for_nav_default_focus = (item_flags & ImGuiItemFlags_NoNavDefaultFocus) == 0;
|
|
|
- if (candidate_for_nav_default_focus || g.NavInitResultId == 0)
|
|
|
+ if (candidate_for_nav_default_focus || g.NavInitResult.ID == 0)
|
|
|
{
|
|
|
- g.NavInitResultId = id;
|
|
|
- g.NavInitResultRectRel = WindowRectAbsToRel(window, nav_bb);
|
|
|
+ NavApplyItemToResult(&g.NavInitResult);
|
|
|
}
|
|
|
if (candidate_for_nav_default_focus)
|
|
|
{
|
|
|
@@ -11139,8 +11264,7 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
|
|
|
SetNavID(0, g.NavLayer, window->NavRootFocusScopeId, ImRect());
|
|
|
g.NavInitRequest = true;
|
|
|
g.NavInitRequestFromMove = false;
|
|
|
- g.NavInitResultId = 0;
|
|
|
- g.NavInitResultRectRel = ImRect();
|
|
|
+ g.NavInitResult.ID = 0;
|
|
|
NavUpdateAnyRequestFlag();
|
|
|
}
|
|
|
else
|
|
|
@@ -11225,12 +11349,12 @@ static void ImGui::NavUpdate()
|
|
|
g.NavInputSource = ImGuiInputSource_Keyboard;
|
|
|
|
|
|
// Process navigation init request (select first/default focus)
|
|
|
- if (g.NavInitResultId != 0)
|
|
|
+ g.NavJustMovedToId = 0;
|
|
|
+ if (g.NavInitResult.ID != 0)
|
|
|
NavInitRequestApplyResult();
|
|
|
g.NavInitRequest = false;
|
|
|
g.NavInitRequestFromMove = false;
|
|
|
- g.NavInitResultId = 0;
|
|
|
- g.NavJustMovedToId = 0;
|
|
|
+ g.NavInitResult.ID = 0;
|
|
|
|
|
|
// Process navigation move request
|
|
|
if (g.NavMoveSubmitted)
|
|
|
@@ -11370,10 +11494,18 @@ void ImGui::NavInitRequestApplyResult()
|
|
|
if (!g.NavWindow)
|
|
|
return;
|
|
|
|
|
|
+ ImGuiNavItemData* result = &g.NavInitResult;
|
|
|
+ if (g.NavId != result->ID)
|
|
|
+ {
|
|
|
+ g.NavJustMovedToId = result->ID;
|
|
|
+ g.NavJustMovedToFocusScopeId = result->FocusScopeId;
|
|
|
+ g.NavJustMovedToKeyMods = 0;
|
|
|
+ }
|
|
|
+
|
|
|
// Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called)
|
|
|
// FIXME-NAV: On _NavFlattened windows, g.NavWindow will only be updated during subsequent frame. Not a problem currently.
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: ApplyResult: NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name);
|
|
|
- SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: ApplyResult: NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
|
|
|
+ SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
|
|
|
g.NavIdIsAlive = true; // Mark as alive from previous frame as we got a result
|
|
|
if (g.NavInitRequestFromMove)
|
|
|
NavRestoreHighlightAfterMove();
|
|
|
@@ -11472,7 +11604,7 @@ void ImGui::NavUpdateCreateMoveRequest()
|
|
|
{
|
|
|
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", window ? window->Name : "<NULL>", g.NavLayer);
|
|
|
g.NavInitRequest = g.NavInitRequestFromMove = true;
|
|
|
- g.NavInitResultId = 0;
|
|
|
+ g.NavInitResult.ID = 0;
|
|
|
g.NavDisableHighlight = false;
|
|
|
}
|
|
|
|
|
|
@@ -11541,9 +11673,10 @@ void ImGui::NavUpdateCreateTabbingRequest()
|
|
|
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1;
|
|
|
else
|
|
|
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1;
|
|
|
+ ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate;
|
|
|
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
|
|
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
|
|
|
- NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
|
|
+ NavMoveRequestSubmit(ImGuiDir_None, clip_dir, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
|
|
g.NavTabbingCounter = -1;
|
|
|
}
|
|
|
|
|
|
@@ -11569,8 +11702,8 @@ void ImGui::NavMoveRequestApplyResult()
|
|
|
if (result == NULL)
|
|
|
{
|
|
|
if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
|
|
|
- g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
|
|
|
- if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
|
|
|
+ g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight;
|
|
|
+ if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0)
|
|
|
NavRestoreHighlightAfterMove();
|
|
|
NavClearPreferredPosForAxis(axis); // On a failed move, clear preferred pos for this axis.
|
|
|
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n");
|
|
|
@@ -11609,7 +11742,7 @@ void ImGui::NavMoveRequestApplyResult()
|
|
|
}
|
|
|
if (g.ActiveId != result->ID)
|
|
|
ClearActiveID();
|
|
|
- if (g.NavId != result->ID)
|
|
|
+ if (g.NavId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSelect) == 0)
|
|
|
{
|
|
|
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
|
|
|
g.NavJustMovedToId = result->ID;
|
|
|
@@ -11630,23 +11763,22 @@ void ImGui::NavMoveRequestApplyResult()
|
|
|
g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer] = preferred_scoring_pos_rel;
|
|
|
}
|
|
|
|
|
|
- // Tabbing: Activates Inputable or Focus non-Inputable
|
|
|
- if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable))
|
|
|
- {
|
|
|
- g.NavNextActivateId = result->ID;
|
|
|
- g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
|
|
|
- g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
|
|
|
- }
|
|
|
+ // Tabbing: Activates Inputable, otherwise only Focus
|
|
|
+ if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0)
|
|
|
+ g.NavMoveFlags &= ~ImGuiNavMoveFlags_Activate;
|
|
|
|
|
|
// Activate
|
|
|
if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate)
|
|
|
{
|
|
|
g.NavNextActivateId = result->ID;
|
|
|
g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
|
|
+ g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight;
|
|
|
+ if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
|
|
|
+ g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
|
|
|
}
|
|
|
|
|
|
// Enable nav highlight
|
|
|
- if ((g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
|
|
|
+ if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0)
|
|
|
NavRestoreHighlightAfterMove();
|
|
|
}
|
|
|
|
|
|
@@ -12912,12 +13044,13 @@ ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
-#if !IMGUI_DEBUG_INI_SETTINGS
|
|
|
- // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
|
|
- // Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
|
|
|
- if (const char* p = strstr(name, "###"))
|
|
|
- name = p;
|
|
|
-#endif
|
|
|
+ if (g.IO.ConfigDebugIniSettings == false)
|
|
|
+ {
|
|
|
+ // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
|
|
+ // Preserve the full string when ConfigDebugVerboseIniSettings is set to make .ini inspection easier.
|
|
|
+ if (const char* p = strstr(name, "###"))
|
|
|
+ name = p;
|
|
|
+ }
|
|
|
const size_t name_len = strlen(name);
|
|
|
|
|
|
// Allocate chunk
|
|
|
@@ -13400,7 +13533,7 @@ void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list)
|
|
|
draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding);
|
|
|
ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y);
|
|
|
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
|
|
|
- if (ImGui::IsKeyDown(key_data->Key))
|
|
|
+ if (IsKeyDown(key_data->Key))
|
|
|
draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding);
|
|
|
}
|
|
|
draw_list->PopClipRect();
|
|
|
@@ -13446,7 +13579,7 @@ void ImGui::DebugTextEncoding(const char* str)
|
|
|
static void MetricsHelpMarker(const char* desc)
|
|
|
{
|
|
|
ImGui::TextDisabled("(?)");
|
|
|
- if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort) && ImGui::BeginTooltip())
|
|
|
+ if (ImGui::BeginItemTooltip())
|
|
|
{
|
|
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
|
|
ImGui::TextUnformatted(desc);
|
|
|
@@ -13541,7 +13674,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
else if (rect_type == WRT_InnerRect) { return window->InnerRect; }
|
|
|
else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; }
|
|
|
else if (rect_type == WRT_WorkRect) { return window->WorkRect; }
|
|
|
- else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
|
|
|
+ else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
|
|
|
else if (rect_type == WRT_ContentIdeal) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSizeIdeal); }
|
|
|
else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; }
|
|
|
IM_ASSERT(0);
|
|
|
@@ -13778,11 +13911,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
Text("\"%s\"", g.IO.IniFilename);
|
|
|
else
|
|
|
TextUnformatted("<NULL>");
|
|
|
+ Checkbox("io.ConfigDebugIniSettings", &io.ConfigDebugIniSettings);
|
|
|
Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer);
|
|
|
if (TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size))
|
|
|
{
|
|
|
for (int n = 0; n < g.SettingsHandlers.Size; n++)
|
|
|
- BulletText("%s", g.SettingsHandlers[n].TypeName);
|
|
|
+ BulletText("\"%s\"", g.SettingsHandlers[n].TypeName);
|
|
|
TreePop();
|
|
|
}
|
|
|
if (TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size()))
|
|
|
@@ -13845,6 +13979,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (IsMouseClicked(i)) { SameLine(); Text("b%d (%d)", i, io.MouseClickedCount[i]); }
|
|
|
Text("Mouse released:"); for (int i = 0; i < count; i++) if (IsMouseReleased(i)) { SameLine(); Text("b%d", i); }
|
|
|
Text("Mouse wheel: %.1f", io.MouseWheel);
|
|
|
+ Text("MouseStationaryTimer: %.2f", g.MouseStationaryTimer);
|
|
|
Text("Mouse source: %s", GetMouseSourceName(io.MouseSource));
|
|
|
Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused
|
|
|
Unindent();
|
|
|
@@ -13920,7 +14055,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
|
Text("ActiveIdUsing: AllKeyboardKeys: %d, NavDirMask: %X", g.ActiveIdUsingAllKeyboardKeys, g.ActiveIdUsingNavDirMask);
|
|
|
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("HoverItemDelayId: 0x%08X, Timer: %.2f, ClearTimer: %.2f", g.HoverItemDelayId, g.HoverItemDelayTimer, g.HoverItemDelayClearTimer);
|
|
|
Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize);
|
|
|
DebugLocateItemOnHover(g.DragDropPayload.SourceId);
|
|
|
Unindent();
|
|
|
@@ -14261,13 +14396,11 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label)
|
|
|
char* p = buf;
|
|
|
const char* buf_end = buf + IM_ARRAYSIZE(buf);
|
|
|
const bool is_active = (tab_bar->PrevFrameVisible >= GetFrameCount() - 2);
|
|
|
- p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*");
|
|
|
- p += ImFormatString(p, buf_end - p, " { ");
|
|
|
+ p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s {", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*");
|
|
|
for (int tab_n = 0; tab_n < ImMin(tab_bar->Tabs.Size, 3); tab_n++)
|
|
|
{
|
|
|
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
|
|
|
- p += ImFormatString(p, buf_end - p, "%s'%s'",
|
|
|
- tab_n > 0 ? ", " : "", TabBarGetTabName(tab_bar, tab));
|
|
|
+ p += ImFormatString(p, buf_end - p, "%s'%s'", tab_n > 0 ? ", " : "", TabBarGetTabName(tab_bar, tab));
|
|
|
}
|
|
|
p += ImFormatString(p, buf_end - p, (tab_bar->Tabs.Size > 3) ? " ... }" : " } ");
|
|
|
if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); }
|