mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated ImGui.
This commit is contained in:
312
3rdparty/dear-imgui/imgui.cpp
vendored
312
3rdparty/dear-imgui/imgui.cpp
vendored
@@ -1,14 +1,14 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
// - Read FAQ at http://dearimgui.org/faq
|
||||
// - Read FAQ at http://dearimgui.com/faq
|
||||
// - Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase.
|
||||
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
|
||||
// Read imgui.cpp for details, links and comments.
|
||||
|
||||
// Resources:
|
||||
// - FAQ http://dearimgui.org/faq
|
||||
// - FAQ http://dearimgui.com/faq
|
||||
// - Homepage & latest https://github.com/ocornut/imgui
|
||||
// - Releases & changelog https://github.com/ocornut/imgui/releases
|
||||
// - Gallery https://github.com/ocornut/imgui/issues/5886 (please post your screenshots/video there!)
|
||||
@@ -48,7 +48,7 @@ DOCUMENTATION
|
||||
- HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
||||
- API BREAKING CHANGES (read me when you update!)
|
||||
- FREQUENTLY ASKED QUESTIONS (FAQ)
|
||||
- Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
|
||||
- Read all answers online: https://www.dearimgui.com/faq, or in docs/FAQ.md (with a Markdown viewer)
|
||||
|
||||
CODE
|
||||
(search for "[SECTION]" in the code to find them)
|
||||
@@ -159,7 +159,7 @@ CODE
|
||||
- GAMEPAD CONTROLS
|
||||
- Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
- Particularly useful to use Dear ImGui on a console system (e.g. PlayStation, Switch, Xbox) without a mouse!
|
||||
- Download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets
|
||||
- Download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets
|
||||
- Backend support: backend needs to:
|
||||
- Set 'io.BackendFlags |= ImGuiBackendFlags_HasGamepad' + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys.
|
||||
- For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly.
|
||||
@@ -286,7 +286,7 @@ CODE
|
||||
// Build and load the texture atlas into a texture
|
||||
// (In the examples/ app this is usually done within the ImGui_ImplXXX_Init() function from one of the demo Renderer)
|
||||
int width, height;
|
||||
unsigned char* pixels = NULL;
|
||||
unsigned char* pixels = nullptr;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// At this point you've got the texture data and you need to upload that to your graphic system:
|
||||
@@ -783,7 +783,7 @@ CODE
|
||||
================================
|
||||
|
||||
Read all answers online:
|
||||
https://www.dearimgui.org/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url)
|
||||
https://www.dearimgui.com/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url)
|
||||
Read all answers locally (with a text editor or ideally a Markdown viewer):
|
||||
docs/FAQ.md
|
||||
Some answers are copied down here to facilitate searching in code.
|
||||
@@ -807,7 +807,7 @@ CODE
|
||||
Q: What is this library called?
|
||||
Q: Which version should I get?
|
||||
>> This library is called "Dear ImGui", please don't call it "ImGui" :)
|
||||
>> See https://www.dearimgui.org/faq for details.
|
||||
>> See https://www.dearimgui.com/faq for details.
|
||||
|
||||
Q&A: Integration
|
||||
================
|
||||
@@ -817,14 +817,14 @@ CODE
|
||||
|
||||
Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?
|
||||
A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
|
||||
>> See https://www.dearimgui.org/faq for a fully detailed answer. You really want to read this.
|
||||
>> See https://www.dearimgui.com/faq for a fully detailed answer. You really want to read this.
|
||||
|
||||
Q. How can I enable keyboard controls?
|
||||
Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
|
||||
Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
|
||||
Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...
|
||||
Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...
|
||||
>> See https://www.dearimgui.org/faq
|
||||
>> See https://www.dearimgui.com/faq
|
||||
|
||||
Q&A: Usage
|
||||
----------
|
||||
@@ -838,7 +838,7 @@ CODE
|
||||
Q: How can I use my own math types instead of ImVec2/ImVec4?
|
||||
Q: How can I interact with standard C++ types (such as std::string and std::vector)?
|
||||
Q: How can I display custom shapes? (using low-level ImDrawList API)
|
||||
>> See https://www.dearimgui.org/faq
|
||||
>> See https://www.dearimgui.com/faq
|
||||
|
||||
Q&A: Fonts, Text
|
||||
================
|
||||
@@ -848,7 +848,7 @@ CODE
|
||||
Q: How can I easily use icons in my application?
|
||||
Q: How can I load multiple fonts?
|
||||
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
||||
>> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md
|
||||
>> See https://www.dearimgui.com/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md
|
||||
|
||||
Q&A: Concerns
|
||||
=============
|
||||
@@ -857,7 +857,7 @@ CODE
|
||||
Q: Can you create elaborate/serious tools with Dear ImGui?
|
||||
Q: Can you reskin the look of Dear ImGui?
|
||||
Q: Why using C++ (as opposed to C)?
|
||||
>> See https://www.dearimgui.org/faq
|
||||
>> See https://www.dearimgui.com/faq
|
||||
|
||||
Q&A: Community
|
||||
==============
|
||||
@@ -1058,7 +1058,6 @@ static void RenderWindowDecorations(ImGuiWindow* window, const ImRec
|
||||
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||||
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
||||
static void RenderDimmedBackgrounds();
|
||||
static ImGuiWindow* FindBlockingModal(ImGuiWindow* window);
|
||||
|
||||
// Viewports
|
||||
static void UpdateViewportsNewFrame();
|
||||
@@ -1248,6 +1247,7 @@ ImGuiIO::ImGuiIO()
|
||||
// Input (NB: we already have memset zero the entire structure!)
|
||||
MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
MouseSource = ImGuiMouseSource_Mouse;
|
||||
MouseDragThreshold = 6.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
|
||||
@@ -1270,6 +1270,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_Text;
|
||||
e.Source = ImGuiInputSource_Keyboard;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.Text.Char = c;
|
||||
g.InputEventsQueue.push_back(e);
|
||||
}
|
||||
@@ -1408,6 +1409,7 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_Key;
|
||||
e.Source = ImGui::IsGamepadKey(key) ? ImGuiInputSource_Gamepad : ImGuiInputSource_Keyboard;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.Key.Key = key;
|
||||
e.Key.Down = down;
|
||||
e.Key.AnalogValue = analog_value;
|
||||
@@ -1472,8 +1474,10 @@ void ImGuiIO::AddMousePosEvent(float x, float y)
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_MousePos;
|
||||
e.Source = ImGuiInputSource_Mouse;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.MousePos.PosX = pos.x;
|
||||
e.MousePos.PosY = pos.y;
|
||||
e.MouseWheel.MouseSource = g.InputEventsNextMouseSource;
|
||||
g.InputEventsQueue.push_back(e);
|
||||
}
|
||||
|
||||
@@ -1494,8 +1498,10 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_MouseButton;
|
||||
e.Source = ImGuiInputSource_Mouse;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.MouseButton.Button = mouse_button;
|
||||
e.MouseButton.Down = down;
|
||||
e.MouseWheel.MouseSource = g.InputEventsNextMouseSource;
|
||||
g.InputEventsQueue.push_back(e);
|
||||
}
|
||||
|
||||
@@ -1512,11 +1518,22 @@ void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y)
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_MouseWheel;
|
||||
e.Source = ImGuiInputSource_Mouse;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.MouseWheel.WheelX = wheel_x;
|
||||
e.MouseWheel.WheelY = wheel_y;
|
||||
e.MouseWheel.MouseSource = g.InputEventsNextMouseSource;
|
||||
g.InputEventsQueue.push_back(e);
|
||||
}
|
||||
|
||||
// This is not a real event, the data is latched in order to be stored in actual Mouse events.
|
||||
// This is so that duplicate events (e.g. Windows sending extraneous WM_MOUSEMOVE) gets filtered and are not leading to actual source changes.
|
||||
void ImGuiIO::AddMouseSourceEvent(ImGuiMouseSource source)
|
||||
{
|
||||
IM_ASSERT(Ctx != NULL);
|
||||
ImGuiContext& g = *Ctx;
|
||||
g.InputEventsNextMouseSource = source;
|
||||
}
|
||||
|
||||
void ImGuiIO::AddFocusEvent(bool focused)
|
||||
{
|
||||
IM_ASSERT(Ctx != NULL);
|
||||
@@ -1530,6 +1547,7 @@ void ImGuiIO::AddFocusEvent(bool focused)
|
||||
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_Focus;
|
||||
e.EventId = g.InputEventsNextEventId++;
|
||||
e.AppFocused.Focused = focused;
|
||||
g.InputEventsQueue.push_back(e);
|
||||
}
|
||||
@@ -3238,6 +3256,9 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
|
||||
|
||||
// Default clip_rect uses (pos_min,pos_max)
|
||||
// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
||||
// FIXME-OPT: Since we have or calculate text_size we could coarse clip whole block immediately, especally for text above draw_list->DrawList.
|
||||
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
|
||||
// better advantage of the render function taking size into account for coarse clipping.
|
||||
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||
{
|
||||
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
||||
@@ -3723,7 +3744,10 @@ static void SetCurrentWindow(ImGuiWindow* window)
|
||||
g.CurrentWindow = window;
|
||||
g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL;
|
||||
if (window)
|
||||
{
|
||||
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
|
||||
ImGui::NavUpdateCurrentWindowIsScrollPushableX();
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::GcCompactTransientMiscBuffers()
|
||||
@@ -3888,7 +3912,7 @@ bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flag
|
||||
|
||||
// Inhibit hover unless the window is within the stack of our modal/popup
|
||||
if (want_inhibit)
|
||||
if (!ImGui::IsWindowWithinBeginStackOf(window->RootWindow, focused_root_window))
|
||||
if (!IsWindowWithinBeginStackOf(window->RootWindow, focused_root_window))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -4273,10 +4297,10 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
if (g.HoveredIdDisabled)
|
||||
g.MovingWindow = NULL;
|
||||
}
|
||||
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||
else if (root_window == NULL && g.NavWindow != NULL)
|
||||
{
|
||||
// Clicking on void disable focus
|
||||
FocusWindow(NULL);
|
||||
FocusWindow(NULL, ImGuiFocusRequestFlags_UnlessBelowModal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4601,7 +4625,7 @@ void ImGui::NewFrame()
|
||||
|
||||
// Closing the focused window restore focus to the first active root window in descending z-order
|
||||
if (g.NavWindow && !g.NavWindow->WasActive)
|
||||
FocusTopMostWindowUnderOne(NULL, NULL);
|
||||
FocusTopMostWindowUnderOne(NULL, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild);
|
||||
|
||||
// No window should be open at the beginning of the frame.
|
||||
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
|
||||
@@ -5292,7 +5316,8 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
||||
parent_window->DC.CursorPos = child_window->Pos;
|
||||
|
||||
// Process navigation-in immediately so NavInit can run on first frame
|
||||
if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavHasScroll))
|
||||
// Can enter a child if (A) it has navigatable items or (B) it can be scrolled.
|
||||
if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
|
||||
{
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
@@ -5339,7 +5364,7 @@ void ImGui::EndChild()
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
|
||||
ItemSize(sz);
|
||||
if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened))
|
||||
if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavWindowHasScrollY) && !(window->Flags & ImGuiWindowFlags_NavFlattened))
|
||||
{
|
||||
ItemAdd(bb, window->ChildId);
|
||||
RenderNavHighlight(bb, window->ChildId);
|
||||
@@ -5352,6 +5377,10 @@ void ImGui::EndChild()
|
||||
{
|
||||
// Not navigable into
|
||||
ItemAdd(bb, 0);
|
||||
|
||||
// But when flattened we directly reach items, adjust active layer mask accordingly
|
||||
if (window->Flags & ImGuiWindowFlags_NavFlattened)
|
||||
parent_window->DC.NavLayersActiveMaskNext |= window->DC.NavLayersActiveMaskNext;
|
||||
}
|
||||
if (g.HoveredWindow == window)
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
@@ -6053,7 +6082,10 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags
|
||||
// - Window // .. returns Modal2
|
||||
// - Window // .. returns Modal2
|
||||
// - Modal2 // .. returns Modal2
|
||||
static ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
|
||||
// Notes:
|
||||
// - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL.
|
||||
// Only difference is here we check for ->Active/WasActive but it may be unecessary.
|
||||
ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.OpenPopupStack.Size <= 0)
|
||||
@@ -6067,6 +6099,8 @@ static ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
|
||||
continue;
|
||||
if (!popup_window->Active && !popup_window->WasActive) // Check WasActive, because this code may run before popup renders on current frame, also check Active to handle newly created windows.
|
||||
continue;
|
||||
if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click.
|
||||
return popup_window;
|
||||
if (IsWindowWithinBeginStackOf(window, popup_window)) // Window is rendered over last modal, no render order change needed.
|
||||
break;
|
||||
for (ImGuiWindow* parent = popup_window->ParentWindowInBeginStack->RootWindow; parent != NULL; parent = parent->ParentWindowInBeginStack->RootWindow)
|
||||
@@ -6441,22 +6475,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
want_focus = true;
|
||||
else if ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) == 0)
|
||||
want_focus = true;
|
||||
|
||||
ImGuiWindow* modal = GetTopMostPopupModal();
|
||||
if (modal != NULL && !IsWindowWithinBeginStackOf(window, modal))
|
||||
{
|
||||
// Avoid focusing a window that is created outside of active modal. This will prevent active modal from being closed.
|
||||
// Since window is not focused it would reappear at the same display position like the last time it was visible.
|
||||
// In case of completely new windows it would go to the top (over current modal), but input to such window would still be blocked by modal.
|
||||
// Position window behind a modal that is not a begin-parent of this window.
|
||||
want_focus = false;
|
||||
if (window == window->RootWindow)
|
||||
{
|
||||
ImGuiWindow* blocking_modal = FindBlockingModal(window);
|
||||
IM_ASSERT(blocking_modal != NULL);
|
||||
BringWindowToDisplayBehind(window, blocking_modal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [Test Engine] Register whole window in the item system (before submitting further decorations)
|
||||
@@ -6583,8 +6601,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs
|
||||
ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL;
|
||||
bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false;
|
||||
bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0;
|
||||
if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping)
|
||||
bool parent_is_empty = (parent_window->DrawList->VtxBuffer.Size == 0);
|
||||
if (window->DrawList->CmdBuffer.back().ElemCount == 0 && !parent_is_empty && !previous_child_overlapping)
|
||||
render_decorations_in_parent = true;
|
||||
}
|
||||
if (render_decorations_in_parent)
|
||||
@@ -6649,8 +6667,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
||||
window->DC.NavLayersActiveMask = window->DC.NavLayersActiveMaskNext;
|
||||
window->DC.NavLayersActiveMaskNext = 0x00;
|
||||
window->DC.NavIsScrollPushableX = true;
|
||||
window->DC.NavHideHighlightOneFrame = false;
|
||||
window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
|
||||
window->DC.NavWindowHasScrollY = (window->ScrollMax.y > 0.0f);
|
||||
|
||||
window->DC.MenuBarAppending = false;
|
||||
window->DC.MenuColumns.Update(style.ItemSpacing.x, window_just_activated_by_user);
|
||||
@@ -6673,11 +6692,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->AutoFitFramesY--;
|
||||
|
||||
// Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there)
|
||||
// We ImGuiFocusRequestFlags_UnlessBelowModal to:
|
||||
// - Avoid focusing a window that is created outside of a modal. This will prevent active modal from being closed.
|
||||
// - Position window behind the modal that is not a begin-parent of this window.
|
||||
if (want_focus)
|
||||
{
|
||||
FocusWindow(window);
|
||||
FocusWindow(window, ImGuiFocusRequestFlags_UnlessBelowModal);
|
||||
if (want_focus && window == g.NavWindow)
|
||||
NavInitWindow(window, false); // <-- this is in the way for us to be able to defer and sort reappearing FocusWindow() calls
|
||||
}
|
||||
|
||||
// Title bar
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
||||
@@ -6903,10 +6924,25 @@ int ImGui::FindWindowDisplayIndex(ImGuiWindow* window)
|
||||
}
|
||||
|
||||
// Moving window to front of display and set focus (which happens to be back of our sorted list)
|
||||
void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Modal check?
|
||||
if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case.
|
||||
if (ImGuiWindow* blocking_modal = FindBlockingModal(window))
|
||||
{
|
||||
IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "<NULL>", blocking_modal->Name);
|
||||
if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
|
||||
BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal.
|
||||
return;
|
||||
}
|
||||
|
||||
// Find last focused child (if any) and focus it instead.
|
||||
if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL)
|
||||
window = NavRestoreLastChildNavWindow(window);
|
||||
|
||||
// Apply focus
|
||||
if (g.NavWindow != window)
|
||||
{
|
||||
SetNavWindow(window);
|
||||
@@ -6943,9 +6979,10 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
BringWindowToDisplayFront(display_front_window);
|
||||
}
|
||||
|
||||
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
|
||||
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_UNUSED(filter_viewport); // Unused in master branch.
|
||||
int start_idx = g.WindowsFocusOrder.Size - 1;
|
||||
if (under_this_window != NULL)
|
||||
{
|
||||
@@ -6963,15 +7000,15 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind
|
||||
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
||||
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
||||
IM_ASSERT(window == window->RootWindow);
|
||||
if (window != ignore_window && window->WasActive)
|
||||
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
||||
{
|
||||
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
|
||||
FocusWindow(focus_window);
|
||||
return;
|
||||
}
|
||||
if (window == ignore_window || !window->WasActive)
|
||||
continue;
|
||||
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
||||
{
|
||||
FocusWindow(window, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
FocusWindow(NULL);
|
||||
FocusWindow(NULL, flags);
|
||||
}
|
||||
|
||||
// Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only.
|
||||
@@ -8665,12 +8702,18 @@ static const char* GetInputSourceName(ImGuiInputSource source)
|
||||
IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT);
|
||||
return input_source_names[source];
|
||||
}
|
||||
static const char* GetMouseSourceName(ImGuiMouseSource source)
|
||||
{
|
||||
const char* mouse_source_names[] = { "Mouse", "TouchScreen", "Pen" };
|
||||
IM_ASSERT(IM_ARRAYSIZE(mouse_source_names) == ImGuiMouseSource_COUNT && source >= 0 && source < ImGuiMouseSource_COUNT);
|
||||
return mouse_source_names[source];
|
||||
}
|
||||
static void DebugPrintInputEvent(const char* prefix, const ImGuiInputEvent* e)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("%s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("%s: MousePos (%.1f, %.1f)\n", prefix, e->MousePos.PosX, e->MousePos.PosY); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("%s: MouseButton %d %s\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up"); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("%s: MouseWheel (%.3f, %.3f)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY); return; }
|
||||
if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("%s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("%s: MousePos (%.1f, %.1f) (%s)\n", prefix, e->MousePos.PosX, e->MousePos.PosY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("%s: MouseButton %d %s (%s)\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up", GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("%s: MouseWheel (%.3f, %.3f) (%s)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; }
|
||||
if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG_IO("%s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; }
|
||||
if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG_IO("%s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; }
|
||||
if (e->Type == ImGuiInputEventType_Focus) { IMGUI_DEBUG_LOG_IO("%s: AppFocused %d\n", prefix, e->AppFocused.Focused); return; }
|
||||
@@ -8706,6 +8749,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
||||
if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputted))
|
||||
break;
|
||||
io.MousePos = event_pos;
|
||||
io.MouseSource = e->MousePos.MouseSource;
|
||||
mouse_moved = true;
|
||||
}
|
||||
else if (e->Type == ImGuiInputEventType_MouseButton)
|
||||
@@ -8715,7 +8759,10 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
||||
IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT);
|
||||
if (trickle_fast_inputs && ((mouse_button_changed & (1 << button)) || mouse_wheeled))
|
||||
break;
|
||||
if (trickle_fast_inputs && e->MouseButton.MouseSource == ImGuiMouseSource_TouchScreen && mouse_moved) // #2702: TouchScreen have no initial hover.
|
||||
break;
|
||||
io.MouseDown[button] = e->MouseButton.Down;
|
||||
io.MouseSource = e->MouseButton.MouseSource;
|
||||
mouse_button_changed |= (1 << button);
|
||||
}
|
||||
else if (e->Type == ImGuiInputEventType_MouseWheel)
|
||||
@@ -8725,6 +8772,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
||||
break;
|
||||
io.MouseWheelH += e->MouseWheel.WheelX;
|
||||
io.MouseWheel += e->MouseWheel.WheelY;
|
||||
io.MouseSource = e->MouseWheel.MouseSource;
|
||||
mouse_wheeled = true;
|
||||
}
|
||||
else if (e->Type == ImGuiInputEventType_Key)
|
||||
@@ -9310,7 +9358,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
|
||||
// [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something".
|
||||
// Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something".
|
||||
// READ THE FAQ: https://dearimgui.org/faq
|
||||
// READ THE FAQ: https://dearimgui.com/faq
|
||||
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
|
||||
}
|
||||
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
|
||||
@@ -9337,6 +9385,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
DebugLocateItemResolveWithLastItem();
|
||||
#endif
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
|
||||
//if ((g.LastItemData.InFlags & ImGuiItemFlags_NoNav) == 0)
|
||||
// window->DrawList->AddRect(g.LastItemData.NavRect.Min, g.LastItemData.NavRect.Max, IM_COL32(255,255,0,255)); // [DEBUG]
|
||||
|
||||
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
|
||||
if (is_rect_visible)
|
||||
@@ -10061,6 +10111,7 @@ bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
return IsPopupOpen(id, popup_flags);
|
||||
}
|
||||
|
||||
// Also see FindBlockingModal(NULL)
|
||||
ImGuiWindow* ImGui::GetTopMostPopupModal()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -10071,6 +10122,7 @@ ImGuiWindow* ImGui::GetTopMostPopupModal()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// See Demo->Stacked Modal to confirm what this is for.
|
||||
ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -10199,7 +10251,7 @@ void ImGui::ClosePopupsExceptModals()
|
||||
for (popup_count_to_keep = g.OpenPopupStack.Size; popup_count_to_keep > 0; popup_count_to_keep--)
|
||||
{
|
||||
ImGuiWindow* window = g.OpenPopupStack[popup_count_to_keep - 1].Window;
|
||||
if (!window || window->Flags & ImGuiWindowFlags_Modal)
|
||||
if (!window || (window->Flags & ImGuiWindowFlags_Modal))
|
||||
break;
|
||||
}
|
||||
if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below
|
||||
@@ -10221,16 +10273,9 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
|
||||
{
|
||||
ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window;
|
||||
if (focus_window && !focus_window->WasActive && popup_window)
|
||||
{
|
||||
// Fallback
|
||||
FocusTopMostWindowUnderOne(popup_window, NULL);
|
||||
}
|
||||
FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback
|
||||
else
|
||||
{
|
||||
if (g.NavLayer == ImGuiNavLayer_Main && focus_window)
|
||||
focus_window = NavRestoreLastChildNavWindow(focus_window);
|
||||
FocusWindow(focus_window);
|
||||
}
|
||||
FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10620,29 +10665,15 @@ ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy)
|
||||
return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up;
|
||||
}
|
||||
|
||||
static float inline NavScoreItemDistInterval(float a0, float a1, float b0, float b1)
|
||||
static float inline NavScoreItemDistInterval(float cand_min, float cand_max, float curr_min, float curr_max)
|
||||
{
|
||||
if (a1 < b0)
|
||||
return a1 - b0;
|
||||
if (b1 < a0)
|
||||
return a0 - b1;
|
||||
if (cand_max < curr_min)
|
||||
return cand_max - curr_min;
|
||||
if (curr_max < cand_min)
|
||||
return cand_min - curr_max;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect& r, const ImRect& clip_rect)
|
||||
{
|
||||
if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
|
||||
{
|
||||
r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y);
|
||||
r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y);
|
||||
}
|
||||
else // FIXME: PageUp/PageDown are leaving move_dir == None
|
||||
{
|
||||
r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x);
|
||||
r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x);
|
||||
}
|
||||
}
|
||||
|
||||
// Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057
|
||||
static bool ImGui::NavScoreItem(ImGuiNavItemData* result)
|
||||
{
|
||||
@@ -10665,10 +10696,6 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result)
|
||||
cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window
|
||||
}
|
||||
|
||||
// We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
|
||||
// For example, this ensures that items in one column are not reached when moving vertically from items in another column.
|
||||
NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect);
|
||||
|
||||
// Compute distance between boxes
|
||||
// FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
|
||||
float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x);
|
||||
@@ -10707,32 +10734,35 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result)
|
||||
quadrant = (g.LastItemData.ID < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right;
|
||||
}
|
||||
|
||||
const ImGuiDir move_dir = g.NavMoveDir;
|
||||
#if IMGUI_DEBUG_NAV_SCORING
|
||||
char buf[128];
|
||||
if (IsMouseHoveringRect(cand.Min, cand.Max))
|
||||
char buf[200];
|
||||
if (g.IO.KeyCtrl) // Hold CTRL to preview score in matching quadrant. CTRL+Arrow to rotate.
|
||||
{
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
|
||||
ImDrawList* draw_list = GetForegroundDrawList(window);
|
||||
draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
|
||||
draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
|
||||
draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,150));
|
||||
draw_list->AddText(cand.Max, ~0U, buf);
|
||||
}
|
||||
else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate.
|
||||
{
|
||||
if (quadrant == g.NavMoveDir)
|
||||
if (quadrant == move_dir)
|
||||
{
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
|
||||
ImDrawList* draw_list = GetForegroundDrawList(window);
|
||||
draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
|
||||
draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 80));
|
||||
draw_list->AddRectFilled(cand.Min, cand.Min + CalcTextSize(buf), IM_COL32(255, 0, 0, 200));
|
||||
draw_list->AddText(cand.Min, IM_COL32(255, 255, 255, 255), buf);
|
||||
}
|
||||
}
|
||||
if (IsMouseHoveringRect(cand.Min, cand.Max))
|
||||
{
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf),
|
||||
"d-box (%7.3f,%7.3f) -> %7.3f\nd-center (%7.3f,%7.3f) -> %7.3f\nd-axial (%7.3f,%7.3f) -> %7.3f\nnav %c, quadrant %c",
|
||||
dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
|
||||
ImDrawList* draw_list = GetForegroundDrawList(window);
|
||||
draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
|
||||
draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
|
||||
draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,200));
|
||||
draw_list->AddText(cand.Max, ~0U, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Is it in the quadrant we're interested in moving to?
|
||||
bool new_best = false;
|
||||
const ImGuiDir move_dir = g.NavMoveDir;
|
||||
if (quadrant == move_dir)
|
||||
{
|
||||
// Does it beat the current best candidate?
|
||||
@@ -10788,6 +10818,15 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
|
||||
result->RectRel = WindowRectAbsToRel(window, g.LastItemData.NavRect);
|
||||
}
|
||||
|
||||
// True when current work location may be scrolled horizontally when moving left / right.
|
||||
// This is generally always true UNLESS within a column. We don't have a vertical equivalent.
|
||||
void ImGui::NavUpdateCurrentWindowIsScrollPushableX()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
window->DC.NavIsScrollPushableX = (g.CurrentTable == NULL && window->DC.CurrentColumns == NULL);
|
||||
}
|
||||
|
||||
// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
|
||||
// This is called after LastItemData is set.
|
||||
static void ImGui::NavProcessItem()
|
||||
@@ -10795,9 +10834,16 @@ static void ImGui::NavProcessItem()
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
const ImGuiID id = g.LastItemData.ID;
|
||||
const ImRect nav_bb = g.LastItemData.NavRect;
|
||||
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
|
||||
|
||||
// When inside a container that isn't scrollable with Left<>Right, clip NavRect accordingly (#2221)
|
||||
if (window->DC.NavIsScrollPushableX == false)
|
||||
{
|
||||
g.LastItemData.NavRect.Min.x = ImClamp(g.LastItemData.NavRect.Min.x, window->ClipRect.Min.x, window->ClipRect.Max.x);
|
||||
g.LastItemData.NavRect.Max.x = ImClamp(g.LastItemData.NavRect.Max.x, window->ClipRect.Min.x, window->ClipRect.Max.x);
|
||||
}
|
||||
const ImRect nav_bb = g.LastItemData.NavRect;
|
||||
|
||||
// Process Init Request
|
||||
if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent && (item_flags & ImGuiItemFlags_Disabled) == 0)
|
||||
{
|
||||
@@ -10839,7 +10885,7 @@ static void ImGui::NavProcessItem()
|
||||
}
|
||||
}
|
||||
|
||||
// Update window-relative bounding box of navigated item
|
||||
// Update information for currently focused/navigated item
|
||||
if (g.NavId == id)
|
||||
{
|
||||
if (g.NavWindow != window)
|
||||
@@ -10847,7 +10893,7 @@ static void ImGui::NavProcessItem()
|
||||
g.NavLayer = window->DC.NavLayerCurrent;
|
||||
g.NavFocusScopeId = g.CurrentFocusScopeId;
|
||||
g.NavIdIsAlive = true;
|
||||
window->NavRectRel[window->DC.NavLayerCurrent] = WindowRectAbsToRel(window, nav_bb); // Store item bounding box (relative to window position)
|
||||
window->NavRectRel[window->DC.NavLayerCurrent] = WindowRectAbsToRel(window, nav_bb); // Store item bounding box (relative to window position)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10977,10 +11023,11 @@ void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNav
|
||||
void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY
|
||||
IM_ASSERT((wrap_flags & ImGuiNavMoveFlags_WrapMask_ ) != 0 && (wrap_flags & ~ImGuiNavMoveFlags_WrapMask_) == 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY
|
||||
|
||||
// In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test
|
||||
if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main)
|
||||
g.NavMoveFlags |= wrap_flags;
|
||||
g.NavMoveFlags = (g.NavMoveFlags & ~ImGuiNavMoveFlags_WrapMask_) | wrap_flags;
|
||||
}
|
||||
|
||||
// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
|
||||
@@ -11237,7 +11284,7 @@ static void ImGui::NavUpdate()
|
||||
ImGuiWindow* window = g.NavWindow;
|
||||
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
|
||||
const ImGuiDir move_dir = g.NavMoveDir;
|
||||
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && move_dir != ImGuiDir_None)
|
||||
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None)
|
||||
{
|
||||
if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
|
||||
SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
|
||||
@@ -11347,13 +11394,15 @@ void ImGui::NavUpdateCreateMoveRequest()
|
||||
g.NavScoringNoClipRect.TranslateY(scoring_rect_offset_y);
|
||||
}
|
||||
|
||||
// [DEBUG] Always send a request
|
||||
// [DEBUG] Always send a request when holding CTRL. Hold CTRL + Arrow change the direction.
|
||||
#if IMGUI_DEBUG_NAV_SCORING
|
||||
if (io.KeyCtrl && IsKeyPressed(ImGuiKey_C))
|
||||
g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3);
|
||||
if (io.KeyCtrl && g.NavMoveDir == ImGuiDir_None)
|
||||
//if (io.KeyCtrl && IsKeyPressed(ImGuiKey_C))
|
||||
// g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3);
|
||||
if (io.KeyCtrl)
|
||||
{
|
||||
g.NavMoveDir = g.NavMoveDirForDebug;
|
||||
if (g.NavMoveDir == ImGuiDir_None)
|
||||
g.NavMoveDir = g.NavMoveDirForDebug;
|
||||
g.NavMoveClipDir = g.NavMoveDir;
|
||||
g.NavMoveFlags |= ImGuiNavMoveFlags_DebugNoResult;
|
||||
}
|
||||
#endif
|
||||
@@ -11467,6 +11516,7 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
|
||||
if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
|
||||
NavRestoreHighlightAfterMove();
|
||||
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11484,17 +11534,15 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
// Scroll to keep newly navigated item fully into view.
|
||||
if (g.NavLayer == ImGuiNavLayer_Main)
|
||||
{
|
||||
ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel);
|
||||
ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags);
|
||||
|
||||
if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdgeY)
|
||||
{
|
||||
// FIXME: Should remove this
|
||||
// FIXME: Should remove this? Or make more precise: use ScrollToRectEx() with edge?
|
||||
float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
|
||||
SetScrollY(result->Window, scroll_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel);
|
||||
ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (g.NavWindow != result->Window)
|
||||
@@ -11605,7 +11653,7 @@ static float ImGui::NavUpdatePageUpPageDown()
|
||||
if (g.NavLayer != ImGuiNavLayer_Main)
|
||||
NavRestoreLayer(ImGuiNavLayer_Main);
|
||||
|
||||
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
|
||||
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY)
|
||||
{
|
||||
// Fallback manual-scroll when window has no navigable item
|
||||
if (IsKeyPressed(ImGuiKey_PageUp, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat))
|
||||
@@ -11673,8 +11721,7 @@ static void ImGui::NavEndFrame()
|
||||
// Perform wrap-around in menus
|
||||
// FIXME-NAV: Wrap may need to apply a weight bias on the other axis. e.g. 4x4 grid with 2 last items missing on last item won't handle LoopY/WrapY correctly.
|
||||
// FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame.
|
||||
const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY;
|
||||
if (g.NavWindow && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
|
||||
if (g.NavWindow && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & ImGuiNavMoveFlags_WrapMask_) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
|
||||
NavUpdateCreateWrappingRequest();
|
||||
}
|
||||
|
||||
@@ -11783,7 +11830,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
bool apply_toggle_layer = false;
|
||||
|
||||
ImGuiWindow* modal_window = GetTopMostPopupModal();
|
||||
bool allow_windowing = (modal_window == NULL);
|
||||
bool allow_windowing = (modal_window == NULL); // FIXME: This prevent CTRL+TAB from being usable with windows that are inside the Begin-stack of that modal.
|
||||
if (!allow_windowing)
|
||||
g.NavWindowingTarget = NULL;
|
||||
|
||||
@@ -11912,9 +11959,9 @@ static void ImGui::NavUpdateWindowing()
|
||||
{
|
||||
ClearActiveID();
|
||||
NavRestoreHighlightAfterMove();
|
||||
apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window);
|
||||
ClosePopupsOverWindow(apply_focus_window, false);
|
||||
FocusWindow(apply_focus_window);
|
||||
FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild);
|
||||
apply_focus_window = g.NavWindow;
|
||||
if (apply_focus_window->NavLastIds[0] == 0)
|
||||
NavInitWindow(apply_focus_window, false);
|
||||
|
||||
@@ -12687,6 +12734,7 @@ void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
|
||||
}
|
||||
|
||||
// Zero-tolerance, no error reporting, cheap .ini parsing
|
||||
// Set ini_size==0 to let us use strlen(ini_data). Do not call this function with a 0 if your buffer is actually empty!
|
||||
void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -12818,7 +12866,7 @@ ImGuiWindowSettings* ImGui::FindWindowSettingsByID(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
|
||||
if (settings->ID == id)
|
||||
if (settings->ID == id && !settings->WantDelete)
|
||||
return settings;
|
||||
return NULL;
|
||||
}
|
||||
@@ -13727,6 +13775,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (IsMouseClicked(i)) { SameLine(); Text("b%d (%d)", i, io.MouseClickedCount[i]); }
|
||||
Text("Mouse released:"); for (int i = 0; i < count; i++) if (IsMouseReleased(i)) { SameLine(); Text("b%d", i); }
|
||||
Text("Mouse wheel: %.1f", io.MouseWheel);
|
||||
Text("Mouse source: %s", GetMouseSourceName(io.MouseSource));
|
||||
Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused
|
||||
Unindent();
|
||||
}
|
||||
@@ -14327,14 +14376,13 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
return;
|
||||
}
|
||||
|
||||
AlignTextToFramePadding();
|
||||
Text("Log events:");
|
||||
SameLine(); CheckboxFlags("All", &g.DebugLogFlags, ImGuiDebugLogFlags_EventMask_);
|
||||
CheckboxFlags("All", &g.DebugLogFlags, ImGuiDebugLogFlags_EventMask_);
|
||||
SameLine(); CheckboxFlags("ActiveId", &g.DebugLogFlags, ImGuiDebugLogFlags_EventActiveId);
|
||||
SameLine(); CheckboxFlags("Focus", &g.DebugLogFlags, ImGuiDebugLogFlags_EventFocus);
|
||||
SameLine(); CheckboxFlags("Popup", &g.DebugLogFlags, ImGuiDebugLogFlags_EventPopup);
|
||||
SameLine(); CheckboxFlags("Nav", &g.DebugLogFlags, ImGuiDebugLogFlags_EventNav);
|
||||
SameLine(); if (CheckboxFlags("Clipper", &g.DebugLogFlags, ImGuiDebugLogFlags_EventClipper)) { g.DebugLogClipperAutoDisableFrames = 2; } if (IsItemHovered()) SetTooltip("Clipper log auto-disabled after 2 frames");
|
||||
//SameLine(); CheckboxFlags("Selection", &g.DebugLogFlags, ImGuiDebugLogFlags_EventSelection);
|
||||
SameLine(); CheckboxFlags("IO", &g.DebugLogFlags, ImGuiDebugLogFlags_EventIO);
|
||||
|
||||
if (SmallButton("Clear"))
|
||||
@@ -14357,7 +14405,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
TextUnformatted(line_begin, line_end);
|
||||
ImRect text_rect = g.LastItemData.Rect;
|
||||
if (IsItemHovered())
|
||||
for (const char* p = line_begin; p < line_end - 10; p++)
|
||||
for (const char* p = line_begin; p <= line_end - 10; p++)
|
||||
{
|
||||
ImGuiID id = 0;
|
||||
if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1)
|
||||
|
||||
35
3rdparty/dear-imgui/imgui.h
vendored
35
3rdparty/dear-imgui/imgui.h
vendored
@@ -1,14 +1,14 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
// - Read FAQ at http://dearimgui.org/faq
|
||||
// - Read FAQ at http://dearimgui.com/faq
|
||||
// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
|
||||
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
|
||||
// Read imgui.cpp for details, links and comments.
|
||||
|
||||
// Resources:
|
||||
// - FAQ http://dearimgui.org/faq
|
||||
// - FAQ http://dearimgui.com/faq
|
||||
// - Homepage & latest https://github.com/ocornut/imgui
|
||||
// - Releases & changelog https://github.com/ocornut/imgui/releases
|
||||
// - Gallery https://github.com/ocornut/imgui/issues/5886 (please post your screenshots/video there!)
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
||||
#define IMGUI_VERSION "1.89.5 WIP"
|
||||
#define IMGUI_VERSION_NUM 18946
|
||||
#define IMGUI_VERSION "1.89.6 WIP"
|
||||
#define IMGUI_VERSION_NUM 18954
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
@@ -167,6 +167,7 @@ struct ImGuiViewport; // A Platform Window (always only one in 'ma
|
||||
// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value)
|
||||
enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen)
|
||||
typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling
|
||||
typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions
|
||||
typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type
|
||||
@@ -255,8 +256,8 @@ struct ImVec2
|
||||
float x, y;
|
||||
constexpr ImVec2() : x(0.0f), y(0.0f) { }
|
||||
constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { }
|
||||
float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine.
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const char*)this)[idx]; }
|
||||
float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine.
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; }
|
||||
#ifdef IM_VEC2_CLASS_EXTRA
|
||||
IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2.
|
||||
#endif
|
||||
@@ -460,7 +461,7 @@ namespace ImGui
|
||||
IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets)
|
||||
|
||||
// ID stack/scopes
|
||||
// Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
|
||||
// Read the FAQ (docs/FAQ.md or http://dearimgui.com/faq) for more details about how ID are handled in dear imgui.
|
||||
// - Those questions are answered and impacted by understanding of the ID stack system:
|
||||
// - "Q: Why is my widget not reacting when I click on it?"
|
||||
// - "Q: How can I have widgets with an empty label?"
|
||||
@@ -1407,7 +1408,7 @@ enum ImGuiKey : int
|
||||
ImGuiKey_KeypadEqual,
|
||||
|
||||
// Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION
|
||||
// (download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets)
|
||||
// (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets)
|
||||
ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS)
|
||||
ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS)
|
||||
ImGuiKey_GamepadFaceLeft, // X (Xbox) Y (Switch) Square (PS) // Tap: Toggle Menu. Hold: Windowing mode (Focus/Move/Resize windows)
|
||||
@@ -1715,6 +1716,18 @@ enum ImGuiMouseCursor_
|
||||
ImGuiMouseCursor_COUNT
|
||||
};
|
||||
|
||||
// Enumeration for AddMouseSourceEvent() actual source of Mouse Input data.
|
||||
// Historically we use "Mouse" terminology everywhere to indicate pointer data, e.g. MousePos, IsMousePressed(), io.AddMousePosEvent()
|
||||
// But that "Mouse" data can come from different source which occasionally may be useful for application to know about.
|
||||
// You can submit a change of pointer type using io.AddMouseSourceEvent().
|
||||
enum ImGuiMouseSource : int
|
||||
{
|
||||
ImGuiMouseSource_Mouse = 0, // Input is coming from an actual mouse.
|
||||
ImGuiMouseSource_TouchScreen, // Input is coming from a touch screen (no hovering prior to initial press, less precise initial press aiming, dual-axis wheeling possible).
|
||||
ImGuiMouseSource_Pen, // Input is coming from a pressure/magnetic pen (often used in conjunction with high-sampling rates).
|
||||
ImGuiMouseSource_COUNT
|
||||
};
|
||||
|
||||
// Enumeration for ImGui::SetWindow***(), SetNextWindow***(), SetNextItem***() functions
|
||||
// Represent a condition.
|
||||
// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always.
|
||||
@@ -1982,6 +1995,7 @@ struct ImGuiIO
|
||||
IMGUI_API void AddMousePosEvent(float x, float y); // Queue a mouse position update. Use -FLT_MAX,-FLT_MAX to signify no mouse (e.g. app not focused and not hovered)
|
||||
IMGUI_API void AddMouseButtonEvent(int button, bool down); // Queue a mouse button change
|
||||
IMGUI_API void AddMouseWheelEvent(float wheel_x, float wheel_y); // Queue a mouse wheel update. wheel_y<0: scroll down, wheel_y>0: scroll up, wheel_x<0: scroll right, wheel_x>0: scroll left.
|
||||
IMGUI_API void AddMouseSourceEvent(ImGuiMouseSource source); // Queue a mouse source change (Mouse/TouchScreen/Pen)
|
||||
IMGUI_API void AddFocusEvent(bool focused); // Queue a gain/loss of focus for the application (generally based on OS/platform focus of your window)
|
||||
IMGUI_API void AddInputCharacter(unsigned int c); // Queue a new character input
|
||||
IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue a new character input from a UTF-16 character, it can be a surrogate
|
||||
@@ -2035,6 +2049,7 @@ struct ImGuiIO
|
||||
bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Other buttons allow us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API.
|
||||
float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. >0 scrolls Up, <0 scrolls Down. Hold SHIFT to turn vertical scroll into horizontal scroll.
|
||||
float MouseWheelH; // Mouse wheel Horizontal. >0 scrolls Left, <0 scrolls Right. Most users don't have a mouse with a horizontal wheel, may not be filled by all backends.
|
||||
ImGuiMouseSource MouseSource; // Mouse actual input peripheral (Mouse/TouchScreen/Pen).
|
||||
bool KeyCtrl; // Keyboard modifier down: Control
|
||||
bool KeyShift; // Keyboard modifier down: Shift
|
||||
bool KeyAlt; // Keyboard modifier down: Alt
|
||||
@@ -2337,7 +2352,6 @@ struct ImGuiListClipper
|
||||
// - It is important that we are keeping those disabled by default so they don't leak in user space.
|
||||
// - This is in order to allow user enabling implicit cast operators between ImVec2/ImVec4 and their own types (using IM_VEC2_CLASS_EXTRA in imconfig.h)
|
||||
// - You can use '#define IMGUI_DEFINE_MATH_OPERATORS' to import our operators, provided as a courtesy.
|
||||
// - We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself.
|
||||
#ifdef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
@@ -2347,6 +2361,7 @@ static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return
|
||||
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
|
||||
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
|
||||
static inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); }
|
||||
static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
|
||||
static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
|
||||
static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
|
||||
|
||||
20
3rdparty/dear-imgui/imgui_demo.cpp
vendored
20
3rdparty/dear-imgui/imgui_demo.cpp
vendored
@@ -1,8 +1,8 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
// - Read FAQ at http://dearimgui.org/faq
|
||||
// - Read FAQ at http://dearimgui.com/faq
|
||||
// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
|
||||
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
|
||||
// Read imgui.cpp for more details, documentation and comments.
|
||||
@@ -409,7 +409,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!");
|
||||
ImGui::BulletText("See comments in imgui.cpp.");
|
||||
ImGui::BulletText("See example applications in the examples/ folder.");
|
||||
ImGui::BulletText("Read the FAQ at http://www.dearimgui.org/faq/");
|
||||
ImGui::BulletText("Read the FAQ at http://www.dearimgui.com/faq/");
|
||||
ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls.");
|
||||
ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls.");
|
||||
ImGui::Separator();
|
||||
@@ -483,13 +483,13 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
"Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n"
|
||||
"Here we expose them as read-only fields to avoid breaking interactions with your backend.");
|
||||
|
||||
// Make a local copy to avoid modifying actual backend flags.
|
||||
// FIXME: We don't use BeginDisabled() to keep label bright, maybe we need a BeginReadonly() equivalent..
|
||||
ImGuiBackendFlags backend_flags = io.BackendFlags;
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &backend_flags, ImGuiBackendFlags_HasGamepad);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &backend_flags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &backend_flags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
// FIXME: Maybe we need a BeginReadonly() equivalent to keep label bright?
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &io.BackendFlags, ImGuiBackendFlags_HasGamepad);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TreePop();
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
5
3rdparty/dear-imgui/imgui_draw.cpp
vendored
5
3rdparty/dear-imgui/imgui_draw.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -2623,6 +2623,9 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
|
||||
|
||||
ImVector<ImFontAtlasCustomRect>& user_rects = atlas->CustomRects;
|
||||
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
|
||||
#ifdef __GNUC__
|
||||
if (user_rects.Size < 1) { __builtin_unreachable(); } // Workaround for GCC bug if IM_ASSERT() is defined to conditionally throw (see #5343)
|
||||
#endif
|
||||
|
||||
ImVector<stbrp_rect> pack_rects;
|
||||
pack_rects.resize(user_rects.Size);
|
||||
|
||||
51
3rdparty/dear-imgui/imgui_internal.h
vendored
51
3rdparty/dear-imgui/imgui_internal.h
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@@ -164,6 +164,7 @@ typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // E
|
||||
// Flags
|
||||
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
|
||||
typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
|
||||
typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow();
|
||||
typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc.
|
||||
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags
|
||||
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
|
||||
@@ -230,6 +231,7 @@ namespace ImStb
|
||||
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
|
||||
@@ -905,6 +907,16 @@ enum ImGuiSeparatorFlags_
|
||||
ImGuiSeparatorFlags_SpanAllColumns = 1 << 2,
|
||||
};
|
||||
|
||||
// Flags for FocusWindow(). This is not called ImGuiFocusFlags to avoid confusion with public-facing ImGuiFocusedFlags.
|
||||
// FIXME: Once we finishing replacing more uses of GetTopMostPopupModal()+IsWindowWithinBeginStackOf()
|
||||
// and FindBlockingModal() with this, we may want to change the flag to be opt-out instead of opt-in.
|
||||
enum ImGuiFocusRequestFlags_
|
||||
{
|
||||
ImGuiFocusRequestFlags_None = 0,
|
||||
ImGuiFocusRequestFlags_RestoreFocusedChild = 1 << 0, // Find last focused child (if any) and focus it instead.
|
||||
ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 1, // Do not set focus if the window is below a modal.
|
||||
};
|
||||
|
||||
enum ImGuiTextFlags_
|
||||
{
|
||||
ImGuiTextFlags_None = 0,
|
||||
@@ -1264,7 +1276,7 @@ enum ImGuiInputEventType
|
||||
enum ImGuiInputSource
|
||||
{
|
||||
ImGuiInputSource_None = 0,
|
||||
ImGuiInputSource_Mouse,
|
||||
ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them.
|
||||
ImGuiInputSource_Keyboard,
|
||||
ImGuiInputSource_Gamepad,
|
||||
ImGuiInputSource_Clipboard, // Currently only used by InputText()
|
||||
@@ -1273,9 +1285,9 @@ enum ImGuiInputSource
|
||||
|
||||
// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension?
|
||||
// Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor'
|
||||
struct ImGuiInputEventMousePos { float PosX, PosY; };
|
||||
struct ImGuiInputEventMouseWheel { float WheelX, WheelY; };
|
||||
struct ImGuiInputEventMouseButton { int Button; bool Down; };
|
||||
struct ImGuiInputEventMousePos { float PosX, PosY; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventMouseWheel { float WheelX, WheelY; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventMouseButton { int Button; bool Down; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; };
|
||||
struct ImGuiInputEventText { unsigned int Char; };
|
||||
struct ImGuiInputEventAppFocused { bool Focused; };
|
||||
@@ -1284,6 +1296,7 @@ struct ImGuiInputEvent
|
||||
{
|
||||
ImGuiInputEventType Type;
|
||||
ImGuiInputSource Source;
|
||||
ImU32 EventId; // Unique, sequential increasing integer to identify an event (if you need to correlate them to other data).
|
||||
union
|
||||
{
|
||||
ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos
|
||||
@@ -1460,6 +1473,7 @@ enum ImGuiNavMoveFlags_
|
||||
ImGuiNavMoveFlags_LoopY = 1 << 1,
|
||||
ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left)
|
||||
ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness
|
||||
ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY,
|
||||
ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
|
||||
ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
|
||||
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
|
||||
@@ -1669,8 +1683,9 @@ enum ImGuiDebugLogFlags_
|
||||
ImGuiDebugLogFlags_EventPopup = 1 << 2,
|
||||
ImGuiDebugLogFlags_EventNav = 1 << 3,
|
||||
ImGuiDebugLogFlags_EventClipper = 1 << 4,
|
||||
ImGuiDebugLogFlags_EventIO = 1 << 5,
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventIO,
|
||||
ImGuiDebugLogFlags_EventSelection = 1 << 5,
|
||||
ImGuiDebugLogFlags_EventIO = 1 << 6,
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY
|
||||
};
|
||||
|
||||
@@ -1739,8 +1754,6 @@ struct ImGuiContext
|
||||
bool Initialized;
|
||||
bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
|
||||
ImGuiIO IO;
|
||||
ImVector<ImGuiInputEvent> InputEventsQueue; // Input events which will be tricked/written into IO structure.
|
||||
ImVector<ImGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail.
|
||||
ImGuiStyle Style;
|
||||
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
||||
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
||||
@@ -1757,6 +1770,12 @@ struct ImGuiContext
|
||||
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
|
||||
void* TestEngine; // Test engine user data
|
||||
|
||||
// Inputs
|
||||
ImVector<ImGuiInputEvent> InputEventsQueue; // Input events which will be trickled/written into IO structure.
|
||||
ImVector<ImGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail.
|
||||
ImGuiMouseSource InputEventsNextMouseSource;
|
||||
ImU32 InputEventsNextEventId;
|
||||
|
||||
// Windows state
|
||||
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
|
||||
ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front.
|
||||
@@ -2041,6 +2060,9 @@ struct ImGuiContext
|
||||
TestEngineHookItems = false;
|
||||
TestEngine = NULL;
|
||||
|
||||
InputEventsNextMouseSource = ImGuiMouseSource_Mouse;
|
||||
InputEventsNextEventId = 1;
|
||||
|
||||
WindowsActiveCount = 0;
|
||||
CurrentWindow = NULL;
|
||||
HoveredWindow = NULL;
|
||||
@@ -2216,14 +2238,15 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
|
||||
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;
|
||||
ImVec2 CursorStartPosLossyness;// Record the loss of precision of CursorStartPos due to really large scrolling amount. This is used by clipper to compensentate and fix the most common use case of large scroll area.
|
||||
ImVec2 CursorStartPosLossyness;// Record the loss of precision of CursorStartPos due to really large scrolling amount. This is used by clipper to compensate and fix the most common use case of large scroll area.
|
||||
|
||||
// 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)
|
||||
short NavLayersActiveMaskNext;// Which layers have been written to (accumulator for current frame)
|
||||
bool NavIsScrollPushableX; // Set when current work location may be scrolled horizontally when moving left / right. This is generally always true UNLESS within a column.
|
||||
bool NavHideHighlightOneFrame;
|
||||
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
|
||||
bool NavWindowHasScrollY; // Set per window when scrolling can be used (== ScrollMax.y > 0.0f)
|
||||
|
||||
// Miscellaneous
|
||||
bool MenuBarAppending; // FIXME: Remove this
|
||||
@@ -2740,8 +2763,8 @@ namespace ImGui
|
||||
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
|
||||
|
||||
// Windows: Display Order and Focus Order
|
||||
IMGUI_API void FocusWindow(ImGuiWindow* window);
|
||||
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window);
|
||||
IMGUI_API void FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0);
|
||||
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags);
|
||||
IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window);
|
||||
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window);
|
||||
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window);
|
||||
@@ -2861,6 +2884,7 @@ namespace ImGui
|
||||
IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window);
|
||||
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
||||
IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal();
|
||||
IMGUI_API ImGuiWindow* FindBlockingModal(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
|
||||
|
||||
@@ -2884,6 +2908,7 @@ namespace ImGui
|
||||
IMGUI_API void NavMoveRequestCancel();
|
||||
IMGUI_API void NavMoveRequestApplyResult();
|
||||
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
||||
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
|
||||
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
|
||||
IMGUI_API void SetNavWindow(ImGuiWindow* window);
|
||||
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
||||
|
||||
14
3rdparty/dear-imgui/imgui_tables.cpp
vendored
14
3rdparty/dear-imgui/imgui_tables.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -483,6 +483,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
|
||||
// Make table current
|
||||
g.CurrentTable = table;
|
||||
outer_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
||||
outer_window->DC.CurrentTableIdx = table_idx;
|
||||
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
|
||||
inner_window->DC.CurrentTableIdx = table_idx;
|
||||
@@ -1436,6 +1437,7 @@ void ImGui::EndTable()
|
||||
g.CurrentTable->DrawSplitter = &temp_data->DrawSplitter;
|
||||
}
|
||||
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
|
||||
NavUpdateCurrentWindowIsScrollPushableX();
|
||||
}
|
||||
|
||||
// See "COLUMN SIZING POLICIES" comments at the top of this file
|
||||
@@ -2381,11 +2383,11 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
struct MergeGroup
|
||||
{
|
||||
ImRect ClipRect;
|
||||
int ChannelsCount;
|
||||
ImBitArrayPtr ChannelsMask;
|
||||
int ChannelsCount = 0;
|
||||
ImBitArrayPtr ChannelsMask = NULL;
|
||||
};
|
||||
int merge_group_mask = 0x00;
|
||||
MergeGroup merge_groups[4] = {};
|
||||
MergeGroup merge_groups[4];
|
||||
|
||||
// Use a reusable temp buffer for the merge masks as they are dynamically sized.
|
||||
const int max_draw_channels = (4 + table->ColumnsCount * 2);
|
||||
@@ -3007,7 +3009,7 @@ void ImGui::TableHeader(const char* label)
|
||||
}
|
||||
|
||||
// Sort order arrow
|
||||
const float ellipsis_max = cell_r.Max.x - w_arrow - w_sort_text;
|
||||
const float ellipsis_max = ImMax(cell_r.Max.x - w_arrow - w_sort_text, label_pos.x);
|
||||
if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
|
||||
{
|
||||
if (column->SortOrder != -1)
|
||||
@@ -3902,6 +3904,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFl
|
||||
columns->Count = columns_count;
|
||||
columns->Flags = flags;
|
||||
window->DC.CurrentColumns = columns;
|
||||
window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
||||
|
||||
columns->HostCursorPosY = window->DC.CursorPos.y;
|
||||
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
||||
@@ -4092,6 +4095,7 @@ void ImGui::EndColumns()
|
||||
window->DC.CurrentColumns = NULL;
|
||||
window->DC.ColumnsOffset.x = 0.0f;
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
NavUpdateCurrentWindowIsScrollPushableX();
|
||||
}
|
||||
|
||||
void ImGui::Columns(int columns_count, const char* id, bool border)
|
||||
|
||||
27
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
27
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.5 WIP
|
||||
// dear imgui, v1.89.6 WIP
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -638,7 +638,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
g.ActiveIdClickOffset = g.IO.MousePos - bb.Min;
|
||||
|
||||
const int mouse_button = g.ActiveIdMouseButton;
|
||||
if (IsMouseDown(mouse_button, test_owner_id))
|
||||
if (mouse_button == -1)
|
||||
{
|
||||
// Fallback for the rare situation were g.ActiveId was set programmatically or from another widget (e.g. #6304).
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (IsMouseDown(mouse_button, test_owner_id))
|
||||
{
|
||||
held = true;
|
||||
}
|
||||
@@ -4051,7 +4056,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
|
||||
return;
|
||||
g.InputTextDeactivatedState.ID = state->ID;
|
||||
g.InputTextDeactivatedState.TextA.resize(state->CurLenA + 1);
|
||||
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->CurLenA + 1);
|
||||
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data ? state->TextA.Data : "", state->CurLenA + 1);
|
||||
}
|
||||
|
||||
// Edit a string of text
|
||||
@@ -4306,7 +4311,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
|
||||
// Down the line we should have a cleaner library-wide concept of Selected vs Active.
|
||||
g.ActiveIdAllowOverlap = !io.MouseDown[0];
|
||||
g.WantTextInputNextFrame = 1;
|
||||
|
||||
// Edit in progress
|
||||
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX;
|
||||
@@ -4745,8 +4749,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
|
||||
// Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value)
|
||||
if (clear_active_id && g.ActiveId == id)
|
||||
// Otherwise request text input ahead for next frame.
|
||||
if (g.ActiveId == id && clear_active_id)
|
||||
ClearActiveID();
|
||||
else if (g.ActiveId == id)
|
||||
g.WantTextInputNextFrame = 1;
|
||||
|
||||
// Render frame
|
||||
if (!is_multiline)
|
||||
@@ -7092,7 +7099,7 @@ void ImGui::EndMainMenuBar()
|
||||
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
|
||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL);
|
||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
|
||||
|
||||
End();
|
||||
}
|
||||
@@ -7106,9 +7113,9 @@ static bool IsRootOfOpenMenuSet()
|
||||
|
||||
// Initially we used 'upper_popup->OpenParentId == window->IDStack.back()' to differentiate multiple menu sets from each others
|
||||
// (e.g. inside menu bar vs loose menu items) based on parent ID.
|
||||
// This would however prevent the use of e.g. PuhsID() user code submitting menus.
|
||||
// This would however prevent the use of e.g. PushID() user code submitting menus.
|
||||
// Previously this worked between popup and a first child menu because the first child menu always had the _ChildWindow flag,
|
||||
// making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects.
|
||||
// making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects.
|
||||
// Instead we don't treat Popup specifically (in order to consistently support menu features in them), maybe the first child menu of a Popup
|
||||
// doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first child menu.
|
||||
// In the end, lack of ID check made it so we could no longer differentiate between separate menu sets. To compensate for that, we at least check parent window nav layer.
|
||||
@@ -7116,7 +7123,9 @@ static bool IsRootOfOpenMenuSet()
|
||||
// open on hover, but that should be a lesser problem, because if such menus are close in proximity in window content then it won't feel weird and if they are far apart
|
||||
// it likely won't be a problem anyone runs into.
|
||||
const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
return (window->DC.NavLayerCurrent == upper_popup->ParentNavLayer && upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu));
|
||||
if (window->DC.NavLayerCurrent != upper_popup->ParentNavLayer)
|
||||
return false;
|
||||
return upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu) && ImGui::IsWindowChildOf(upper_popup->Window, window, true);
|
||||
}
|
||||
|
||||
bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
|
||||
Reference in New Issue
Block a user