mirror of https://github.com/ocornut/imgui
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_glfw.cpp # docs/CHANGELOG.txt # imgui.cpp
This commit is contained in:
commit
1450d23b60
|
@ -22,6 +22,7 @@
|
|||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
|
||||
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
||||
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
||||
|
@ -937,7 +938,10 @@ void ImGui_ImplGlfw_NewFrame()
|
|||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||
double current_time = glfwGetTime();
|
||||
if (current_time <= bd->Time)
|
||||
current_time = bd->Time + 0.00001f;
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
|
|
|
@ -289,7 +289,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
|
||||
// Query for GL version (e.g. 320 for GL 3.2)
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GLES 2
|
||||
bd->GlVersion = 200;
|
||||
bd->GlProfileIsES2 = true;
|
||||
#else
|
||||
// Desktop or GLES 3
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
|
@ -306,6 +311,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
|
||||
#endif
|
||||
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
bd->GlProfileIsES3 = true;
|
||||
#endif
|
||||
|
||||
bd->UseBufferSubData = false;
|
||||
/*
|
||||
// Query vendor to enable glBufferSubData kludge
|
||||
|
@ -315,16 +324,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||
bd->UseBufferSubData = true;
|
||||
#endif
|
||||
*/
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
bd->GlVersion = 200; // GLES 2
|
||||
bd->GlProfileIsES2 = true;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
bd->GlVersion = 200; // Don't raise version as it is intended as a desktop version check for now.
|
||||
bd->GlProfileIsES3 = true;
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
|
|
|
@ -101,12 +101,53 @@ Other changes:
|
|||
VERSION 1.89.7 WIP (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- 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 initialisation, we are exceptionally accepting the breakage.
|
||||
Majority of users should not even notice.
|
||||
|
||||
Other changes:
|
||||
|
||||
- Tooltips/IsItemHovered() related changes:
|
||||
- IsItemHovered: Added ImGuiHoveredFlags_Stationary to require mouse being
|
||||
stationary when hovering a new item. Added style.HoverStationaryDelay (~0.15 sec).
|
||||
Once the mouse has been stationary once the state is preserved for same item. (#1485)
|
||||
- IsItemHovered: Added ImGuiHoveredFlags_ForTooltip as a shortcut for pulling flags
|
||||
from style.HoverFlagsForTooltipMouse or style.HoverFlagsForTooltipNav. (#1485)
|
||||
- style.HoverFlagsForTooltipMouse defaults to ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort
|
||||
- style.HoverFlagsForTooltipNav defaults to ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal
|
||||
- Tooltips: Added SetItemTooltip() and BeginItemTooltip() functions.
|
||||
They are shortcuts for the common idiom of using IsItemHovered().
|
||||
- SetItemTooltip("Hello") == if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { SetTooltip("Hello"); }
|
||||
- BeginItemTooltip() == IsItemHovered(ImGuiHoveredFlags_Tooltip) && BeginTooltip()
|
||||
The newly added ImGuiHoveredFlags_Tooltip is meant to standardize mouse hovering
|
||||
delays and rules for a whole application.
|
||||
The previously common idiom of using 'if (IsItemHovered()) { SetTooltip(...); }' won't
|
||||
use delay or stationary test.
|
||||
- Tooltips: Tweak default offset for non-drag and drop tooltips so underlying items
|
||||
isn't covered as much. (Match offset for drag and drop tooltips)
|
||||
- IsItemHovered: Tweaked default value of style.HoverDelayNormal from 0.30 to 0.40,
|
||||
Tweaked default value of style.HoverDelayShort from 0.10 to 0.15. (#1485)
|
||||
- IsWindowHovered: Added support for ImGuiHoveredFlags_Stationary.
|
||||
- IsWindowHovered, IsItemHovered: Assert when passed any unsupported flags.
|
||||
- Tables: Fixed a regression in 1.89.6 leading to the first column of tables with either
|
||||
ScrollX or ScrollY flags from being impossible to resize. (#6503)
|
||||
- Clipper: Rework inner logic to allow functioning with a zero-clear constructor.
|
||||
This is order to facilitate usage for language bindings (e.g cimgui or dear_binding)
|
||||
where user may not be callinga constructor manually. (#5856)
|
||||
- Modals: In the case of nested modal, made sure that focused or appearing windows are
|
||||
moved below the lowest blocking modal (rather than the highest one). (#4317)
|
||||
- Debug Tools: Added 'io.ConfigDebugIniSettings' option to save .ini data with extra
|
||||
comments. Currently mainly for inspecting Docking .ini data, but makes saving slower.
|
||||
- Demo: Added more developed "Widgets->Tooltips" section. (#1485)
|
||||
- Backends: OpenGL3: Fixed support for glBindSampler() backup/restore on ES3. (#6375, #6508) [@jsm174]
|
||||
- Backends: GLFW: Accept glfwGetTime() not returning a monotonically increasing value.
|
||||
This seems to happens on some Windows setup when peripherals disconnect, and is likely
|
||||
to also happen on browser+Emscripten. Matches similar 1.89.4 fix in SDL backend. (#6491)
|
||||
- Examples: Win32+OpenGL3: Changed DefWindowProc() to DefWindowProcW() to match other examples
|
||||
and support the example app being compiled without UNICODE. (#6516, #5725, #5961, #5975) [@yenixing]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
|
@ -662,7 +703,7 @@ Other Changes:
|
|||
- ColorEdit3: fixed id collision leading to an assertion. (#5707)
|
||||
- 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)
|
||||
io.HoverDelayNormal (default to 0.30f) and io.HoverDelayShort (default to 0.10f). (#1485)
|
||||
- IsItemHovered: Added ImGuiHoveredFlags_NoSharedDelay to disable sharing delays between items,
|
||||
so moving from one item to a nearby one will requires delay to elapse again. (#1485)
|
||||
- Tables: activating an ID (e.g. clicking button inside) column doesn't prevent columns
|
||||
|
|
|
@ -300,5 +300,5 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
return ::DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
|
230
imgui.cpp
230
imgui.cpp
|
@ -405,6 +405,7 @@ CODE
|
|||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
|
||||
- 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)
|
||||
|
@ -1001,6 +1002,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
|
||||
|
||||
// Docking
|
||||
static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f; // For use with io.ConfigDockingTransparentPayload. Apply to Viewport _or_ WindowBg in host viewport.
|
||||
static const float DOCKING_SPLITTER_SIZE = 2.0f;
|
||||
|
@ -1183,6 +1187,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);
|
||||
}
|
||||
|
@ -1231,16 +1242,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;
|
||||
|
@ -1278,6 +1283,13 @@ ImGuiIO::ImGuiIO()
|
|||
ConfigDebugBeginReturnValueOnce = false;
|
||||
ConfigDebugBeginReturnValueLoop = false;
|
||||
|
||||
// Inputs Behaviors
|
||||
MouseDoubleClickTime = 0.30f;
|
||||
MouseDoubleClickMaxDist = 6.0f;
|
||||
MouseDragThreshold = 6.0f;
|
||||
KeyRepeatDelay = 0.275f;
|
||||
KeyRepeatRate = 0.050f;
|
||||
|
||||
// Platform Functions
|
||||
// Note: Initialize() will setup default clipboard/ime handlers.
|
||||
BackendPlatformName = BackendRendererName = NULL;
|
||||
|
@ -1287,7 +1299,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;
|
||||
|
@ -2807,9 +2818,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()
|
||||
|
@ -2819,6 +2827,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);
|
||||
|
@ -2844,10 +2855,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);
|
||||
|
@ -3573,6 +3584,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" },
|
||||
|
@ -4013,6 +4025,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
|
||||
|
@ -4020,12 +4042,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
|
||||
{
|
||||
|
@ -4033,6 +4060,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 | ImGuiHoveredFlags_DockHierarchy)) == 0); // Flags not supported by this function
|
||||
|
||||
// Done with rectangle culling so we can perform heavier checks now
|
||||
|
@ -4069,20 +4100,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;
|
||||
|
@ -4716,21 +4749,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
|
||||
|
@ -6452,12 +6497,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.
|
||||
|
@ -6468,7 +6514,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))
|
||||
|
@ -6477,11 +6523,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;
|
||||
}
|
||||
|
@ -7760,7 +7804,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;
|
||||
|
@ -7789,6 +7834,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;
|
||||
}
|
||||
|
||||
|
@ -9127,6 +9183,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;
|
||||
|
@ -10695,26 +10760,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)
|
||||
{
|
||||
|
@ -10738,14 +10812,6 @@ void ImGui::EndTooltip()
|
|||
End();
|
||||
}
|
||||
|
||||
void ImGui::SetTooltipV(const char* fmt, va_list args)
|
||||
{
|
||||
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None))
|
||||
return;
|
||||
TextV(fmt, args);
|
||||
EndTooltip();
|
||||
}
|
||||
|
||||
void ImGui::SetTooltip(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -10754,6 +10820,32 @@ void ImGui::SetTooltip(const char* fmt, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
void ImGui::SetTooltipV(const char* fmt, va_list args)
|
||||
{
|
||||
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
|
||||
return;
|
||||
TextV(fmt, args);
|
||||
EndTooltip();
|
||||
}
|
||||
|
||||
// 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);
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -11287,15 +11379,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;
|
||||
|
@ -19040,7 +19137,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);
|
||||
|
@ -19135,7 +19232,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);
|
||||
|
@ -19512,6 +19609,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();
|
||||
|
@ -19589,7 +19687,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();
|
||||
|
|
78
imgui.h
78
imgui.h
|
@ -23,7 +23,7 @@
|
|||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.89.7 WIP"
|
||||
#define IMGUI_VERSION_NUM 18962
|
||||
#define IMGUI_VERSION_NUM 18964
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
|
@ -674,12 +674,19 @@ namespace ImGui
|
|||
IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL
|
||||
|
||||
// Tooltips
|
||||
// - Tooltip are windows following the mouse. They do not take focus away.
|
||||
// - Tooltips are windows following the mouse. They do not take focus away.
|
||||
IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).
|
||||
IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip() returns true!
|
||||
IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true!
|
||||
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip().
|
||||
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||
|
||||
// Tooltips: helper for showing a tooltip when hovering an item
|
||||
// - BeginItemTooltip(), SetItemTooltip() are shortcuts for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { BeginTooltip() or SetTooltip() }' idiom.
|
||||
// - Where 'ImGuiHoveredFlags_Tooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav'. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
|
||||
IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered.
|
||||
IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip().
|
||||
IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||
|
||||
// Popups, Modals
|
||||
// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
|
||||
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
|
||||
|
@ -1325,14 +1332,26 @@ enum ImGuiHoveredFlags_
|
|||
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
|
||||
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
|
||||
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled
|
||||
ImGuiHoveredFlags_NoNavOverride = 1 << 10, // Disable using gamepad/keyboard navigation state when active, always query mouse.
|
||||
ImGuiHoveredFlags_NoNavOverride = 1 << 10, // IsItemHovered() only: Disable using gamepad/keyboard navigation state when active, always query mouse
|
||||
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
|
||||
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows,
|
||||
|
||||
// Hovering delays (for tooltips)
|
||||
ImGuiHoveredFlags_DelayNormal = 1 << 11, // Return true after io.HoverDelayNormal elapsed (~0.30 sec)
|
||||
ImGuiHoveredFlags_DelayShort = 1 << 12, // Return true after io.HoverDelayShort elapsed (~0.10 sec)
|
||||
ImGuiHoveredFlags_NoSharedDelay = 1 << 13, // Disable shared delay system where moving from one item to the next keeps the previous timer for a short time (standard for tooltips with long delays)
|
||||
// Tooltips mode
|
||||
// - typically used in IsItemHovered() + SetTooltip() sequence.
|
||||
// - this is a shortcut to pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' where you can reconfigure desired behavior.
|
||||
// e.g. 'TooltipHoveredFlagsForMouse' defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
|
||||
// - for frequently actioned or hovered items providing a tooltip, you want may to use ImGuiHoveredFlags_ForTooltip (stationary + delay) so the tooltip doesn't show too often.
|
||||
// - for items which main purpose is to be hovered, or items with low affordance, or in less consistent apps, prefer no delay or shorter delay.
|
||||
ImGuiHoveredFlags_ForTooltip = 1 << 11, // Shortcut for standard flags when using IsItemHovered() + SetTooltip() sequence.
|
||||
|
||||
// (Advanced) Mouse Hovering delays.
|
||||
// - generally you can use ImGuiHoveredFlags_ForTooltip to use application-standardized flags.
|
||||
// - use those if you need specific overrides.
|
||||
ImGuiHoveredFlags_Stationary = 1 << 12, // Require mouse to be stationary for style.HoverStationaryDelay (~0.15 sec) _at least one time_. After this, can move on same item/window. Using the stationary test tends to reduces the need for a long delay.
|
||||
ImGuiHoveredFlags_DelayNone = 1 << 13, // IsItemHovered() only: Return true immediately (default). As this is the default you generally ignore this.
|
||||
ImGuiHoveredFlags_DelayShort = 1 << 14, // IsItemHovered() only: Return true after style.HoverDelayShort elapsed (~0.15 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item).
|
||||
ImGuiHoveredFlags_DelayNormal = 1 << 15, // IsItemHovered() only: Return true after style.HoverDelayNormal elapsed (~0.40 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item).
|
||||
ImGuiHoveredFlags_NoSharedDelay = 1 << 16, // IsItemHovered() only: Disable shared delay system where moving from one item to the next keeps the previous timer for a short time (standard for tooltips with long delays)
|
||||
};
|
||||
|
||||
// Flags for ImGui::DockSpace(), shared/inherited by child nodes.
|
||||
|
@ -1965,6 +1984,13 @@ struct ImGuiStyle
|
|||
float CircleTessellationMaxError; // 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.
|
||||
ImVec4 Colors[ImGuiCol_COUNT];
|
||||
|
||||
// Behaviors
|
||||
float HoverStationaryDelay; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary.
|
||||
float HoverDelayShort; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay.
|
||||
float HoverDelayNormal; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). "
|
||||
ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
|
||||
ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
|
||||
|
||||
IMGUI_API ImGuiStyle();
|
||||
IMGUI_API void ScaleAllSizes(float scale_factor);
|
||||
};
|
||||
|
@ -1999,13 +2025,6 @@ struct ImGuiIO
|
|||
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
|
||||
const char* IniFilename; // = "imgui.ini" // Path to .ini file (important: default "imgui.ini" is relative to current working dir!). Set NULL to disable automatic .ini loading/saving or if you want to manually call LoadIniSettingsXXX() / SaveIniSettingsXXX() functions.
|
||||
const char* LogFilename; // = "imgui_log.txt"// Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
|
||||
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
|
||||
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging.
|
||||
float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
|
||||
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
|
||||
float HoverDelayNormal; // = 0.30 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayNormal) returns true.
|
||||
float HoverDelayShort; // = 0.10 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayShort) returns true.
|
||||
void* UserData; // = NULL // Store your own data.
|
||||
|
||||
ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture.
|
||||
|
@ -2037,18 +2056,31 @@ struct ImGuiIO
|
|||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
|
||||
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
|
||||
|
||||
// Inputs Behaviors
|
||||
// (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle)
|
||||
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
|
||||
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging.
|
||||
float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
|
||||
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Debug options
|
||||
// - tools to test correct Begin/End and BeginChild/EndChild behaviors.
|
||||
// - presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
|
||||
// this is inconsistent with other BeginXXX functions and create confusion for many users.
|
||||
// - we expect to update the API eventually. In the meanwhile we provide tools to facilitate checking user-code behavior.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Tools to test correct Begin/End and BeginChild/EndChild behaviors.
|
||||
// Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
|
||||
// This is inconsistent with other BeginXXX functions and create confusion for many users.
|
||||
// We expect to update the API eventually. In the meanwhile we provide tools to facilitate checking user-code behavior.
|
||||
bool ConfigDebugBeginReturnValueOnce;// = false // First-time calls to Begin()/BeginChild() will return false. NEEDS TO BE SET AT APPLICATION BOOT TIME if you don't want to miss windows.
|
||||
bool ConfigDebugBeginReturnValueLoop;// = false // Some calls to Begin()/BeginChild() will return false. Will cycle through window depths then repeat. Suggested use: add "io.ConfigDebugBeginReturnValue = io.KeyShift" in your main loop then occasionally press SHIFT. Windows should be flickering while running.
|
||||
// - option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.
|
||||
// - backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them.
|
||||
// - consider using e.g. Win32's IsDebuggerPresent() as an additional filter (or see ImOsIsDebuggerPresent() in imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version).
|
||||
|
||||
// Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.
|
||||
// Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them.
|
||||
// Consider using e.g. Win32's IsDebuggerPresent() as an additional filter (or see ImOsIsDebuggerPresent() in imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version).
|
||||
bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys() in input processing.
|
||||
// - tools to audit ini data
|
||||
|
||||
// Option to audit .ini data
|
||||
bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower)
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
150
imgui_demo.cpp
150
imgui_demo.cpp
|
@ -213,7 +213,7 @@ static void ShowDemoWindowInputs();
|
|||
static void HelpMarker(const char* desc)
|
||||
{
|
||||
ImGui::TextDisabled("(?)");
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort) && ImGui::BeginTooltip())
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||
ImGui::TextUnformatted(desc);
|
||||
|
@ -685,37 +685,8 @@ static void ShowDemoWindowWidgets()
|
|||
ImGui::SameLine();
|
||||
ImGui::Text("%d", counter);
|
||||
|
||||
{
|
||||
// Tooltips
|
||||
IMGUI_DEMO_MARKER("Widgets/Basic/Tooltips");
|
||||
//ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Tooltips:");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SmallButton("Basic");
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("I am a tooltip");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SmallButton("Fancy");
|
||||
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::Text("I am a fancy tooltip");
|
||||
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
||||
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
|
||||
ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime()));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SmallButton("Delayed");
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) // With a delay
|
||||
ImGui::SetTooltip("I am a tooltip with a delay.");
|
||||
|
||||
ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"Tooltip are created by using the IsItemHovered() function over any kind of item.");
|
||||
}
|
||||
ImGui::Button("Tooltip");
|
||||
ImGui::SetItemTooltip("I am a tooltip");
|
||||
|
||||
ImGui::LabelText("label", "Value");
|
||||
|
||||
|
@ -850,6 +821,73 @@ static void ShowDemoWindowWidgets()
|
|||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Tooltips");
|
||||
if (ImGui::TreeNode("Tooltips"))
|
||||
{
|
||||
// Tooltips are windows following the mouse. They do not take focus away.
|
||||
ImGui::SeparatorText("General");
|
||||
|
||||
// Typical use cases:
|
||||
// - Short-form (text only): SetItemTooltip("Hello");
|
||||
// - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); }
|
||||
|
||||
// - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); }
|
||||
// - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); }
|
||||
|
||||
HelpMarker(
|
||||
"Tooltip are typically created by using the IsItemHovered() + SetTooltip() functions over any kind of item.\n\n"
|
||||
"We provide a helper SetItemTooltip() function to perform the two with standards flags.");
|
||||
|
||||
ImVec2 sz = ImVec2(-FLT_MIN, 0.0f);
|
||||
|
||||
ImGui::Button("Basic", sz);
|
||||
ImGui::SetItemTooltip("I am a tooltip");
|
||||
|
||||
ImGui::Button("Fancy", sz);
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
ImGui::Text("I am a fancy tooltip");
|
||||
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
||||
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
|
||||
ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime()));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Custom");
|
||||
|
||||
// Showcase NOT relying on a IsItemHovered() to emit a tooltip.
|
||||
static bool always_on = false;
|
||||
ImGui::Checkbox("Always On", &always_on);
|
||||
if (always_on)
|
||||
ImGui::SetTooltip("I am following you around.");
|
||||
|
||||
// The following examples are passed for documentation purpose but may not be useful to most users.
|
||||
// Passing ImGuiHoveredFlags_Tooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
|
||||
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used.
|
||||
// With default settings, ImGuiHoveredFlags_Tooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
|
||||
ImGui::Button("Manual", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||
ImGui::SetTooltip("I am a manually emitted tooltip");
|
||||
|
||||
ImGui::Button("DelayNone", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone))
|
||||
ImGui::SetTooltip("I am a tooltip with no delay.");
|
||||
|
||||
ImGui::Button("DelayShort", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay))
|
||||
ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort);
|
||||
|
||||
ImGui::Button("DelayLong", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay))
|
||||
ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec)", ImGui::GetStyle().HoverDelayNormal);
|
||||
|
||||
ImGui::Button("Stationary", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
|
||||
ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating.");
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Testing ImGuiOnceUponAFrame helper.
|
||||
//static ImGuiOnceUponAFrame once;
|
||||
//for (int i = 0; i < 5; i++)
|
||||
|
@ -1115,7 +1153,7 @@ static void ShowDemoWindowWidgets()
|
|||
ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||||
ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border);
|
||||
ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col);
|
||||
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
float region_sz = 32.0f;
|
||||
float region_x = io.MousePos.x - pos.x - region_sz * 0.5f;
|
||||
|
@ -2436,8 +2474,10 @@ static void ShowDemoWindowWidgets()
|
|||
if (item_type == 15){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
|
||||
|
||||
bool hovered_delay_none = ImGui::IsItemHovered();
|
||||
bool hovered_delay_stationary = ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary);
|
||||
bool hovered_delay_short = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort);
|
||||
bool hovered_delay_normal = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal);
|
||||
bool hovered_delay_tooltip = ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip); // = Normal + Stationary
|
||||
|
||||
// Display the values of IsItemHovered() and other common item state functions.
|
||||
// Note that the ImGuiHoveredFlags_XXX flags can be combined.
|
||||
|
@ -2484,7 +2524,13 @@ static void ShowDemoWindowWidgets()
|
|||
ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y
|
||||
);
|
||||
ImGui::BulletText(
|
||||
"w/ Hovering Delay: None = %d, Fast %d, Normal = %d", hovered_delay_none, hovered_delay_short, hovered_delay_normal);
|
||||
"with Hovering Delay or Stationary test:\n"
|
||||
"IsItemHovered() = = %d\n"
|
||||
"IsItemHovered(_Stationary) = %d\n"
|
||||
"IsItemHovered(_DelayShort) = %d\n"
|
||||
"IsItemHovered(_DelayNormal) = %d\n"
|
||||
"IsItemHovered(_Tooltip) = %d",
|
||||
hovered_delay_none, hovered_delay_stationary, hovered_delay_short, hovered_delay_normal, hovered_delay_tooltip);
|
||||
|
||||
if (item_disabled)
|
||||
ImGui::EndDisabled();
|
||||
|
@ -2545,7 +2591,8 @@ static void ShowDemoWindowWidgets()
|
|||
"IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowHovered(_RootWindow|_DockHierarchy) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
|
||||
"IsWindowHovered(_AnyWindow) = %d\n",
|
||||
"IsWindowHovered(_AnyWindow) = %d\n"
|
||||
"IsWindowHovered(_Stationary) = %d\n",
|
||||
ImGui::IsWindowHovered(),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
|
||||
|
@ -2559,7 +2606,8 @@ static void ShowDemoWindowWidgets()
|
|||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow));
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_Stationary));
|
||||
|
||||
ImGui::BeginChild("child", ImVec2(0, 50), true);
|
||||
ImGui::Text("This is another child window for testing the _ChildWindows flag.");
|
||||
|
@ -2860,7 +2908,7 @@ static void ShowDemoWindowLayout()
|
|||
ImGui::PushID(i);
|
||||
ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items));
|
||||
ImGui::PopID();
|
||||
//if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i);
|
||||
//ImGui::SetItemTooltip("ListBox %d hovered", i);
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
|
@ -2913,8 +2961,7 @@ static void ShowDemoWindowLayout()
|
|||
ImGui::SameLine();
|
||||
ImGui::Button("EEE");
|
||||
ImGui::EndGroup();
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("First group hovered");
|
||||
ImGui::SetItemTooltip("First group hovered");
|
||||
}
|
||||
// Capture the group size and create widgets using the same size
|
||||
ImVec2 size = ImGui::GetItemRectSize();
|
||||
|
@ -3475,8 +3522,7 @@ static void ShowDemoWindowPopups()
|
|||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Tooltip here");
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("I am a tooltip over a popup");
|
||||
ImGui::SetItemTooltip("I am a tooltip over a popup");
|
||||
|
||||
if (ImGui::Button("Stacked Popup"))
|
||||
ImGui::OpenPopup("another popup");
|
||||
|
@ -3560,8 +3606,7 @@ static void ShowDemoWindowPopups()
|
|||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Right-click to open popup");
|
||||
ImGui::SetItemTooltip("Right-click to open popup");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3813,7 +3858,7 @@ static void EditTableSizingFlags(ImGuiTableFlags* p_flags)
|
|||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("(?)");
|
||||
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 50.0f);
|
||||
for (int m = 0; m < IM_ARRAYSIZE(policies); m++)
|
||||
|
@ -6014,10 +6059,11 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
|||
return;
|
||||
}
|
||||
IMGUI_DEMO_MARKER("Tools/About Dear ImGui");
|
||||
ImGui::Text("Dear ImGui %s", ImGui::GetVersion());
|
||||
ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
|
||||
ImGui::Text("If your company uses this, please consider sponsoring the project!");
|
||||
|
||||
static bool show_config_info = false;
|
||||
ImGui::Checkbox("Config/Build Information", &show_config_info);
|
||||
|
@ -6316,8 +6362,22 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||
ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%0.f");
|
||||
ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
ImGui::SeparatorText("Tooltips");
|
||||
for (int n = 0; n < 2; n++)
|
||||
if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse" : "HoverFlagsForTooltipNav"))
|
||||
{
|
||||
ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse : &style.HoverFlagsForTooltipNav;
|
||||
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p, ImGuiHoveredFlags_DelayNone);
|
||||
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p, ImGuiHoveredFlags_DelayShort);
|
||||
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p, ImGuiHoveredFlags_DelayNormal);
|
||||
ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p, ImGuiHoveredFlags_Stationary);
|
||||
ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p, ImGuiHoveredFlags_NoSharedDelay);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Misc");
|
||||
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
|
|
|
@ -278,6 +278,8 @@ namespace ImStb
|
|||
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
|
||||
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
|
||||
#define IM_STRINGIFY_HELPER(_X) #_X
|
||||
#define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer.
|
||||
|
||||
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
|
||||
#ifdef _MSC_VER
|
||||
|
@ -841,6 +843,14 @@ enum ImGuiItemStatusFlags_
|
|||
#endif
|
||||
};
|
||||
|
||||
// Extend ImGuiHoveredFlags_
|
||||
enum ImGuiHoveredFlagsPrivate_
|
||||
{
|
||||
ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay,
|
||||
ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary,
|
||||
ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_,
|
||||
};
|
||||
|
||||
// Extend ImGuiInputTextFlags_
|
||||
enum ImGuiInputTextFlagsPrivate_
|
||||
{
|
||||
|
@ -906,6 +916,7 @@ enum ImGuiSelectableFlagsPrivate_
|
|||
enum ImGuiTreeNodeFlagsPrivate_
|
||||
{
|
||||
ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20,
|
||||
ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 21,// (FIXME-WIP) Turn Down arrow into an Up arrow, but reversed trees (#6517)
|
||||
};
|
||||
|
||||
enum ImGuiSeparatorFlags_
|
||||
|
@ -935,7 +946,7 @@ enum ImGuiTextFlags_
|
|||
enum ImGuiTooltipFlags_
|
||||
{
|
||||
ImGuiTooltipFlags_None = 0,
|
||||
ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0, // Override will clear/ignore previously submitted tooltip (defaults to append)
|
||||
ImGuiTooltipFlags_OverridePrevious = 1 << 1, // Clear/ignore previously submitted tooltip (defaults to append)
|
||||
};
|
||||
|
||||
// FIXME: this is in development, not exposed/functional as a generic feature yet.
|
||||
|
@ -1829,6 +1840,7 @@ struct ImGuiSettingsHandler
|
|||
// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack.
|
||||
enum ImGuiLocKey : int
|
||||
{
|
||||
ImGuiLocKey_VersionStr,
|
||||
ImGuiLocKey_TableSizeOne,
|
||||
ImGuiLocKey_TableSizeAllFit,
|
||||
ImGuiLocKey_TableSizeAllDefault,
|
||||
|
@ -2106,7 +2118,6 @@ struct ImGuiContext
|
|||
|
||||
// Render
|
||||
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
|
||||
ImGuiMouseCursor MouseCursor;
|
||||
|
||||
// Drag and Drop
|
||||
bool DragDropActive;
|
||||
|
@ -2146,13 +2157,20 @@ struct ImGuiContext
|
|||
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
|
||||
|
||||
// Hover Delay system
|
||||
ImGuiID HoverDelayId;
|
||||
ImGuiID HoverDelayIdPreviousFrame;
|
||||
float HoverDelayTimer; // Currently used IsItemHovered(), generally inferred from g.HoveredIdTimer but kept uncleared until clear timer elapse.
|
||||
float HoverDelayClearTimer; // Currently used IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
|
||||
ImGuiID HoverItemDelayId;
|
||||
ImGuiID HoverItemDelayIdPreviousFrame;
|
||||
float HoverItemDelayTimer; // Currently used by IsItemHovered()
|
||||
float HoverItemDelayClearTimer; // Currently used by IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
|
||||
ImGuiID HoverItemUnlockedStationaryId; // Mouse has once been stationary on this item. Only reset after departing the item.
|
||||
ImGuiID HoverWindowUnlockedStationaryId; // Mouse has once been stationary on this window. Only reset after departing the window.
|
||||
|
||||
// Mouse state
|
||||
ImGuiMouseCursor MouseCursor;
|
||||
int MouseMovingFrames;
|
||||
float MouseStationaryTimer; // Time the mouse has been stationary (with some loose heuristic)
|
||||
ImVec2 MouseLastValidPos;
|
||||
|
||||
// Widget state
|
||||
ImVec2 MouseLastValidPos;
|
||||
ImGuiInputTextState InputTextState;
|
||||
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
|
||||
ImFont InputTextPasswordFont;
|
||||
|
@ -2343,7 +2361,6 @@ struct ImGuiContext
|
|||
NavWindowingToggleLayer = false;
|
||||
|
||||
DimBgRatio = 0.0f;
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
|
||||
DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
|
||||
DragDropSourceFlags = ImGuiDragDropFlags_None;
|
||||
|
@ -2363,8 +2380,12 @@ struct ImGuiContext
|
|||
TablesTempDataStacked = 0;
|
||||
CurrentTabBar = NULL;
|
||||
|
||||
HoverDelayId = HoverDelayIdPreviousFrame = 0;
|
||||
HoverDelayTimer = HoverDelayClearTimer = 0.0f;
|
||||
HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
|
||||
HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
|
||||
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
MouseMovingFrames = 0;
|
||||
MouseStationaryTimer = 0.0f;
|
||||
|
||||
TempInputId = 0;
|
||||
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
|
||||
|
|
|
@ -3036,8 +3036,8 @@ void ImGui::TableHeader(const char* label)
|
|||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size);
|
||||
|
||||
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
||||
if (text_clipped && hovered && g.ActiveId == 0 && IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
||||
SetTooltip("%.*s", (int)(label_end - label), label);
|
||||
if (text_clipped && hovered && g.ActiveId == 0)
|
||||
SetItemTooltip("%.*s", (int)(label_end - label), label);
|
||||
|
||||
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
||||
if (IsMouseReleased(1) && IsItemHovered())
|
||||
|
|
|
@ -5808,7 +5808,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||
}
|
||||
|
||||
// Tooltip
|
||||
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered)
|
||||
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
|
||||
|
||||
return pressed;
|
||||
|
@ -5838,7 +5838,7 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
|
|||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None))
|
||||
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
|
||||
return;
|
||||
const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text;
|
||||
if (text_end > text)
|
||||
|
@ -6266,7 +6266,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||
if (flags & ImGuiTreeNodeFlags_Bullet)
|
||||
RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col);
|
||||
else if (!is_leaf)
|
||||
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
||||
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f);
|
||||
else // Leaf without bullet, left-adjusted text
|
||||
text_pos.x -= text_offset_x;
|
||||
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
|
||||
|
@ -8596,8 +8596,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||
// FIXME: We may want disabled tab to still display the tooltip?
|
||||
if (text_clipped && g.HoveredId == id && !held)
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
if (IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
||||
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
|
||||
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
||||
if (is_tab_button)
|
||||
|
|
Loading…
Reference in New Issue