mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-05 04:28:47 +02:00
Merge branch 'master' into docking
# Conflicts: # imgui.cpp # imgui_internal.h
This commit is contained in:
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
|
||||
|
Reference in New Issue
Block a user