mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-16 12:03:27 +01:00
Merge branch 'master' into docking
# Conflicts: # imgui.cpp # imgui_internal.h
This commit is contained in:
commit
7bfc379a23
@ -131,6 +131,8 @@ Other Changes:
|
||||
- Disabled: disabled items set HoveredId, allowing e.g. HoveredIdTimer to function. (#211, #3419) [@rokups]
|
||||
- Disabled: disabled mode more consistently release active id if the active item got disabled. (#211)
|
||||
- Disabled: disabled mode doesn't prevent Selectable() from looking selected. (#211)
|
||||
- Disabled: fixed IsItemHovered() returning true on disabled item when navigated to. (#211)
|
||||
- Disabled: fixed IsItemHovered() if popped disabled state after item, or when using Selectable_Disabled. (#211)
|
||||
- Fixed printf-style format checks on non-MinGW flavors. (#4183, #3592)
|
||||
- Fonts: Functions with a 'float size_pixels' parameter can accept zero if it is set in ImFontSize::SizePixels.
|
||||
- Fonts: Prefer using U+FFFD character for fallback instead of '?', if available. (#4269)
|
||||
|
204
imgui.cpp
204
imgui.cpp
@ -1095,7 +1095,7 @@ ImGuiIO::ImGuiIO()
|
||||
DisplaySize = ImVec2(-1.0f, -1.0f);
|
||||
DeltaTime = 1.0f / 60.0f;
|
||||
IniSavingRate = 5.0f;
|
||||
IniFilename = "imgui.ini";
|
||||
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;
|
||||
@ -3177,7 +3177,7 @@ void ImGui::MarkItemEdited(ImGuiID id)
|
||||
//IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
|
||||
g.ActiveIdHasBeenEditedThisFrame = true;
|
||||
g.ActiveIdHasBeenEditedBefore = true;
|
||||
g.CurrentWindow->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
}
|
||||
|
||||
static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
|
||||
@ -3213,10 +3213,14 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.NavDisableMouseHover && !g.NavDisableHighlight)
|
||||
{
|
||||
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
return false;
|
||||
return IsItemFocused();
|
||||
}
|
||||
|
||||
// Test for bounding box overlap, as updated as ItemAdd()
|
||||
ImGuiItemStatusFlags status_flags = window->DC.LastItemStatusFlags;
|
||||
ImGuiItemStatusFlags status_flags = g.LastItemData.StatusFlags;
|
||||
if (!(status_flags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function
|
||||
@ -3232,7 +3236,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
|
||||
// Test if another item is active (e.g. being dragged)
|
||||
if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0)
|
||||
if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
|
||||
if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
|
||||
return false;
|
||||
|
||||
// Test if interactions on this window are blocked by an active popup or modal.
|
||||
@ -3241,12 +3245,12 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
return false;
|
||||
|
||||
// Test if the item is disabled
|
||||
if ((g.CurrentItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
return false;
|
||||
|
||||
// Special handling for calling after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if ((window->DC.LastItemId == window->ID || window->DC.LastItemId == window->MoveId) && window->WriteAccessed)
|
||||
if ((g.LastItemData.ID == window->ID || g.LastItemData.ID == window->MoveId) && window->WriteAccessed)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -3279,8 +3283,12 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
||||
SetHoveredID(id);
|
||||
|
||||
// When disabled we'll return false but still set HoveredId
|
||||
if (g.CurrentItemFlags & ImGuiItemFlags_Disabled)
|
||||
ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
||||
if (item_flags & ImGuiItemFlags_Disabled)
|
||||
{
|
||||
// Release active id if turning disabled
|
||||
if (g.ActiveId == id)
|
||||
ClearActiveID();
|
||||
g.HoveredIdDisabled = true;
|
||||
return false;
|
||||
}
|
||||
@ -3314,22 +3322,25 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged
|
||||
|
||||
// This is also inlined in ItemAdd()
|
||||
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect!
|
||||
void ImGui::SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
|
||||
void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
|
||||
{
|
||||
window->DC.LastItemId = item_id;
|
||||
window->DC.LastItemStatusFlags = item_flags;
|
||||
window->DC.LastItemRect = item_rect;
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.LastItemData.ID = item_id;
|
||||
g.LastItemData.InFlags = in_flags;
|
||||
g.LastItemData.StatusFlags = item_flags;
|
||||
g.LastItemData.Rect = item_rect;
|
||||
}
|
||||
|
||||
// Called by ItemAdd()
|
||||
// Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
|
||||
void ImGui::ItemFocusable(ImGuiWindow* window, ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(id != 0 && id == window->DC.LastItemId);
|
||||
IM_ASSERT(id != 0 && id == g.LastItemData.ID);
|
||||
|
||||
// Increment counters
|
||||
// FIXME: ImGuiItemFlags_Disabled should disable more.
|
||||
const bool is_tab_stop = (g.CurrentItemFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
|
||||
const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
|
||||
window->DC.FocusCounterRegular++;
|
||||
if (is_tab_stop)
|
||||
{
|
||||
@ -3351,13 +3362,13 @@ void ImGui::ItemFocusable(ImGuiWindow* window, ImGuiID id)
|
||||
{
|
||||
if (window->DC.FocusCounterRegular == g.TabFocusRequestCurrCounterRegular)
|
||||
{
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_FocusedByCode;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByCode;
|
||||
return;
|
||||
}
|
||||
if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop)
|
||||
{
|
||||
g.NavJustTabbedId = id;
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_FocusedByTabbing;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByTabbing;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3760,8 +3771,6 @@ static void TranslateWindow(ImGuiWindow* window, const ImVec2& delta)
|
||||
window->DC.CursorPos += delta;
|
||||
window->DC.CursorStartPos += delta;
|
||||
window->DC.CursorMaxPos += delta;
|
||||
window->DC.LastItemRect.Translate(delta);
|
||||
window->DC.LastItemDisplayRect.Translate(delta);
|
||||
}
|
||||
|
||||
static void ScaleWindow(ImGuiWindow* window, float scale)
|
||||
@ -5109,10 +5118,7 @@ bool ImGui::IsItemActive()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId)
|
||||
{
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
return g.ActiveId == window->DC.LastItemId;
|
||||
}
|
||||
return g.ActiveId == g.LastItemData.ID;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5120,21 +5126,17 @@ bool ImGui::IsItemActivated()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId)
|
||||
{
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.ActiveId == window->DC.LastItemId && g.ActiveIdPreviousFrame != window->DC.LastItemId)
|
||||
if (g.ActiveId == g.LastItemData.ID && g.ActiveIdPreviousFrame != g.LastItemData.ID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::IsItemDeactivated()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDeactivated)
|
||||
return (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_Deactivated) != 0;
|
||||
return (g.ActiveIdPreviousFrame == window->DC.LastItemId && g.ActiveIdPreviousFrame != 0 && g.ActiveId != window->DC.LastItemId);
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDeactivated)
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Deactivated) != 0;
|
||||
return (g.ActiveIdPreviousFrame == g.LastItemData.ID && g.ActiveIdPreviousFrame != 0 && g.ActiveId != g.LastItemData.ID);
|
||||
}
|
||||
|
||||
bool ImGui::IsItemDeactivatedAfterEdit()
|
||||
@ -5147,14 +5149,13 @@ bool ImGui::IsItemDeactivatedAfterEdit()
|
||||
bool ImGui::IsItemFocused()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
if (g.NavId != window->DC.LastItemId || g.NavId == 0)
|
||||
if (g.NavId != g.LastItemData.ID || g.NavId == 0)
|
||||
return false;
|
||||
|
||||
// Special handling for the dummy item after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if (window->DC.LastItemId == window->ID && window->WriteAccessed)
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.LastItemData.ID == window->ID && window->WriteAccessed)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -5170,13 +5171,13 @@ bool ImGui::IsItemClicked(ImGuiMouseButton mouse_button)
|
||||
bool ImGui::IsItemToggledOpen()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return (g.CurrentWindow->DC.LastItemStatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
|
||||
}
|
||||
|
||||
bool ImGui::IsItemToggledSelection()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return (g.CurrentWindow->DC.LastItemStatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false;
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false;
|
||||
}
|
||||
|
||||
bool ImGui::IsAnyItemHovered()
|
||||
@ -5199,14 +5200,14 @@ bool ImGui::IsAnyItemFocused()
|
||||
|
||||
bool ImGui::IsItemVisible()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->ClipRect.Overlaps(window->DC.LastItemRect);
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.CurrentWindow->ClipRect.Overlaps(g.LastItemData.Rect);
|
||||
}
|
||||
|
||||
bool ImGui::IsItemEdited()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_Edited) != 0;
|
||||
ImGuiContext& g = *GImGui;
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Edited) != 0;
|
||||
}
|
||||
|
||||
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
|
||||
@ -5214,7 +5215,7 @@ bool ImGui::IsItemEdited()
|
||||
void ImGui::SetItemAllowOverlap()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiID id = g.CurrentWindow->DC.LastItemId;
|
||||
ImGuiID id = g.LastItemData.ID;
|
||||
if (g.HoveredId == id)
|
||||
g.HoveredIdAllowOverlap = true;
|
||||
if (g.ActiveId == id)
|
||||
@ -5224,7 +5225,7 @@ void ImGui::SetItemAllowOverlap()
|
||||
void ImGui::SetItemUsingMouseWheel()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiID id = g.CurrentWindow->DC.LastItemId;
|
||||
ImGuiID id = g.LastItemData.ID;
|
||||
if (g.HoveredId == id)
|
||||
g.HoveredIdUsingMouseWheel = true;
|
||||
if (g.ActiveId == id)
|
||||
@ -5243,20 +5244,20 @@ void ImGui::SetActiveIdUsingNavAndKeys()
|
||||
|
||||
ImVec2 ImGui::GetItemRectMin()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.LastItemRect.Min;
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.LastItemData.Rect.Min;
|
||||
}
|
||||
|
||||
ImVec2 ImGui::GetItemRectMax()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.LastItemRect.Max;
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.LastItemData.Rect.Max;
|
||||
}
|
||||
|
||||
ImVec2 ImGui::GetItemRectSize()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.LastItemRect.GetSize();
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.LastItemData.Rect.GetSize();
|
||||
}
|
||||
|
||||
bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags)
|
||||
@ -5361,7 +5362,7 @@ void ImGui::EndChild()
|
||||
ItemAdd(bb, 0);
|
||||
}
|
||||
if (g.HoveredWindow == window)
|
||||
parent_window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
}
|
||||
g.WithinEndChild = false;
|
||||
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
|
||||
@ -6189,7 +6190,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
}
|
||||
|
||||
// Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
|
||||
ImGuiWindow* parent_window_in_stack = window->DockIsActive ? window->DockNode->HostWindow : g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
|
||||
ImGuiWindow* parent_window_in_stack = window->DockIsActive ? window->DockNode->HostWindow : g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back().Window;
|
||||
ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow;
|
||||
IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
|
||||
|
||||
@ -6199,7 +6200,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// Add to stack
|
||||
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
|
||||
g.CurrentWindowStack.push_back(window);
|
||||
ImGuiWindowStackData window_stack_data;
|
||||
window_stack_data.Window = window;
|
||||
window_stack_data.ParentLastItemDataBackup = g.LastItemData;
|
||||
g.CurrentWindowStack.push_back(window_stack_data);
|
||||
g.CurrentWindow = window;
|
||||
window->DC.StackSizesOnBegin.SetToCurrentState();
|
||||
g.CurrentWindow = NULL;
|
||||
@ -6810,13 +6814,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
|
||||
// This is useful to allow creating context menus on title bar only, etc.
|
||||
if (window->DockIsActive)
|
||||
SetLastItemData(window, window->ID, window->DockTabItemStatusFlags, window->DockTabItemRect);
|
||||
SetLastItemData(window->ID, g.CurrentItemFlags, window->DockTabItemStatusFlags, window->DockTabItemRect);
|
||||
else
|
||||
SetLastItemData(window, window->MoveId, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect);
|
||||
SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect);
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
IMGUI_TEST_ENGINE_ITEM_ADD(window->DC.LastItemRect, window->DC.LastItemId);
|
||||
IMGUI_TEST_ENGINE_ITEM_ADD(g.LastItemData.Rect, g.LastItemData.ID);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -6827,7 +6831,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
}
|
||||
|
||||
// Pull/inherit current state
|
||||
g.CurrentItemFlags = g.ItemFlagsStack.back(); // Inherit from shared stack
|
||||
window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetID("#FOCUSSCOPE"); // Inherit from parent only // -V595
|
||||
|
||||
if (!(flags & ImGuiWindowFlags_DockNodeHost))
|
||||
@ -6934,11 +6937,12 @@ void ImGui::End()
|
||||
host_window->DC.CursorMaxPos = window->DC.CursorMaxPos + window->WindowPadding - host_window->WindowPadding;
|
||||
|
||||
// Pop from window stack
|
||||
g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup;
|
||||
g.CurrentWindowStack.pop_back();
|
||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||
g.BeginPopupStack.pop_back();
|
||||
window->DC.StackSizesOnBegin.CompareWithCurrentState();
|
||||
SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
|
||||
SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window);
|
||||
if (g.CurrentWindow)
|
||||
SetCurrentViewport(g.CurrentWindow, g.CurrentWindow->Viewport);
|
||||
}
|
||||
@ -7628,8 +7632,8 @@ void ImGui::SetItemDefaultFocus()
|
||||
if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
{
|
||||
g.NavInitRequest = false;
|
||||
g.NavInitResultId = window->DC.LastItemId;
|
||||
g.NavInitResultRectRel = ImRect(window->DC.LastItemRect.Min - window->Pos, window->DC.LastItemRect.Max - window->Pos);
|
||||
g.NavInitResultId = g.LastItemData.ID;
|
||||
g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
|
||||
NavUpdateAnyRequestFlag();
|
||||
if (!IsItemVisible())
|
||||
SetScrollHereY();
|
||||
@ -8064,9 +8068,16 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
// Set item data
|
||||
g.LastItemData.ID = id;
|
||||
g.LastItemData.Rect = bb;
|
||||
g.LastItemData.InFlags = g.CurrentItemFlags;
|
||||
g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None;
|
||||
|
||||
// Directional navigation processing
|
||||
if (id != 0)
|
||||
{
|
||||
// Navigation processing runs prior to clipping early-out
|
||||
// Runs prior to clipping early-out
|
||||
// (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget
|
||||
// (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests
|
||||
// unfortunately, but it is still limited to one window. It may not scale very well for windows with ten of
|
||||
@ -8090,11 +8101,6 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Equivalent to calling SetLastItemData()
|
||||
window->DC.LastItemId = id;
|
||||
window->DC.LastItemRect = bb;
|
||||
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
|
||||
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
@ -8115,7 +8121,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
|
||||
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
|
||||
if (IsMouseHoveringRect(bb.Min, bb.Max))
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8447,24 +8453,24 @@ void ImGui::EndGroup()
|
||||
const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId;
|
||||
const bool group_contains_prev_active_id = (group_data.BackupActiveIdPreviousFrameIsAlive == false) && (g.ActiveIdPreviousFrameIsAlive == true);
|
||||
if (group_contains_curr_active_id)
|
||||
window->DC.LastItemId = g.ActiveId;
|
||||
g.LastItemData.ID = g.ActiveId;
|
||||
else if (group_contains_prev_active_id)
|
||||
window->DC.LastItemId = g.ActiveIdPreviousFrame;
|
||||
window->DC.LastItemRect = group_bb;
|
||||
g.LastItemData.ID = g.ActiveIdPreviousFrame;
|
||||
g.LastItemData.Rect = group_bb;
|
||||
|
||||
// Forward Hovered flag
|
||||
const bool group_contains_curr_hovered_id = (group_data.BackupHoveredIdIsAlive == false) && g.HoveredId != 0;
|
||||
if (group_contains_curr_hovered_id)
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
|
||||
// Forward Edited flag
|
||||
if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame)
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
|
||||
// Forward Deactivated flag
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDeactivated;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDeactivated;
|
||||
if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame)
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_Deactivated;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Deactivated;
|
||||
|
||||
g.GroupStack.pop_back();
|
||||
//window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug]
|
||||
@ -8653,7 +8659,7 @@ void ImGui::SetScrollHereX(float center_x_ratio)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float spacing_x = ImMax(window->WindowPadding.x, g.Style.ItemSpacing.x);
|
||||
float target_pos_x = ImLerp(window->DC.LastItemRect.Min.x - spacing_x, window->DC.LastItemRect.Max.x + spacing_x, center_x_ratio);
|
||||
float target_pos_x = ImLerp(g.LastItemData.Rect.Min.x - spacing_x, g.LastItemData.Rect.Max.x + spacing_x, center_x_ratio);
|
||||
SetScrollFromPosX(window, target_pos_x - window->Pos.x, center_x_ratio); // Convert from absolute to local pos
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge
|
||||
@ -9049,12 +9055,13 @@ void ImGui::EndPopup()
|
||||
// - This is essentially the same as BeginPopupContextItem() but without the trailing BeginPopup()
|
||||
void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
{
|
||||
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||
ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||
OpenPopupEx(id, popup_flags);
|
||||
}
|
||||
}
|
||||
@ -9077,11 +9084,12 @@ void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags
|
||||
// The main difference being that this is tweaked to avoid computing the ID twice.
|
||||
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||
ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
OpenPopupEx(id, popup_flags);
|
||||
@ -9090,7 +9098,8 @@ bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flag
|
||||
|
||||
bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!str_id)
|
||||
str_id = "window_context";
|
||||
ImGuiID id = window->GetID(str_id);
|
||||
@ -9103,7 +9112,8 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_fl
|
||||
|
||||
bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!str_id)
|
||||
str_id = "void_context";
|
||||
ImGuiID id = window->GetID(str_id);
|
||||
@ -9288,8 +9298,8 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
|
||||
g.NavLayer = nav_layer;
|
||||
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
window->NavLastIds[nav_layer] = id;
|
||||
if (window->DC.LastItemId == id)
|
||||
window->NavRectRel[nav_layer] = ImRect(window->DC.LastItemRect.Min - window->Pos, window->DC.LastItemRect.Max - window->Pos);
|
||||
if (g.LastItemData.ID == id)
|
||||
window->NavRectRel[nav_layer] = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
|
||||
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
||||
g.NavDisableMouseHover = true;
|
||||
@ -9386,7 +9396,7 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
|
||||
else
|
||||
{
|
||||
// Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter)
|
||||
quadrant = (window->DC.LastItemId < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right;
|
||||
quadrant = (g.LastItemData.ID < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right;
|
||||
}
|
||||
|
||||
#if IMGUI_DEBUG_NAV_SCORING
|
||||
@ -9474,7 +9484,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
||||
//if (!g.IO.NavActive) // [2017/10/06] Removed this possibly redundant test but I am not sure of all the side-effects yet. Some of the feature here will need to work regardless of using a _NoNavInputs flag.
|
||||
// return;
|
||||
|
||||
const ImGuiItemFlags item_flags = g.CurrentItemFlags;
|
||||
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
|
||||
const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
|
||||
|
||||
// Process Init Request
|
||||
@ -10481,7 +10491,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
ImGuiID source_parent_id = 0;
|
||||
if (!(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
{
|
||||
source_id = window->DC.LastItemId;
|
||||
source_id = g.LastItemData.ID;
|
||||
if (source_id != 0)
|
||||
{
|
||||
// Common path: items with ID
|
||||
@ -10508,15 +10518,16 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
}
|
||||
|
||||
// Early out
|
||||
if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window))
|
||||
if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window))
|
||||
return false;
|
||||
|
||||
// Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image()
|
||||
// We build a throwaway ID based on current ID stack + relative AABB of items in window.
|
||||
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
|
||||
// We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
|
||||
source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect);
|
||||
bool is_hovered = ItemHoverable(window->DC.LastItemRect, source_id);
|
||||
// Rely on keeping other window->LastItemXXX fields intact.
|
||||
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
|
||||
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id);
|
||||
if (is_hovered && g.IO.MouseClicked[mouse_button])
|
||||
{
|
||||
SetActiveID(source_id, window);
|
||||
@ -10572,7 +10583,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
}
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
window->DC.LastItemStatusFlags &= ~ImGuiItemStatusFlags_HoveredRect;
|
||||
g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -10672,14 +10683,14 @@ bool ImGui::BeginDragDropTarget()
|
||||
return false;
|
||||
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
if (!(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
|
||||
if (hovered_window == NULL || window->RootWindowDockTree != hovered_window->RootWindowDockTree)
|
||||
return false;
|
||||
|
||||
const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
|
||||
ImGuiID id = window->DC.LastItemId;
|
||||
const ImRect& display_rect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? g.LastItemData.DisplayRect : g.LastItemData.Rect;
|
||||
ImGuiID id = g.LastItemData.ID;
|
||||
if (id == 0)
|
||||
id = window->GetIDFromRectangle(display_rect);
|
||||
if (g.DragDropPayload.SourceId == id)
|
||||
@ -14067,8 +14078,8 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
|
||||
node->VisibleWindow = window;
|
||||
|
||||
// Store last item data so it can be queried with IsItemXXX functions after the user Begin() call
|
||||
window->DockTabItemStatusFlags = host_window->DC.LastItemStatusFlags;
|
||||
window->DockTabItemRect = host_window->DC.LastItemRect;
|
||||
window->DockTabItemStatusFlags = g.LastItemData.StatusFlags;
|
||||
window->DockTabItemRect = g.LastItemData.Rect;
|
||||
|
||||
// Update navigation ID on menu layer
|
||||
if (g.NavWindow && g.NavWindow->RootWindow == window && (window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0)
|
||||
@ -14123,7 +14134,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
|
||||
{
|
||||
// ImGuiButtonFlags_AllowItemOverlap + SetItemAllowOverlap() required for appending into dock node tab bar,
|
||||
// otherwise dragging window will steal HoveredId and amended tabs cannot get them.
|
||||
host_window->DC.LastItemId = title_bar_id;
|
||||
g.LastItemData.ID = title_bar_id;
|
||||
SetItemAllowOverlap();
|
||||
}
|
||||
if (held)
|
||||
@ -15682,8 +15693,9 @@ void ImGui::BeginDockableDragDropSource(ImGuiWindow* window)
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.ActiveId == window->MoveId);
|
||||
IM_ASSERT(g.MovingWindow == window);
|
||||
IM_ASSERT(g.CurrentWindow == window);
|
||||
|
||||
window->DC.LastItemId = window->MoveId;
|
||||
g.LastItemData.ID = window->MoveId;
|
||||
window = window->RootWindowDockTree;
|
||||
IM_ASSERT((window->Flags & ImGuiWindowFlags_NoDocking) == 0);
|
||||
bool is_drag_docking = ImRect(0, 0, window->SizeFull.x, GetFrameHeight()).Contains(g.ActiveIdClickOffset); // FIXME-DOCKING: Need to make this stateful and explicit
|
||||
|
5
imgui.h
5
imgui.h
@ -62,7 +62,7 @@ Index of this file:
|
||||
// Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
|
||||
#define IMGUI_VERSION "1.84 WIP"
|
||||
#define IMGUI_VERSION_NUM 18309
|
||||
#define IMGUI_VERSION_NUM 18311
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
@ -930,6 +930,7 @@ namespace ImGui
|
||||
// Settings/.Ini Utilities
|
||||
// - The disk functions are automatically called if io.IniFilename != NULL (default is "imgui.ini").
|
||||
// - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually.
|
||||
// - Important: default value "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).
|
||||
IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename).
|
||||
IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.
|
||||
IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext).
|
||||
@ -1876,7 +1877,7 @@ struct ImGuiIO
|
||||
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size)
|
||||
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
|
||||
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
|
||||
const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory.
|
||||
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.
|
||||
|
@ -120,7 +120,7 @@ struct ImGuiDockNode; // Docking system node (hold a list of Windo
|
||||
struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session)
|
||||
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
|
||||
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
|
||||
struct ImGuiLastItemDataBackup; // Backup and restore IsItemHovered() internal data
|
||||
struct ImGuiLastItemData; // Status storage for last submitted items
|
||||
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
|
||||
struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result
|
||||
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
|
||||
@ -1192,6 +1192,25 @@ struct ImGuiNextItemData
|
||||
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
};
|
||||
|
||||
// Status storage for the last submitted item
|
||||
struct ImGuiLastItemData
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
|
||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||
ImRect Rect;
|
||||
ImRect DisplayRect;
|
||||
|
||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Data saved for each window pushed into the stack
|
||||
struct ImGuiWindowStackData
|
||||
{
|
||||
ImGuiWindow* Window;
|
||||
ImGuiLastItemData ParentLastItemDataBackup;
|
||||
};
|
||||
|
||||
struct ImGuiShrinkWidthItem
|
||||
{
|
||||
int Index;
|
||||
@ -1588,7 +1607,7 @@ struct ImGuiContext
|
||||
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
|
||||
ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front.
|
||||
ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child
|
||||
ImVector<ImGuiWindow*> CurrentWindowStack;
|
||||
ImVector<ImGuiWindowStackData> CurrentWindowStack;
|
||||
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
||||
int WindowsActiveCount; // Number of unique windows submitted by frame
|
||||
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
|
||||
@ -1602,7 +1621,6 @@ struct ImGuiContext
|
||||
float WheelingWindowTimer;
|
||||
|
||||
// Item/widgets state and tracking information
|
||||
ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
|
||||
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
||||
ImGuiID HoveredIdPreviousFrame;
|
||||
bool HoveredIdAllowOverlap;
|
||||
@ -1636,8 +1654,10 @@ struct ImGuiContext
|
||||
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
|
||||
|
||||
// Next window/item data
|
||||
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
|
||||
ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
|
||||
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
|
||||
ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd)
|
||||
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
|
||||
|
||||
// Shared stacks
|
||||
ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
|
||||
@ -1848,7 +1868,6 @@ struct ImGuiContext
|
||||
WheelingWindow = NULL;
|
||||
WheelingWindowTimer = 0.0f;
|
||||
|
||||
CurrentItemFlags = ImGuiItemFlags_None;
|
||||
HoveredId = HoveredIdPreviousFrame = 0;
|
||||
HoveredIdAllowOverlap = false;
|
||||
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
|
||||
@ -1878,6 +1897,8 @@ struct ImGuiContext
|
||||
LastActiveId = 0;
|
||||
LastActiveIdTimer = 0.0f;
|
||||
|
||||
CurrentItemFlags = ImGuiItemFlags_None;
|
||||
|
||||
CurrentDpiScale = 0.0f;
|
||||
CurrentViewport = NULL;
|
||||
MouseViewport = MouseLastHoveredViewport = NULL;
|
||||
@ -2002,12 +2023,6 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
|
||||
ImVec1 GroupOffset;
|
||||
|
||||
// Last item status
|
||||
ImGuiID LastItemId; // ID for last item
|
||||
ImGuiItemStatusFlags LastItemStatusFlags; // Status flags for last item (see ImGuiItemStatusFlags_)
|
||||
ImRect LastItemRect; // Interaction rect for last item
|
||||
ImRect LastItemDisplayRect; // End-user display rect for last item (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect)
|
||||
|
||||
// Keyboard/Gamepad navigation
|
||||
ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
|
||||
short NavLayersActiveMask; // Which layers have been written to (result from previous frame)
|
||||
@ -2177,19 +2192,6 @@ public:
|
||||
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
|
||||
};
|
||||
|
||||
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
|
||||
struct ImGuiLastItemDataBackup
|
||||
{
|
||||
ImGuiID LastItemId;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect;
|
||||
ImRect LastItemDisplayRect;
|
||||
|
||||
ImGuiLastItemDataBackup() { Backup(); }
|
||||
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemStatusFlags = window->DC.LastItemStatusFlags; LastItemRect = window->DC.LastItemRect; LastItemDisplayRect = window->DC.LastItemDisplayRect; }
|
||||
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Tab bar, Tab item support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2609,11 +2611,11 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_rect);
|
||||
|
||||
// Basic Accessors
|
||||
inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemId; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand)
|
||||
inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemStatusFlags; }
|
||||
inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.LastItemData.ID; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand)
|
||||
inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; }
|
||||
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; }
|
||||
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
|
||||
inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; }
|
||||
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.CurrentItemFlags; }
|
||||
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
|
||||
IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window);
|
||||
IMGUI_API void ClearActiveID();
|
||||
@ -2631,7 +2633,7 @@ namespace ImGui
|
||||
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
|
||||
IMGUI_API void ItemFocusable(ImGuiWindow* window, ImGuiID id);
|
||||
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
|
||||
IMGUI_API void SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
||||
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
|
||||
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
|
||||
@ -2947,7 +2949,7 @@ namespace ImGui
|
||||
|
||||
// Debug Tools
|
||||
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
|
||||
inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, col); }
|
||||
inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); }
|
||||
inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }
|
||||
|
||||
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas);
|
||||
|
@ -1956,8 +1956,9 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
|
||||
window->SkipItems = column->IsSkipItems;
|
||||
if (column->IsSkipItems)
|
||||
{
|
||||
window->DC.LastItemId = 0;
|
||||
window->DC.LastItemStatusFlags = 0;
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.LastItemData.ID = 0;
|
||||
g.LastItemData.StatusFlags = 0;
|
||||
}
|
||||
|
||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||
|
@ -502,7 +502,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
g.HoveredWindow = window;
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
if (id != 0 && window->DC.LastItemId != id)
|
||||
if (id != 0 && g.LastItemData.ID != id)
|
||||
IMGUI_TEST_ENGINE_ITEM_ADD(bb, id);
|
||||
#endif
|
||||
|
||||
@ -611,10 +611,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
}
|
||||
}
|
||||
|
||||
// Release active id if turning disabled
|
||||
if (g.ActiveId == id && (g.CurrentItemFlags & ImGuiItemFlags_Disabled))
|
||||
ClearActiveID();
|
||||
|
||||
// Process while held
|
||||
bool held = false;
|
||||
if (g.ActiveId == id)
|
||||
@ -684,8 +680,9 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (g.CurrentItemFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
@ -702,7 +699,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
||||
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -760,7 +757,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (g.CurrentItemFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
|
||||
bool hovered, held;
|
||||
@ -1085,7 +1082,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id))
|
||||
{
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1101,7 +1098,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
RenderNavHighlight(total_bb, id);
|
||||
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
|
||||
bool mixed_value = (g.CurrentItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
if (mixed_value)
|
||||
{
|
||||
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
||||
@ -1121,7 +1118,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(label_pos, label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -1223,7 +1220,7 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(label_pos, label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -1447,7 +1444,7 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
||||
bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
|
||||
ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
|
||||
if (hovered)
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb
|
||||
if (g.ActiveId != id)
|
||||
SetItemAllowOverlap();
|
||||
|
||||
@ -1705,9 +1702,9 @@ bool ImGui::BeginComboPreview()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
||||
|
||||
if (window->SkipItems || !window->ClipRect.Overlaps(window->DC.LastItemRect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result
|
||||
if (window->SkipItems || !window->ClipRect.Overlaps(g.LastItemData.Rect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result
|
||||
return false;
|
||||
IM_ASSERT(window->DC.LastItemRect.Min.x == preview_data->PreviewRect.Min.x && window->DC.LastItemRect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
|
||||
IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
|
||||
if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional)
|
||||
return false;
|
||||
|
||||
@ -1816,8 +1813,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
}
|
||||
|
||||
EndCombo();
|
||||
|
||||
if (value_changed)
|
||||
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
@ -2353,7 +2351,7 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
|
||||
}
|
||||
if (g.ActiveId != id)
|
||||
return false;
|
||||
if ((g.CurrentItemFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
|
||||
if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
|
||||
return false;
|
||||
|
||||
switch (data_type)
|
||||
@ -2407,7 +2405,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
const bool focus_requested = temp_input_allowed && (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_Focused) != 0;
|
||||
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
|
||||
const bool clicked = (hovered && g.IO.MouseClicked[0]);
|
||||
const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
|
||||
if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavInputId == id)
|
||||
@ -2456,7 +2454,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -2544,6 +2542,7 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
|
||||
TextEx(label, FindRenderedTextEnd(label));
|
||||
EndGroup();
|
||||
PopID();
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -2956,7 +2955,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
|
||||
IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.");
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
if ((g.CurrentItemFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
|
||||
if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
|
||||
return false;
|
||||
|
||||
switch (data_type)
|
||||
@ -3022,7 +3021,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
const bool focus_requested = temp_input_allowed && (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_Focused) != 0;
|
||||
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
|
||||
const bool clicked = (hovered && g.IO.MouseClicked[0]);
|
||||
if (focus_requested || clicked || g.NavActivateId == id || g.NavInputId == id)
|
||||
{
|
||||
@ -3067,7 +3066,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -3479,7 +3478,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, p_data, format);
|
||||
}
|
||||
if (value_changed)
|
||||
MarkItemEdited(window->DC.LastItemId);
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
@ -4013,8 +4012,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// We are only allowed to access the state if we are already the active widget.
|
||||
ImGuiInputTextState* state = GetInputTextState(id);
|
||||
|
||||
const bool focus_requested_by_code = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_FocusedByCode) != 0;
|
||||
const bool focus_requested_by_tabbing = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
const bool focus_requested_by_code = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByCode) != 0;
|
||||
const bool focus_requested_by_tabbing = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
|
||||
const bool user_clicked = hovered && io.MouseClicked[0];
|
||||
const bool user_nav_input_start = (g.ActiveId != id) && ((g.NavInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard));
|
||||
@ -4736,7 +4735,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (value_changed && !(flags & ImGuiInputTextFlags_NoMarkEdited))
|
||||
MarkItemEdited(id);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0)
|
||||
return enter_pressed;
|
||||
else
|
||||
@ -4919,7 +4918,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// Store current color and open a picker
|
||||
g.ColorPickerRef = col_v4;
|
||||
OpenPopup("picker");
|
||||
SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1, style.ItemSpacing.y));
|
||||
SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(-1, style.ItemSpacing.y));
|
||||
}
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
@ -4976,7 +4975,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
|
||||
// Drag and Drop Target
|
||||
// NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test.
|
||||
if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropTarget())
|
||||
if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropTarget())
|
||||
{
|
||||
bool accepted_drag_drop = false;
|
||||
if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
@ -4998,10 +4997,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
|
||||
// When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4().
|
||||
if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window)
|
||||
window->DC.LastItemId = g.ActiveId;
|
||||
g.LastItemData.ID = g.ActiveId;
|
||||
|
||||
if (value_changed)
|
||||
MarkItemEdited(window->DC.LastItemId);
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
@ -5397,7 +5396,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
if (value_changed && memcmp(backup_initial_col, col, components * sizeof(float)) == 0)
|
||||
value_changed = false;
|
||||
if (value_changed)
|
||||
MarkItemEdited(window->DC.LastItemId);
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
PopID();
|
||||
|
||||
@ -5830,14 +5829,14 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
window->DC.TreeJumpToParentOnPopMask |= (1 << window->DC.TreeDepth);
|
||||
|
||||
bool item_add = ItemAdd(interact_bb, id);
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDisplayRect;
|
||||
window->DC.LastItemDisplayRect = frame_bb;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect;
|
||||
g.LastItemData.DisplayRect = frame_bb;
|
||||
|
||||
if (!item_add)
|
||||
{
|
||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
TreePushOverrideID(id);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
return is_open;
|
||||
}
|
||||
|
||||
@ -5911,7 +5910,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
{
|
||||
is_open = !is_open;
|
||||
window->DC.StateStorage->SetInt(id, is_open);
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledOpen;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen;
|
||||
}
|
||||
}
|
||||
if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
|
||||
@ -5919,7 +5918,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
|
||||
// Render
|
||||
const ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
@ -5963,7 +5962,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
TreePushOverrideID(id);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
return is_open;
|
||||
}
|
||||
|
||||
@ -6067,14 +6066,14 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
|
||||
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
|
||||
// FIXME: CloseButton can overlap into text, need find a way to clip the text somehow.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiLastItemDataBackup last_item_backup;
|
||||
ImGuiLastItemData last_item_backup = g.LastItemData;
|
||||
float button_size = g.FontSize;
|
||||
float button_x = ImMax(window->DC.LastItemRect.Min.x, window->DC.LastItemRect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
|
||||
float button_y = window->DC.LastItemRect.Min.y;
|
||||
float button_x = ImMax(g.LastItemData.Rect.Min.x, g.LastItemData.Rect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
|
||||
float button_y = g.LastItemData.Rect.Min.y;
|
||||
ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id);
|
||||
if (CloseButton(close_button_id, ImVec2(button_x, button_y)))
|
||||
*p_visible = false;
|
||||
last_item_backup.Restore();
|
||||
g.LastItemData = last_item_backup;
|
||||
}
|
||||
|
||||
return is_open;
|
||||
@ -6167,7 +6166,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
return false;
|
||||
|
||||
const bool disabled_global = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
||||
if (disabled_item && !disabled_global)
|
||||
if (disabled_item && !disabled_global) // Only testing this as an optimization
|
||||
PushDisabled(true);
|
||||
|
||||
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
||||
@ -6217,7 +6216,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
|
||||
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
|
||||
// Render
|
||||
if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld))
|
||||
@ -6237,13 +6236,13 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
|
||||
// Automatically close popups
|
||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.LastItemData.InFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
||||
CloseCurrentPopup();
|
||||
|
||||
if (disabled_item && !disabled_global)
|
||||
PopDisabled();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -6376,8 +6375,9 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
|
||||
PopID();
|
||||
}
|
||||
EndListBox();
|
||||
|
||||
if (value_changed)
|
||||
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
@ -6596,6 +6596,7 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
|
||||
// - EndMainMenuBar()
|
||||
// - BeginMenu()
|
||||
// - EndMenu()
|
||||
// - MenuItemEx() [Internal]
|
||||
// - MenuItem()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@ -6869,7 +6870,6 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
}
|
||||
if (!enabled)
|
||||
PopDisabled();
|
||||
PopID();
|
||||
|
||||
const bool hovered = (g.HoveredId == id) && enabled;
|
||||
if (menuset_is_open)
|
||||
@ -6943,7 +6943,8 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||
ClosePopupToLevel(g.BeginPopupStack.Size, true);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
PopID();
|
||||
|
||||
if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
|
||||
{
|
||||
@ -7039,11 +7040,11 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
if (selected)
|
||||
RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
}
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||
if (!enabled)
|
||||
PopDisabled();
|
||||
PopID();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -7905,7 +7906,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
|
||||
// If the user called us with *p_open == false, we early out and don't render.
|
||||
// We make a call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID.
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
if (p_open && !*p_open)
|
||||
{
|
||||
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);
|
||||
@ -8282,12 +8283,12 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
|
||||
if (close_button_visible)
|
||||
{
|
||||
ImGuiLastItemDataBackup last_item_backup;
|
||||
ImGuiLastItemData last_item_backup = g.LastItemData;
|
||||
PushStyleVar(ImGuiStyleVar_FramePadding, frame_padding);
|
||||
if (CloseButton(close_button_id, button_pos))
|
||||
close_button_pressed = true;
|
||||
PopStyleVar();
|
||||
last_item_backup.Restore();
|
||||
g.LastItemData = last_item_backup;
|
||||
|
||||
// Close with middle mouse button
|
||||
if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2))
|
||||
|
Loading…
Reference in New Issue
Block a user