|
|
@@ -376,6 +376,9 @@ CODE
|
|
|
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
|
|
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
|
|
|
|
|
+ - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
|
|
|
+ - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
|
|
|
+ - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
|
|
|
- 2021/05/19 (1.83) - backends: obsoleted direct access to ImDrawCmd::TextureId in favor of calling ImDrawCmd::GetTexID().
|
|
|
- if you are using official backends from the source tree: you have nothing to do.
|
|
|
- if you have copied old backend code or using your own: change access to draw_cmd->TextureId to draw_cmd->GetTexID().
|
|
|
@@ -396,7 +399,7 @@ CODE
|
|
|
- ImGui::SetScrollHere() -> use ImGui::SetScrollHereY()
|
|
|
- 2021/03/11 (1.82) - clarified that ImDrawList::PathArcTo(), ImDrawList::PathArcToFast() won't render with radius < 0.0f. Previously it sorts of accidentally worked but would generally lead to counter-clockwise paths and have an effect on anti-aliasing.
|
|
|
- 2021/03/10 (1.82) - upgraded ImDrawList::AddPolyline() and PathStroke() "bool closed" parameter to "ImDrawFlags flags". The matching ImDrawFlags_Closed value is guaranteed to always stay == 1 in the future.
|
|
|
- - 2021/02/22 (1.82) - win32+mingw: Re-enabled IME functions by default even under MinGW. In July 2016, issue #738 had me incorrectly disable those default functions for MinGW. MinGW users should: either link with -limm32, either set their imconfig file with '#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS'.
|
|
|
+ - 2021/02/22 (1.82) - (*undone in 1.84*) win32+mingw: Re-enabled IME functions by default even under MinGW. In July 2016, issue #738 had me incorrectly disable those default functions for MinGW. MinGW users should: either link with -limm32, either set their imconfig file with '#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS'.
|
|
|
- 2021/02/17 (1.82) - renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) to style.CircleTessellationMaxError (new default = 0.30f) as the meaning of the value changed.
|
|
|
- 2021/02/03 (1.81) - renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox(). Kept inline redirection function (will obsolete).
|
|
|
- removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size. Kept inline redirection function (will obsolete).
|
|
|
@@ -785,6 +788,11 @@ CODE
|
|
|
#include <stdint.h> // intptr_t
|
|
|
#endif
|
|
|
|
|
|
+// [Windows] On non-Visual Studio compilers, we default to IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS unless explicitly enabled
|
|
|
+#if defined(_WIN32) && !defined(_MSC_VER) && !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)
|
|
|
+#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
|
|
|
+#endif
|
|
|
+
|
|
|
// [Windows] OS specific includes (optional)
|
|
|
#if defined(_WIN32) && defined(IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
|
|
|
#define IMGUI_DISABLE_WIN32_FUNCTIONS
|
|
|
@@ -1067,7 +1075,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;
|
|
|
@@ -2788,7 +2796,7 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
|
|
|
int ellipsis_char_count = 1;
|
|
|
if (ellipsis_char == (ImWchar)-1)
|
|
|
{
|
|
|
- ellipsis_char = (ImWchar)'.';
|
|
|
+ ellipsis_char = font->DotChar;
|
|
|
ellipsis_char_count = 3;
|
|
|
}
|
|
|
const ImFontGlyph* glyph = font->FindGlyph(ellipsis_char);
|
|
|
@@ -2929,8 +2937,7 @@ ImGuiWindow::~ImGuiWindow()
|
|
|
{
|
|
|
IM_ASSERT(DrawList == &DrawListInst);
|
|
|
IM_DELETE(Name);
|
|
|
- for (int i = 0; i != ColumnsStorage.Size; i++)
|
|
|
- ColumnsStorage[i].~ImGuiOldColumns();
|
|
|
+ ColumnsStorage.clear_destruct();
|
|
|
}
|
|
|
|
|
|
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
|
|
@@ -3130,7 +3137,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)
|
|
|
@@ -3160,10 +3167,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
|
|
|
@@ -3179,7 +3190,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.
|
|
|
@@ -3188,12 +3199,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->MoveId && window->WriteAccessed)
|
|
|
+ if (g.LastItemData.ID == window->MoveId && window->WriteAccessed)
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
@@ -3214,7 +3225,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|
|
return false;
|
|
|
if (g.NavDisableMouseHover)
|
|
|
return false;
|
|
|
- if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (g.CurrentItemFlags & ImGuiItemFlags_Disabled))
|
|
|
+ if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
|
|
{
|
|
|
g.HoveredIdDisabled = true;
|
|
|
return false;
|
|
|
@@ -3223,9 +3234,21 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|
|
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
|
|
|
// hover test in widgets code. We could also decide to split this function is two.
|
|
|
if (id != 0)
|
|
|
- {
|
|
|
SetHoveredID(id);
|
|
|
|
|
|
+ // When disabled we'll return false but still set HoveredId
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id != 0)
|
|
|
+ {
|
|
|
// [DEBUG] Item Picker tool!
|
|
|
// We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
|
|
|
// the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered
|
|
|
@@ -3251,24 +3274,16 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-// 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)
|
|
|
-{
|
|
|
- window->DC.LastItemId = item_id;
|
|
|
- window->DC.LastItemStatusFlags = item_flags;
|
|
|
- window->DC.LastItemRect = 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)
|
|
|
{
|
|
|
@@ -3290,13 +3305,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;
|
|
|
}
|
|
|
|
|
|
@@ -3529,8 +3544,9 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
|
|
|
FocusWindow(window);
|
|
|
SetActiveID(window->MoveId, window);
|
|
|
g.NavDisableHighlight = true;
|
|
|
+ g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - window->RootWindow->Pos;
|
|
|
g.ActiveIdNoClearOnFocusLoss = true;
|
|
|
- g.ActiveIdClickOffset = g.IO.MousePos - window->RootWindow->Pos;
|
|
|
+ SetActiveIdUsingNavAndKeys();
|
|
|
|
|
|
bool can_move_window = true;
|
|
|
if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindow->Flags & ImGuiWindowFlags_NoMove))
|
|
|
@@ -3566,8 +3582,8 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ClearActiveID();
|
|
|
g.MovingWindow = NULL;
|
|
|
+ ClearActiveID();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -4091,7 +4107,6 @@ void ImGui::NewFrame()
|
|
|
g.ItemFlagsStack.resize(0);
|
|
|
g.ItemFlagsStack.push_back(ImGuiItemFlags_None);
|
|
|
g.GroupStack.resize(0);
|
|
|
- ClosePopupsOverWindow(g.NavWindow, false);
|
|
|
|
|
|
// [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
|
|
|
UpdateDebugToolItemPicker();
|
|
|
@@ -4158,7 +4173,7 @@ void ImGui::Initialize(ImGuiContext* context)
|
|
|
g.Viewports.push_back(viewport);
|
|
|
|
|
|
#ifdef IMGUI_HAS_DOCK
|
|
|
-#endif // #ifdef IMGUI_HAS_DOCK
|
|
|
+#endif
|
|
|
|
|
|
g.Initialized = true;
|
|
|
}
|
|
|
@@ -4191,9 +4206,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|
|
CallContextHooks(&g, ImGuiContextHookType_Shutdown);
|
|
|
|
|
|
// Clear everything else
|
|
|
- for (int i = 0; i < g.Windows.Size; i++)
|
|
|
- IM_DELETE(g.Windows[i]);
|
|
|
- g.Windows.clear();
|
|
|
+ g.Windows.clear_delete();
|
|
|
g.WindowsFocusOrder.clear();
|
|
|
g.WindowsTempSortBuffer.clear();
|
|
|
g.CurrentWindow = NULL;
|
|
|
@@ -4209,18 +4222,14 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|
|
g.OpenPopupStack.clear();
|
|
|
g.BeginPopupStack.clear();
|
|
|
|
|
|
- for (int i = 0; i < g.Viewports.Size; i++)
|
|
|
- IM_DELETE(g.Viewports[i]);
|
|
|
- g.Viewports.clear();
|
|
|
+ g.Viewports.clear_delete();
|
|
|
|
|
|
g.TabBars.Clear();
|
|
|
g.CurrentTabBarStack.clear();
|
|
|
g.ShrinkWidthBuffer.clear();
|
|
|
|
|
|
g.Tables.Clear();
|
|
|
- for (int i = 0; i < g.TablesTempDataStack.Size; i++)
|
|
|
- g.TablesTempDataStack[i].~ImGuiTableTempData();
|
|
|
- g.TablesTempDataStack.clear();
|
|
|
+ g.TablesTempDataStack.clear_destruct();
|
|
|
g.DrawChannelsTempMergeBuffer.clear();
|
|
|
|
|
|
g.ClipboardHandlerData.clear();
|
|
|
@@ -4468,6 +4477,9 @@ void ImGui::EndFrame()
|
|
|
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
|
|
|
}
|
|
|
|
|
|
+// Prepare the data for rendering so you can call GetDrawData()
|
|
|
+// (As with anything within the ImGui:: namspace this doesn't touch your GPU or graphics API at all:
|
|
|
+// it is the role of the ImGui_ImplXXXX_RenderDrawData() function provided by the renderer backend)
|
|
|
void ImGui::Render()
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
@@ -4841,10 +4853,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;
|
|
|
}
|
|
|
|
|
|
@@ -4852,21 +4861,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()
|
|
|
@@ -4879,9 +4884,7 @@ 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;
|
|
|
return true;
|
|
|
}
|
|
|
@@ -4896,13 +4899,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()
|
|
|
@@ -4925,14 +4928,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.
|
|
|
@@ -4940,7 +4943,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)
|
|
|
@@ -4950,29 +4953,39 @@ 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)
|
|
|
g.ActiveIdUsingMouseWheel = true;
|
|
|
}
|
|
|
|
|
|
+void ImGui::SetActiveIdUsingNavAndKeys()
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ IM_ASSERT(g.ActiveId != 0);
|
|
|
+ g.ActiveIdUsingNavDirMask = ~(ImU32)0;
|
|
|
+ g.ActiveIdUsingNavInputMask = ~(ImU32)0;
|
|
|
+ g.ActiveIdUsingKeyInputMask = ~(ImU64)0;
|
|
|
+ NavMoveRequestCancel();
|
|
|
+}
|
|
|
+
|
|
|
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)
|
|
|
@@ -5077,7 +5090,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
|
|
|
@@ -5675,8 +5688,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|
|
|
|
|
// Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
|
|
|
// FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code..
|
|
|
- const char* UNSAVED_DOCUMENT_MARKER = "*";
|
|
|
- const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? CalcTextSize(UNSAVED_DOCUMENT_MARKER, NULL, false).x : 0.0f;
|
|
|
+ const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? button_sz * 0.80f : 0.0f;
|
|
|
const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
|
|
|
|
|
|
// As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button,
|
|
|
@@ -5695,15 +5707,20 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|
|
|
|
|
ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y);
|
|
|
ImRect clip_r(layout_r.Min.x, layout_r.Min.y, ImMin(layout_r.Max.x + g.Style.ItemInnerSpacing.x, title_bar_rect.Max.x), layout_r.Max.y);
|
|
|
- //if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
|
|
- //if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
|
|
- RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r);
|
|
|
if (flags & ImGuiWindowFlags_UnsavedDocument)
|
|
|
{
|
|
|
- ImVec2 marker_pos = ImVec2(ImMax(layout_r.Min.x, layout_r.Min.x + (layout_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x) + text_size.x, layout_r.Min.y) + ImVec2(2 - marker_size_x, 0.0f);
|
|
|
- ImVec2 off = ImVec2(0.0f, IM_FLOOR(-g.FontSize * 0.25f));
|
|
|
- RenderTextClipped(marker_pos + off, layout_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_r);
|
|
|
+ ImVec2 marker_pos;
|
|
|
+ marker_pos.x = ImClamp(layout_r.Min.x + (layout_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x + text_size.x, layout_r.Min.x, layout_r.Max.x);
|
|
|
+ marker_pos.y = (layout_r.Min.y + layout_r.Max.y) * 0.5f;
|
|
|
+ if (marker_pos.x > layout_r.Min.x)
|
|
|
+ {
|
|
|
+ RenderBullet(window->DrawList, marker_pos, GetColorU32(ImGuiCol_Text));
|
|
|
+ clip_r.Max.x = ImMin(clip_r.Max.x, marker_pos.x - (int)(marker_size_x * 0.5f));
|
|
|
+ }
|
|
|
}
|
|
|
+ //if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
|
|
+ //if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
|
|
+ RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r);
|
|
|
}
|
|
|
|
|
|
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
|
|
|
@@ -5780,7 +5797,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 = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
|
|
|
+ ImGuiWindow* parent_window_in_stack = 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));
|
|
|
|
|
|
@@ -5790,7 +5807,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;
|
|
|
@@ -6257,7 +6277,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
|
|
|
|
|
|
window->DC.MenuBarAppending = false;
|
|
|
- window->DC.MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user);
|
|
|
+ window->DC.MenuColumns.Update(style.ItemSpacing.x, window_just_activated_by_user);
|
|
|
window->DC.TreeDepth = 0;
|
|
|
window->DC.TreeJumpToParentOnPopMask = 0x00;
|
|
|
window->DC.ChildWindows.resize(0);
|
|
|
@@ -6303,11 +6323,14 @@ 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.
|
|
|
- SetLastItemData(window, window->MoveId, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect);
|
|
|
+ g.LastItemData.ID = window->MoveId;
|
|
|
+ g.LastItemData.InFlags = g.CurrentItemFlags;
|
|
|
+ g.LastItemData.StatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
|
|
|
+ g.LastItemData.Rect = 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
|
|
|
@@ -6317,8 +6340,7 @@ 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 : 0; // Inherit from parent only // -V595
|
|
|
+ window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetID("#FOCUSSCOPE"); // Inherit from parent only // -V595
|
|
|
|
|
|
PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
|
|
|
|
|
|
@@ -6399,11 +6421,12 @@ void ImGui::End()
|
|
|
LogFinish();
|
|
|
|
|
|
// 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);
|
|
|
}
|
|
|
|
|
|
void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
|
|
|
@@ -6577,6 +6600,31 @@ void ImGui::PopItemFlag()
|
|
|
g.CurrentItemFlags = g.ItemFlagsStack.back();
|
|
|
}
|
|
|
|
|
|
+// PushDisabled()/PopDisabled()
|
|
|
+// - Those can be nested but this cannot be used to enable an already disabled section (a single PushDisabled(true) in the stack is enough to keep things disabled)
|
|
|
+// - Those are not yet exposed in imgui.h because we are unsure of how to alter the style in a way that works for everyone.
|
|
|
+// We may rework this. Hypothetically, a future styling system may set a flag which make widgets use different colors.
|
|
|
+// - Feedback welcome at https://github.com/ocornut/imgui/issues/211
|
|
|
+// - You may trivially implement your own variation of this if needed.
|
|
|
+// Here we test (CurrentItemFlags & ImGuiItemFlags_Disabled) to allow nested PushDisabled() calls.
|
|
|
+void ImGui::PushDisabled(bool disabled)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
|
+ if (!was_disabled && disabled)
|
|
|
+ PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.6f);
|
|
|
+ PushItemFlag(ImGuiItemFlags_Disabled, was_disabled || disabled);
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui::PopDisabled()
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
|
+ PopItemFlag();
|
|
|
+ if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0)
|
|
|
+ PopStyleVar();
|
|
|
+}
|
|
|
+
|
|
|
// FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system.
|
|
|
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
|
|
|
{
|
|
|
@@ -7004,8 +7052,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();
|
|
|
@@ -7156,8 +7204,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
|
|
|
IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
|
|
|
IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
|
|
|
IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
|
|
|
- IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
|
|
|
- IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
|
|
|
+ IM_ASSERT(g.IO.Fonts->IsBuilt() && "Font Atlas not built! Make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()");
|
|
|
IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!");
|
|
|
IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!");
|
|
|
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations
|
|
|
@@ -7401,9 +7448,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
|
|
|
@@ -7427,11 +7481,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
|
|
|
@@ -7452,7 +7501,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;
|
|
|
}
|
|
|
|
|
|
@@ -7784,24 +7833,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]
|
|
|
@@ -7990,7 +8039,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
|
|
|
@@ -8386,12 +8435,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);
|
|
|
}
|
|
|
}
|
|
|
@@ -8414,11 +8464,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);
|
|
|
@@ -8427,7 +8478,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);
|
|
|
@@ -8440,7 +8492,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);
|
|
|
@@ -8551,7 +8604,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
|
|
// Child menus typically request _any_ position within the parent menu item, and then we move the new menu outside the parent bounds.
|
|
|
// This is how we end up with child menus appearing (most-commonly) on the right of the parent menu.
|
|
|
IM_ASSERT(g.CurrentWindow == window);
|
|
|
- ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2];
|
|
|
+ ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2].Window;
|
|
|
float horizontal_overlap = g.Style.ItemInnerSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x).
|
|
|
ImRect r_avoid;
|
|
|
if (parent_window->DC.MenuBarAppending)
|
|
|
@@ -8615,8 +8668,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;
|
|
|
@@ -8713,7 +8766,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
|
|
|
@@ -8801,19 +8854,20 @@ 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
|
|
|
if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent)
|
|
|
{
|
|
|
// Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback
|
|
|
- if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus) || g.NavInitResultId == 0)
|
|
|
+ const bool candidate_for_nav_default_focus = (item_flags & (ImGuiItemFlags_NoNavDefaultFocus | ImGuiItemFlags_Disabled)) == 0;
|
|
|
+ if (candidate_for_nav_default_focus || g.NavInitResultId == 0)
|
|
|
{
|
|
|
g.NavInitResultId = id;
|
|
|
g.NavInitResultRectRel = nav_bb_rel;
|
|
|
}
|
|
|
- if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus))
|
|
|
+ if (candidate_for_nav_default_focus)
|
|
|
{
|
|
|
g.NavInitRequest = false; // Found a match, clear request
|
|
|
NavUpdateAnyRequestFlag();
|
|
|
@@ -9589,7 +9643,7 @@ static void ImGui::NavUpdateWindowing()
|
|
|
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
|
|
|
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
|
|
|
{
|
|
|
- g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // FIXME-DOCK: Will need to use RootWindowDockStop
|
|
|
+ g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow;
|
|
|
g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
|
|
|
g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true;
|
|
|
g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
|
|
|
@@ -9795,7 +9849,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
|
|
|
@@ -9822,15 +9876,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);
|
|
|
@@ -9844,10 +9899,8 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
|
|
source_parent_id = window->IDStack.back();
|
|
|
source_drag_active = IsMouseDragging(mouse_button);
|
|
|
|
|
|
- // Disable navigation and key inputs while dragging
|
|
|
- g.ActiveIdUsingNavDirMask = ~(ImU32)0;
|
|
|
- g.ActiveIdUsingNavInputMask = ~(ImU32)0;
|
|
|
- g.ActiveIdUsingKeyInputMask = ~(ImU64)0;
|
|
|
+ // Disable navigation and key inputs while dragging + cancel existing request if any
|
|
|
+ SetActiveIdUsingNavAndKeys();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -9888,7 +9941,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;
|
|
|
}
|
|
|
@@ -9988,14 +10041,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->RootWindow != hovered_window->RootWindow)
|
|
|
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)
|
|
|
@@ -10037,17 +10090,11 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|
|
}
|
|
|
|
|
|
// Render default drop visuals
|
|
|
+ // FIXME-DRAGDROP: Settle on a proper default visuals for drop target.
|
|
|
payload.Preview = was_accepted_previously;
|
|
|
flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame)
|
|
|
if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview)
|
|
|
- {
|
|
|
- // FIXME-DRAGDROP: Settle on a proper default visuals for drop target.
|
|
|
- r.Expand(3.5f);
|
|
|
- bool push_clip_rect = !window->ClipRect.Contains(r);
|
|
|
- if (push_clip_rect) window->DrawList->PushClipRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1));
|
|
|
- window->DrawList->AddRect(r.Min, r.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f);
|
|
|
- if (push_clip_rect) window->DrawList->PopClipRect();
|
|
|
- }
|
|
|
+ window->DrawList->AddRect(r.Min - ImVec2(3.5f,3.5f), r.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f);
|
|
|
|
|
|
g.DragDropAcceptFrameCount = g.FrameCount;
|
|
|
payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased()
|
|
|
@@ -10609,8 +10656,9 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
|
|
|
window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
|
|
|
}
|
|
|
IM_ASSERT(settings->ID == window->ID);
|
|
|
- settings->Pos = ImVec2ih((short)window->Pos.x, (short)window->Pos.y);
|
|
|
- settings->Size = ImVec2ih((short)window->SizeFull.x, (short)window->SizeFull.y);
|
|
|
+ settings->Pos = ImVec2ih(window->Pos);
|
|
|
+ settings->Size = ImVec2ih(window->SizeFull);
|
|
|
+
|
|
|
settings->Collapsed = window->Collapsed;
|
|
|
}
|
|
|
|
|
|
@@ -11214,7 +11262,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
Indent();
|
|
|
Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
|
|
|
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
|
- Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|
|
|
+ Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %llX", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, g.ActiveIdUsingKeyInputMask);
|
|
|
+ Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
|
|
|
Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize);
|
|
|
Unindent();
|
|
|
|
|
|
@@ -11566,7 +11615,14 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label)
|
|
|
const char* buf_end = buf + IM_ARRAYSIZE(buf);
|
|
|
const bool is_active = (tab_bar->PrevFrameVisible >= GetFrameCount() - 2);
|
|
|
p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*");
|
|
|
- IM_UNUSED(p);
|
|
|
+ p += ImFormatString(p, buf_end - p, " { ");
|
|
|
+ for (int tab_n = 0; tab_n < ImMin(tab_bar->Tabs.Size, 3); tab_n++)
|
|
|
+ {
|
|
|
+ ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
|
|
|
+ p += ImFormatString(p, buf_end - p, "%s'%s'",
|
|
|
+ tab_n > 0 ? ", " : "", (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???");
|
|
|
+ }
|
|
|
+ p += ImFormatString(p, buf_end - p, (tab_bar->Tabs.Size > 3) ? " ... }" : " } ");
|
|
|
if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); }
|
|
|
bool open = TreeNode(label, "%s", buf);
|
|
|
if (!is_active) { PopStyleColor(); }
|
|
|
@@ -11586,7 +11642,7 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label)
|
|
|
if (SmallButton("<")) { TabBarQueueReorder(tab_bar, tab, -1); } SameLine(0, 2);
|
|
|
if (SmallButton(">")) { TabBarQueueReorder(tab_bar, tab, +1); } SameLine();
|
|
|
Text("%02d%c Tab 0x%08X '%s' Offset: %.1f, Width: %.1f/%.1f",
|
|
|
- tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "", tab->Offset, tab->Width, tab->ContentWidth);
|
|
|
+ tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???", tab->Offset, tab->Width, tab->ContentWidth);
|
|
|
PopID();
|
|
|
}
|
|
|
TreePop();
|