|
@@ -373,12 +373,12 @@ CODE
|
|
|
|
|
|
(Docking/Viewport Branch)
|
|
|
- 2019/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that:
|
|
|
- - reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore.
|
|
|
+ - reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore.
|
|
|
you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos)
|
|
|
- - likewise io.MousePos and GetMousePos() will use OS coordinates.
|
|
|
+ - likewise io.MousePos and GetMousePos() will use OS coordinates.
|
|
|
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
|
|
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- 2019/07/15 (1.72) - removed TreeAdvanceToLabelPos() which is rarely used and only does SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()). Kept redirection function (will obsolete).
|
|
|
- 2019/07/12 (1.72) - renamed ImFontAtlas::CustomRect to ImFontAtlasCustomRect. Kept redirection typedef (will obsolete).
|
|
@@ -586,17 +586,17 @@ CODE
|
|
|
Q: Where is the documentation?
|
|
|
A: This library is poorly documented at the moment and expects of the user to be acquainted with C/C++.
|
|
|
- Run the examples/ and explore them.
|
|
|
- - See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function.
|
|
|
- - The demo covers most features of Dear ImGui, so you can read the code and see its output.
|
|
|
+ - See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function.
|
|
|
+ - The demo covers most features of Dear ImGui, so you can read the code and see its output.
|
|
|
- See documentation and comments at the top of imgui.cpp + effectively imgui.h.
|
|
|
- - Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the examples/
|
|
|
+ - Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the examples/
|
|
|
folder to explain how to integrate Dear ImGui with your own engine/application.
|
|
|
- - Your programming IDE is your friend, find the type or function declaration to find comments
|
|
|
+ - Your programming IDE is your friend, find the type or function declaration to find comments
|
|
|
associated to it.
|
|
|
|
|
|
Q: Which version should I get?
|
|
|
- A: I occasionally tag Releases (https://github.com/ocornut/imgui/releases) but it is generally safe
|
|
|
- and recommended to sync to master/latest. The library is fairly stable and regressions tend to be
|
|
|
+ A: I occasionally tag Releases (https://github.com/ocornut/imgui/releases) but it is generally safe
|
|
|
+ and recommended to sync to master/latest. The library is fairly stable and regressions tend to be
|
|
|
fixed fast when reported. You may also peak at the 'docking' branch which includes:
|
|
|
- Docking/Merging features (https://github.com/ocornut/imgui/issues/2109)
|
|
|
- Multi-viewport features (https://github.com/ocornut/imgui/issues/1542)
|
|
@@ -608,11 +608,11 @@ CODE
|
|
|
for a list of games/software which are publicly known to use dear imgui. Please add yours if you can!
|
|
|
|
|
|
Q: Why the odd dual naming, "Dear ImGui" vs "ImGui"?
|
|
|
- A: The library started its life as "ImGui" due to the fact that I didn't give it a proper name when
|
|
|
- when I released 1.0, and had no particular expectation that it would take off. However, the term IMGUI
|
|
|
- (immediate-mode graphical user interface) was coined before and is being used in variety of other
|
|
|
- situations (e.g. Unity uses it own implementation of the IMGUI paradigm).
|
|
|
- To reduce the ambiguity without affecting existing code bases, I have decided on an alternate,
|
|
|
+ A: The library started its life as "ImGui" due to the fact that I didn't give it a proper name when
|
|
|
+ when I released 1.0, and had no particular expectation that it would take off. However, the term IMGUI
|
|
|
+ (immediate-mode graphical user interface) was coined before and is being used in variety of other
|
|
|
+ situations (e.g. Unity uses it own implementation of the IMGUI paradigm).
|
|
|
+ To reduce the ambiguity without affecting existing code bases, I have decided on an alternate,
|
|
|
longer name "Dear ImGui" that people can use to refer to this specific library.
|
|
|
Please try to refer to this library as "Dear ImGui".
|
|
|
|
|
@@ -1090,7 +1090,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2&
|
|
|
// Navigation
|
|
|
static void NavUpdate();
|
|
|
static void NavUpdateWindowing();
|
|
|
-static void NavUpdateWindowingList();
|
|
|
+static void NavUpdateWindowingOverlay();
|
|
|
static void NavUpdateMoveResult();
|
|
|
static float NavUpdatePageUpPageDown(int allowed_dir_flags);
|
|
|
static inline void NavUpdateAnyRequestFlag();
|
|
@@ -2532,14 +2532,18 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons
|
|
|
|
|
|
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
|
|
|
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display.
|
|
|
-// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
|
|
|
-void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
|
|
|
+// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
|
|
|
+void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
if (text_end_full == NULL)
|
|
|
text_end_full = FindRenderedTextEnd(text);
|
|
|
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f);
|
|
|
|
|
|
+ //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255));
|
|
|
+ //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255));
|
|
|
+ //draw_list->AddLine(ImVec2(clip_max_x, pos_min.y), ImVec2(clip_max_x, pos_max.y), IM_COL32(255, 0, 0, 255));
|
|
|
+ // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels.
|
|
|
if (text_size.x > pos_max.x - pos_min.x)
|
|
|
{
|
|
|
// Hello wo...
|
|
@@ -2547,15 +2551,33 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min,
|
|
|
// min max ellipsis_max
|
|
|
// <-> this is generally some padding value
|
|
|
|
|
|
- // FIXME-STYLE: RenderPixelEllipsis() style should use actual font data.
|
|
|
const ImFont* font = draw_list->_Data->Font;
|
|
|
const float font_size = draw_list->_Data->FontSize;
|
|
|
- const int ellipsis_dot_count = 3;
|
|
|
- const float ellipsis_width = (1.0f + 1.0f) * ellipsis_dot_count - 1.0f;
|
|
|
const char* text_end_ellipsis = NULL;
|
|
|
|
|
|
- float text_width = ImMax((pos_max.x - ellipsis_width) - pos_min.x, 1.0f);
|
|
|
- float text_size_clipped_x = font->CalcTextSizeA(font_size, text_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
|
|
|
+ ImWchar ellipsis_char = font->EllipsisChar;
|
|
|
+ int ellipsis_char_count = 1;
|
|
|
+ if (ellipsis_char == (ImWchar)-1)
|
|
|
+ {
|
|
|
+ ellipsis_char = (ImWchar)'.';
|
|
|
+ ellipsis_char_count = 3;
|
|
|
+ }
|
|
|
+ const ImFontGlyph* glyph = font->FindGlyph(ellipsis_char);
|
|
|
+
|
|
|
+ float ellipsis_glyph_width = glyph->X1; // Width of the glyph with no padding on either side
|
|
|
+ float ellipsis_total_width = ellipsis_glyph_width; // Full width of entire ellipsis
|
|
|
+
|
|
|
+ if (ellipsis_char_count > 1)
|
|
|
+ {
|
|
|
+ // Full ellipsis size without free spacing after it.
|
|
|
+ const float spacing_between_dots = 1.0f * (draw_list->_Data->FontSize / font->FontSize);
|
|
|
+ ellipsis_glyph_width = glyph->X1 - glyph->X0 + spacing_between_dots;
|
|
|
+ ellipsis_total_width = ellipsis_glyph_width * (float)ellipsis_char_count - spacing_between_dots;
|
|
|
+ }
|
|
|
+
|
|
|
+ // We can now claim the space between pos_max.x and ellipsis_max.x
|
|
|
+ const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f);
|
|
|
+ float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
|
|
|
if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
|
|
|
{
|
|
|
// Always display at least 1 character if there's no room for character + ellipsis
|
|
@@ -2564,15 +2586,20 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min,
|
|
|
}
|
|
|
while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
|
|
|
{
|
|
|
- // Trim trailing space before ellipsis
|
|
|
+ // Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text)
|
|
|
text_end_ellipsis--;
|
|
|
text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte
|
|
|
}
|
|
|
- RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
|
|
|
|
|
|
- const float ellipsis_x = pos_min.x + text_size_clipped_x + 1.0f;
|
|
|
- if (ellipsis_x + ellipsis_width - 1.0f <= ellipsis_max_x)
|
|
|
- RenderPixelEllipsis(draw_list, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_dot_count);
|
|
|
+ // Render text, render ellipsis
|
|
|
+ RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
|
|
|
+ float ellipsis_x = pos_min.x + text_size_clipped_x;
|
|
|
+ if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x)
|
|
|
+ for (int i = 0; i < ellipsis_char_count; i++)
|
|
|
+ {
|
|
|
+ font->RenderChar(draw_list, font_size, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char);
|
|
|
+ ellipsis_x += ellipsis_glyph_width;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -3059,8 +3086,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
|
|
|
{
|
|
|
// Navigation processing 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
|
|
|
+ // (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
|
|
|
// thousands of item, but at least NavMoveRequest is only set on user interaction, aka maximum once a frame.
|
|
|
// We could early out with "if (is_clipped && !g.NavInitRequest) return false;" but when we wouldn't be able
|
|
|
// to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick).
|
|
@@ -3505,7 +3532,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // Try to merge the window back into the main viewport.
|
|
|
+ // Try to merge the window back into the main viewport.
|
|
|
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
|
|
|
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
|
|
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
|
|
@@ -3830,7 +3857,7 @@ static void NewFrameSanityChecks()
|
|
|
IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!");
|
|
|
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!");
|
|
|
IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting.");
|
|
|
- IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
|
|
|
+ IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
|
|
|
for (int n = 0; n < ImGuiKey_COUNT; n++)
|
|
|
IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)");
|
|
|
|
|
@@ -4291,7 +4318,7 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
|
|
+ // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
|
|
// May trigger for you if you are using PrimXXX functions incorrectly.
|
|
|
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
|
|
IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size);
|
|
@@ -4300,7 +4327,7 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
|
|
|
|
|
|
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
|
|
|
// If this assert triggers because you are drawing lots of stuff manually:
|
|
|
- // - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
|
|
|
+ // - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
|
|
|
// Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics window to inspect draw list contents.
|
|
|
// - If you want large meshes with more than 64K vertices, you can either:
|
|
|
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer back-end, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
|
|
@@ -4309,9 +4336,9 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
|
|
|
// (B) Or handle 32-bits indices in your renderer back-end, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
|
|
|
// Most example back-ends already support this. For example, the OpenGL example code detect index size at compile-time:
|
|
|
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
|
|
- // Your own engine or render API may use different parameters or function calls to specify index sizes.
|
|
|
+ // Your own engine or render API may use different parameters or function calls to specify index sizes.
|
|
|
// 2 and 4 bytes indices are generally supported by most graphics API.
|
|
|
- // - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
|
|
|
+ // - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
|
|
|
// the 64K limit to split your draw commands in multiple draw lists.
|
|
|
if (sizeof(ImDrawIdx) == 2)
|
|
|
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
|
|
@@ -4493,8 +4520,8 @@ void ImGui::EndFrame()
|
|
|
EndFrameDrawDimmedBackgrounds();
|
|
|
|
|
|
// Show CTRL+TAB list window
|
|
|
- if (g.NavWindowingTarget)
|
|
|
- NavUpdateWindowingList();
|
|
|
+ if (g.NavWindowingTarget != NULL)
|
|
|
+ NavUpdateWindowingOverlay();
|
|
|
|
|
|
SetCurrentViewport(NULL, NULL);
|
|
|
|
|
@@ -4560,7 +4587,7 @@ void ImGui::Render()
|
|
|
EndFrame();
|
|
|
g.FrameCountRendered = g.FrameCount;
|
|
|
g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
|
|
|
-
|
|
|
+
|
|
|
// Add background ImDrawList (for each active viewport)
|
|
|
for (int n = 0; n != g.Viewports.Size; n++)
|
|
|
{
|
|
@@ -4683,7 +4710,7 @@ static void FindHoveredWindow()
|
|
|
if (hole_bb.Contains(g.IO.MousePos - window->Pos))
|
|
|
continue;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (hovered_window == NULL)
|
|
|
hovered_window = window;
|
|
|
if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow))
|
|
@@ -4731,7 +4758,7 @@ int ImGui::GetKeyIndex(ImGuiKey imgui_key)
|
|
|
// Note that imgui doesn't know the semantic of each entry of io.KeysDown[]. Use your own indices/enums according to how your back-end/engine stored them into io.KeysDown[]!
|
|
|
bool ImGui::IsKeyDown(int user_key_index)
|
|
|
{
|
|
|
- if (user_key_index < 0)
|
|
|
+ if (user_key_index < 0)
|
|
|
return false;
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
|
@@ -4963,7 +4990,7 @@ bool ImGui::IsItemFocused()
|
|
|
if (g.NavId == 0 || g.NavDisableHighlight || g.NavId != window->DC.LastItemId)
|
|
|
return false;
|
|
|
|
|
|
- // Special handling for the dummy item after Begin() which represent the title bar or tab.
|
|
|
+ // Special handling for the dummy item after Begin() which represent the title bar or tab.
|
|
|
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
|
|
if (window->DC.LastItemId == window->ID && window->WriteAccessed)
|
|
|
return false;
|
|
@@ -5650,7 +5677,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
|
|
}
|
|
|
|
|
|
// Title bar
|
|
|
- // (when docked, DockNode are drawing their own title bar. Individual windows however do NOT set the _NoTitleBar flag,
|
|
|
+ // (when docked, DockNode are drawing their own title bar. Individual windows however do NOT set the _NoTitleBar flag,
|
|
|
// in order for their pos/size to be matching their undocking state.)
|
|
|
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
|
|
{
|
|
@@ -5718,7 +5745,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|
|
ImGuiWindowFlags flags = window->Flags;
|
|
|
|
|
|
const bool has_close_button = (p_open != NULL);
|
|
|
- const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse);
|
|
|
+ const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse) && (style.WindowMenuButtonPosition != ImGuiDir_None);
|
|
|
|
|
|
// Close & Collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer)
|
|
|
const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
|
@@ -6195,7 +6222,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
|
|
|
// For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
|
|
|
// won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
|
|
|
- // Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
|
|
|
+ // Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
|
|
|
// but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
|
|
|
if (is_short_lived_floating_window && (flags & ImGuiWindowFlags_Modal) == 0)
|
|
|
viewport_flags |= ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick;
|
|
@@ -6321,7 +6348,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
window->OuterRectClipped.ClipWith(host_rect);
|
|
|
|
|
|
// Inner rectangle
|
|
|
- // Not affected by window border size. Used by:
|
|
|
+ // Not affected by window border size. Used by:
|
|
|
// - InnerClipRect
|
|
|
// - ScrollToBringRectIntoView()
|
|
|
// - NavUpdatePageUpPageDown()
|
|
@@ -6586,7 +6613,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
|
|
|
// When we are about to select this tab (which will only be visible on the _next frame_), flag it with a non-zero HiddenFramesCannotSkipItems.
|
|
|
// This will have the important effect of actually returning true in Begin() and not setting SkipItems, allowing an earlier submission of the window contents.
|
|
|
- // This is analogous to regular windows being hidden from one frame.
|
|
|
+ // This is analogous to regular windows being hidden from one frame.
|
|
|
// It is especially important as e.g. nested TabBars would otherwise generate flicker in the form of one empty frame, or focus requests won't be processed.
|
|
|
if (window->DockIsActive && !window->DockTabIsVisible)
|
|
|
{
|
|
@@ -6787,7 +6814,7 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind
|
|
|
if (window != ignore_window && window->WasActive && !(window->Flags & ImGuiWindowFlags_ChildWindow))
|
|
|
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
|
|
{
|
|
|
- // FIXME-DOCKING: This is failing (lagging by one frame) for docked windows.
|
|
|
+ // FIXME-DOCKING: This is failing (lagging by one frame) for docked windows.
|
|
|
// If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B.
|
|
|
// We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update)
|
|
|
// to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself?
|
|
@@ -7410,11 +7437,11 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi
|
|
|
}
|
|
|
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
|
-void ImGui::SetNextWindowPosCenter(ImGuiCond cond)
|
|
|
-{
|
|
|
- ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
|
- SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, cond, ImVec2(0.5f, 0.5f));
|
|
|
- SetNextWindowViewport(viewport->ID);
|
|
|
+void ImGui::SetNextWindowPosCenter(ImGuiCond cond)
|
|
|
+{
|
|
|
+ ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
|
+ SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, cond, ImVec2(0.5f, 0.5f));
|
|
|
+ SetNextWindowViewport(viewport->ID);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -8818,7 +8845,7 @@ void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const Im
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
|
|
|
- ImGui::NavMoveRequestCancel();
|
|
|
+ NavMoveRequestCancel();
|
|
|
g.NavMoveDir = move_dir;
|
|
|
g.NavMoveClipDir = clip_dir;
|
|
|
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
|
@@ -9159,10 +9186,10 @@ static void ImGui::NavUpdate()
|
|
|
g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
|
|
|
if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
|
{
|
|
|
- if ((allowed_dir_flags & (1<<ImGuiDir_Left)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadLeft, ImGuiNavInput_KeyLeft_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Left;
|
|
|
- if ((allowed_dir_flags & (1<<ImGuiDir_Right)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadRight,ImGuiNavInput_KeyRight_,ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Right;
|
|
|
- if ((allowed_dir_flags & (1<<ImGuiDir_Up)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadUp, ImGuiNavInput_KeyUp_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Up;
|
|
|
- if ((allowed_dir_flags & (1<<ImGuiDir_Down)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadDown, ImGuiNavInput_KeyDown_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Down;
|
|
|
+ if ((allowed_dir_flags & (1 << ImGuiDir_Left)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadLeft, ImGuiNavInput_KeyLeft_, ImGuiInputReadMode_Repeat)) { g.NavMoveDir = ImGuiDir_Left; }
|
|
|
+ if ((allowed_dir_flags & (1 << ImGuiDir_Right)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadRight,ImGuiNavInput_KeyRight_,ImGuiInputReadMode_Repeat)) { g.NavMoveDir = ImGuiDir_Right; }
|
|
|
+ if ((allowed_dir_flags & (1 << ImGuiDir_Up)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadUp, ImGuiNavInput_KeyUp_, ImGuiInputReadMode_Repeat)) { g.NavMoveDir = ImGuiDir_Up; }
|
|
|
+ if ((allowed_dir_flags & (1 << ImGuiDir_Down)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadDown, ImGuiNavInput_KeyDown_, ImGuiInputReadMode_Repeat)) { g.NavMoveDir = ImGuiDir_Down; }
|
|
|
}
|
|
|
g.NavMoveClipDir = g.NavMoveDir;
|
|
|
}
|
|
@@ -9175,7 +9202,8 @@ static void ImGui::NavUpdate()
|
|
|
g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
|
|
|
}
|
|
|
|
|
|
- // Update PageUp/PageDown scroll
|
|
|
+ // Update PageUp/PageDown/Home/End scroll
|
|
|
+ // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
|
|
|
float nav_scoring_rect_offset_y = 0.0f;
|
|
|
if (nav_keyboard_active)
|
|
|
nav_scoring_rect_offset_y = NavUpdatePageUpPageDown(allowed_dir_flags);
|
|
@@ -9294,8 +9322,18 @@ static void ImGui::NavUpdateMoveResult()
|
|
|
// Scroll to keep newly navigated item fully into view.
|
|
|
if (g.NavLayer == 0)
|
|
|
{
|
|
|
- ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos);
|
|
|
- ImVec2 delta_scroll = ScrollToBringRectIntoView(result->Window, rect_abs);
|
|
|
+ ImVec2 delta_scroll;
|
|
|
+ if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_ScrollToEdge)
|
|
|
+ {
|
|
|
+ float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
|
|
|
+ delta_scroll.y = result->Window->Scroll.y - scroll_target;
|
|
|
+ SetScrollY(result->Window, scroll_target);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos);
|
|
|
+ delta_scroll = ScrollToBringRectIntoView(result->Window, rect_abs);
|
|
|
+ }
|
|
|
|
|
|
// Offset our result position so mouse position can be applied immediately after in NavUpdate()
|
|
|
result->RectRel.TranslateX(-delta_scroll.x);
|
|
@@ -9314,6 +9352,7 @@ static void ImGui::NavUpdateMoveResult()
|
|
|
g.NavMoveFromClampedRefRect = false;
|
|
|
}
|
|
|
|
|
|
+// Handle PageUp/PageDown/Home/End keys
|
|
|
static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -9323,9 +9362,11 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags)
|
|
|
return 0.0f;
|
|
|
|
|
|
ImGuiWindow* window = g.NavWindow;
|
|
|
- bool page_up_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageUp]) && (allowed_dir_flags & (1 << ImGuiDir_Up));
|
|
|
- bool page_down_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageDown]) && (allowed_dir_flags & (1 << ImGuiDir_Down));
|
|
|
- if (page_up_held != page_down_held) // If either (not both) are pressed
|
|
|
+ const bool page_up_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageUp]) && (allowed_dir_flags & (1 << ImGuiDir_Up));
|
|
|
+ const bool page_down_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageDown]) && (allowed_dir_flags & (1 << ImGuiDir_Down));
|
|
|
+ const bool home_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_Home]) && (allowed_dir_flags & (1 << ImGuiDir_Up));
|
|
|
+ const bool end_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_End]) && (allowed_dir_flags & (1 << ImGuiDir_Down));
|
|
|
+ if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed
|
|
|
{
|
|
|
if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll)
|
|
|
{
|
|
@@ -9334,26 +9375,49 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags)
|
|
|
SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
|
|
|
else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true))
|
|
|
SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
|
|
|
+ else if (home_pressed)
|
|
|
+ SetScrollY(window, 0.0f);
|
|
|
+ else if (end_pressed)
|
|
|
+ SetScrollY(window, window->ScrollMax.y);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- const ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
+ ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
|
|
float nav_scoring_rect_offset_y = 0.0f;
|
|
|
if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageUp], true))
|
|
|
{
|
|
|
nav_scoring_rect_offset_y = -page_offset_y;
|
|
|
- g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset, we intentionally request the opposite direction (so we can always land on the last item)
|
|
|
+ g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
|
|
|
g.NavMoveClipDir = ImGuiDir_Up;
|
|
|
g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
}
|
|
|
else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true))
|
|
|
{
|
|
|
nav_scoring_rect_offset_y = +page_offset_y;
|
|
|
- g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset, we intentionally request the opposite direction (so we can always land on the last item)
|
|
|
+ g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
|
|
|
g.NavMoveClipDir = ImGuiDir_Down;
|
|
|
g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
}
|
|
|
+ else if (home_pressed)
|
|
|
+ {
|
|
|
+ // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
|
|
|
+ // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
|
|
|
+ // Preserve current horizontal position if we have any.
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
+ g.NavMoveDir = ImGuiDir_Down;
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
+ }
|
|
|
+ else if (end_pressed)
|
|
|
+ {
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
+ g.NavMoveDir = ImGuiDir_Up;
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
+ }
|
|
|
return nav_scoring_rect_offset_y;
|
|
|
}
|
|
|
}
|
|
@@ -9559,7 +9623,7 @@ static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window)
|
|
|
}
|
|
|
|
|
|
// Overlay displayed when using CTRL+TAB. Called by EndFrame().
|
|
|
-void ImGui::NavUpdateWindowingList()
|
|
|
+void ImGui::NavUpdateWindowingOverlay()
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
IM_ASSERT(g.NavWindowingTarget != NULL);
|
|
@@ -10471,7 +10535,7 @@ void ImGui::TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& o
|
|
|
// 1) We test if ImGuiConfigFlags_ViewportsEnable was just toggled, which allows us to conveniently
|
|
|
// translate imgui windows from OS-window-local to absolute coordinates or vice-versa.
|
|
|
// 2) If it's not going to fit into the new size, keep it at same absolute position.
|
|
|
- // One problem with this is that most Win32 applications doesn't update their render while dragging,
|
|
|
+ // One problem with this is that most Win32 applications doesn't update their render while dragging,
|
|
|
// and so the window will appear to teleport when releasing the mouse.
|
|
|
const bool translate_all_windows = (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) != (g.ConfigFlagsLastFrame & ImGuiConfigFlags_ViewportsEnable);
|
|
|
ImRect test_still_fit_rect(old_pos, old_pos + viewport->Size);
|
|
@@ -10498,7 +10562,7 @@ void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale)
|
|
|
}
|
|
|
|
|
|
// If the back-end doesn't set MouseLastHoveredViewport or doesn't honor ImGuiViewportFlags_NoInputs, we do a search ourselves.
|
|
|
-// A) It won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
|
|
|
+// A) It won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
|
|
|
// B) It requires Platform_GetWindowFocus to be implemented by back-end.
|
|
|
static ImGuiViewportP* FindHoveredViewportFromPlatformWindowStack(const ImVec2 mouse_platform_pos)
|
|
|
{
|
|
@@ -10566,7 +10630,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|
|
g.Windows[window_n]->Viewport = NULL;
|
|
|
g.Windows[window_n]->ViewportOwned = false;
|
|
|
}
|
|
|
- if (viewport == g.MouseLastHoveredViewport)
|
|
|
+ if (viewport == g.MouseLastHoveredViewport)
|
|
|
g.MouseLastHoveredViewport = NULL;
|
|
|
g.Viewports.erase(g.Viewports.Data + n);
|
|
|
|
|
@@ -10582,7 +10646,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|
|
const bool platform_funcs_available = viewport->PlatformWindowCreated;
|
|
|
if ((g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
|
|
{
|
|
|
- // Update Position and Size (from Platform Window to ImGui) if requested.
|
|
|
+ // Update Position and Size (from Platform Window to ImGui) if requested.
|
|
|
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
|
|
|
if (!(viewport->Flags & ImGuiViewportFlags_Minimized) && platform_funcs_available)
|
|
|
{
|
|
@@ -10652,7 +10716,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|
|
else
|
|
|
{
|
|
|
// If the back-end doesn't know how to honor ImGuiViewportFlags_NoInputs, we do a search ourselves. Note that this search:
|
|
|
- // A) won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
|
|
|
+ // A) won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
|
|
|
// B) uses LastFrameAsRefViewport as a flawed replacement for the last time a window was focused (we could/should fix that by introducing Focus functions in PlatformIO)
|
|
|
viewport_hovered = FindHoveredViewportFromPlatformWindowStack(g.IO.MousePos);
|
|
|
}
|
|
@@ -10664,11 +10728,11 @@ static void ImGui::UpdateViewportsNewFrame()
|
|
|
// Update mouse reference viewport
|
|
|
// (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode)
|
|
|
if (g.MovingWindow)
|
|
|
- g.MouseViewport = g.MovingWindow->Viewport;
|
|
|
+ g.MouseViewport = g.MovingWindow->Viewport;
|
|
|
else
|
|
|
g.MouseViewport = g.MouseLastHoveredViewport;
|
|
|
|
|
|
- // When dragging something, always refer to the last hovered viewport.
|
|
|
+ // When dragging something, always refer to the last hovered viewport.
|
|
|
// - when releasing a moving window we will revert to aiming behind (at viewport_hovered)
|
|
|
// - when we are between viewports, our dragged preview will tend to show in the last viewport _even_ if we don't have tooltips in their viewports (when lacking monitor info)
|
|
|
// - consider the case of holding on a menu item to browse child menus: even thou a mouse button is held, there's no active id because menu items only react on mouse release.
|
|
@@ -10909,7 +10973,7 @@ void ImGui::UpdatePlatformWindows()
|
|
|
{
|
|
|
ImGuiViewportP* viewport = g.Viewports[i];
|
|
|
|
|
|
- // Destroy platform window if the viewport hasn't been submitted or if it is hosting a hidden window
|
|
|
+ // Destroy platform window if the viewport hasn't been submitted or if it is hosting a hidden window
|
|
|
// (the implicit/fallback Debug##Default window will be registering its viewport then be disabled, causing a dummy DestroyPlatformWindow to be made each frame)
|
|
|
bool destroy_platform_window = false;
|
|
|
destroy_platform_window |= (viewport->LastFrameActive < g.FrameCount - 1);
|
|
@@ -10982,7 +11046,7 @@ void ImGui::UpdatePlatformWindows()
|
|
|
// Show window
|
|
|
g.PlatformIO.Platform_ShowWindow(viewport);
|
|
|
|
|
|
- // Even without focus, we assume the window becomes front-most.
|
|
|
+ // Even without focus, we assume the window becomes front-most.
|
|
|
// This is useful for our platform z-order heuristic when io.MouseHoveredViewport is not available.
|
|
|
if (viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
|
|
|
viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
|
|
@@ -10993,7 +11057,7 @@ void ImGui::UpdatePlatformWindows()
|
|
|
}
|
|
|
|
|
|
// Update our implicit z-order knowledge of platform windows, which is used when the back-end cannot provide io.MouseHoveredViewport.
|
|
|
- // When setting Platform_GetWindowFocus, it is expected that the platform back-end can handle calls without crashing if it doesn't have data stored.
|
|
|
+ // When setting Platform_GetWindowFocus, it is expected that the platform back-end can handle calls without crashing if it doesn't have data stored.
|
|
|
if (g.PlatformIO.Platform_GetWindowFocus != NULL)
|
|
|
{
|
|
|
ImGuiViewportP* focused_viewport = NULL;
|
|
@@ -11061,7 +11125,7 @@ static int ImGui::FindPlatformMonitorForPos(const ImVec2& pos)
|
|
|
|
|
|
// Search for the monitor with the largest intersection area with the given rectangle
|
|
|
// We generally try to avoid searching loops but the monitor count should be very small here
|
|
|
-// FIXME-OPT: We could test the last monitor used for that viewport first, and early
|
|
|
+// FIXME-OPT: We could test the last monitor used for that viewport first, and early
|
|
|
static int ImGui::FindPlatformMonitorForRect(const ImRect& rect)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -11070,7 +11134,7 @@ static int ImGui::FindPlatformMonitorForRect(const ImRect& rect)
|
|
|
if (monitor_count <= 1)
|
|
|
return monitor_count - 1;
|
|
|
|
|
|
- // Use a minimum threshold of 1.0f so a zero-sized rect won't false positive, and will still find the correct monitor given its position.
|
|
|
+ // Use a minimum threshold of 1.0f so a zero-sized rect won't false positive, and will still find the correct monitor given its position.
|
|
|
// This is necessary for tooltips which always resize down to zero at first.
|
|
|
const float surface_threshold = ImMax(rect.GetWidth() * rect.GetHeight() * 0.5f, 1.0f);
|
|
|
int best_monitor_n = -1;
|
|
@@ -11121,12 +11185,12 @@ void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport)
|
|
|
|
|
|
void ImGui::DestroyPlatformWindows()
|
|
|
{
|
|
|
- // We call the destroy window on every viewport (including the main viewport, index 0) to give a chance to the back-end
|
|
|
- // to clear any data they may have stored in e.g. PlatformUserData, RendererUserData.
|
|
|
- // It is convenient for the platform back-end code to store something in the main viewport, in order for e.g. the mouse handling
|
|
|
+ // We call the destroy window on every viewport (including the main viewport, index 0) to give a chance to the back-end
|
|
|
+ // to clear any data they may have stored in e.g. PlatformUserData, RendererUserData.
|
|
|
+ // It is convenient for the platform back-end code to store something in the main viewport, in order for e.g. the mouse handling
|
|
|
// code to operator a consistent manner.
|
|
|
// It is expected that the back-end can handle calls to Renderer_DestroyWindow/Platform_DestroyWindow without
|
|
|
- // crashing if it doesn't have data stored.
|
|
|
+ // crashing if it doesn't have data stored.
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
for (int i = 0; i < g.Viewports.Size; i++)
|
|
|
DestroyPlatformWindow(g.Viewports[i]);
|
|
@@ -11172,7 +11236,7 @@ struct ImGuiDockRequest
|
|
|
{
|
|
|
ImGuiDockRequestType Type;
|
|
|
ImGuiWindow* DockTargetWindow; // Destination/Target Window to dock into (may be a loose window or a DockNode, might be NULL in which case DockTargetNode cannot be NULL)
|
|
|
- ImGuiDockNode* DockTargetNode; // Destination/Target Node to dock into
|
|
|
+ ImGuiDockNode* DockTargetNode; // Destination/Target Node to dock into
|
|
|
ImGuiWindow* DockPayload; // Source/Payload window to dock (may be a loose window or a DockNode), [Optional]
|
|
|
ImGuiDir DockSplitDir;
|
|
|
float DockSplitRatio;
|
|
@@ -11397,7 +11461,7 @@ void ImGui::DockContextUpdateUndocking(ImGuiContext* ctx)
|
|
|
DockBuilderRemoveNodeChildNodes(node->ID);
|
|
|
//dc->WantFullRebuild = true;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// Process full rebuild
|
|
|
#if 0
|
|
|
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C)))
|
|
@@ -11999,7 +12063,7 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b
|
|
|
{
|
|
|
DockNodeAddTabBar(node);
|
|
|
node->TabBar->SelectedTabId = node->TabBar->NextSelectedTabId = node->SelectedTabID;
|
|
|
-
|
|
|
+
|
|
|
// Add existing windows
|
|
|
for (int n = 0; n < node->Windows.Size - 1; n++)
|
|
|
TabBarAddTab(node->TabBar, ImGuiTabItemFlags_None, node->Windows[n]);
|
|
@@ -12367,7 +12431,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
|
|
// N+2: DockNodeUpdate(): node can create host window / Begin(): window becomes visible
|
|
|
// We could remove this frame if we could reliably calculate the expected window size during node update, before the Begin() code.
|
|
|
// It would require a generalization of CalcWindowExpectedSize(), probably extracting code away from Begin().
|
|
|
- // In reality it isn't very important as user quickly ends up with size data in .ini file.
|
|
|
+ // In reality it isn't very important as user quickly ends up with size data in .ini file.
|
|
|
if (node->IsVisible && node->HostWindow == NULL && node->IsFloatingNode() && node->IsLeafNode())
|
|
|
{
|
|
|
IM_ASSERT(node->Windows.Size > 0);
|
|
@@ -12459,7 +12523,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
|
|
// We set ImGuiWindowFlags_NoFocusOnAppearing because we don't want the host window to take full focus (e.g. steal NavWindow)
|
|
|
// But we still it bring it to the front of display. There's no way to choose this precise behavior via window flags.
|
|
|
// One simple case to ponder if: window A has a toggle to create windows B/C/D. Dock B/C/D together, clear the toggle and enable it again.
|
|
|
- // When reappearing B/C/D will request focus and be moved to the top of the display pile, but they are not linked to the dock host window
|
|
|
+ // When reappearing B/C/D will request focus and be moved to the top of the display pile, but they are not linked to the dock host window
|
|
|
// during the frame they appear. The dock host window would keep its old display order, and the sorting in EndFrame would move B/C/D back
|
|
|
// after the dock host window, losing their top-most status.
|
|
|
if (node->HostWindow->Appearing)
|
|
@@ -13035,7 +13099,7 @@ static void ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
// There is an edge case when docking into a dockspace which only has inactive nodes.
|
|
|
- // In this case DockNodeTreeFindNodeByPos() will have selected a leaf node which is inactive.
|
|
|
+ // In this case DockNodeTreeFindNodeByPos() will have selected a leaf node which is inactive.
|
|
|
// Because the inactive leaf node doesn't have proper pos/size yet, we'll use the root node as reference.
|
|
|
ImGuiDockNode* ref_node_for_rect = (host_node && !host_node->IsVisible) ? DockNodeGetRootNode(host_node) : host_node;
|
|
|
if (ref_node_for_rect)
|
|
@@ -13206,7 +13270,7 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
|
|
|
overlay_draw_lists[overlay_n]->AddLine(ImVec2(draw_r_in.Min.x, center.y), ImVec2(draw_r_in.Max.x, center.y), overlay_col_lines);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// Stop after ImGuiDir_None
|
|
|
if ((host_node && (host_node->GetMergedFlags() & ImGuiDockNodeFlags_NoSplit)) || g.IO.ConfigDockingNoSplit)
|
|
|
return;
|
|
@@ -13552,7 +13616,7 @@ ImGuiDockNode* ImGui::DockNodeTreeFindNodeByPos(ImGuiDockNode* node, ImVec2 pos)
|
|
|
return node->CentralNode;
|
|
|
return DockNodeTreeFindFallbackLeafNode(node);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
@@ -13684,7 +13748,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags fla
|
|
|
}
|
|
|
|
|
|
// Tips: Use with ImGuiDockNodeFlags_PassthruCentralNode!
|
|
|
-// The limitation with this call is that your window won't have a menu bar.
|
|
|
+// The limitation with this call is that your window won't have a menu bar.
|
|
|
// Even though we could pass window flags, it would also require the user to be able to call BeginMenuBar() somehow meaning we can't Begin/End in a single function.
|
|
|
// So if you want a menu bar you need to repeat this code manually ourselves. As with advanced other Docking API, we may change this function signature.
|
|
|
ImGuiID ImGui::DockSpaceOverViewport(ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class)
|
|
@@ -13933,7 +13997,7 @@ void ImGui::DockBuilderRemoveNodeDockedWindows(ImGuiID root_id, bool clear_persi
|
|
|
|
|
|
// If 'out_id_at_dir' or 'out_id_at_opposite_dir' are non NULL, the function will write out the ID of the two new nodes created.
|
|
|
// Return value is ID of the node at the specified direction, so same as (*out_id_at_dir) if that pointer is set.
|
|
|
-// FIXME-DOCK: We are not exposing nor using split_outer.
|
|
|
+// FIXME-DOCK: We are not exposing nor using split_outer.
|
|
|
ImGuiID ImGui::DockBuilderSplitNode(ImGuiID id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir)
|
|
|
{
|
|
|
ImGuiContext* ctx = GImGui;
|
|
@@ -14081,7 +14145,7 @@ void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_docks
|
|
|
|
|
|
if (dst_dock_id != 0)
|
|
|
{
|
|
|
- // Docked windows gets redocked into the new node hierarchy.
|
|
|
+ // Docked windows gets redocked into the new node hierarchy.
|
|
|
IMGUI_DEBUG_LOG_DOCKING("Remap live window '%s' 0x%08X -> '%s' 0x%08X\n", src_window_name, src_dock_id, dst_window_name, dst_dock_id);
|
|
|
DockBuilderDockWindow(dst_window_name, dst_dock_id);
|
|
|
}
|
|
@@ -14107,7 +14171,7 @@ void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_docks
|
|
|
if (src_windows.contains(window->ID))
|
|
|
continue;
|
|
|
|
|
|
- // Docked windows gets redocked into the new node hierarchy.
|
|
|
+ // Docked windows gets redocked into the new node hierarchy.
|
|
|
IMGUI_DEBUG_LOG_DOCKING("Remap window '%s' %08X -> %08X\n", window->Name, src_dock_id, dst_dock_id);
|
|
|
DockBuilderDockWindow(window->Name, dst_dock_id);
|
|
|
}
|
|
@@ -14360,7 +14424,7 @@ void ImGui::BeginAsDockableDragDropTarget(ImGuiWindow* window)
|
|
|
const bool is_explicit_target = g.IO.ConfigDockingWithShift || IsMouseHoveringRect(explicit_target_rect.Min, explicit_target_rect.Max);
|
|
|
|
|
|
// Preview docking request and find out split direction/ratio
|
|
|
- //const bool do_preview = true; // Ignore testing for payload->IsPreview() which removes one frame of delay, but breaks overlapping drop targets within the same window.
|
|
|
+ //const bool do_preview = true; // Ignore testing for payload->IsPreview() which removes one frame of delay, but breaks overlapping drop targets within the same window.
|
|
|
const bool do_preview = payload->IsPreview() || payload->IsDelivery();
|
|
|
if (do_preview && (node != NULL || allow_null_target_node))
|
|
|
{
|
|
@@ -14692,7 +14756,7 @@ static const char* GetClipboardTextFn_DefaultImpl(void*)
|
|
|
|
|
|
ItemCount item_count = 0;
|
|
|
PasteboardGetItemCount(main_clipboard, &item_count);
|
|
|
- for (int i = 0; i < item_count; i++)
|
|
|
+ for (ItemCount i = 0; i < item_count; i++)
|
|
|
{
|
|
|
PasteboardItemID item_id = 0;
|
|
|
PasteboardGetItemIdentifier(main_clipboard, i + 1, &item_id);
|
|
@@ -15096,8 +15160,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
for (int i = 0; i < g.PlatformIO.Monitors.Size; i++)
|
|
|
{
|
|
|
const ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[i];
|
|
|
- ImGui::BulletText("Monitor #%d: DPI %.0f%%\n MainMin (%.0f,%.0f), MainMax (%.0f,%.0f), MainSize (%.0f,%.0f)\n WorkMin (%.0f,%.0f), WorkMax (%.0f,%.0f), WorkSize (%.0f,%.0f)",
|
|
|
- i, mon.DpiScale * 100.0f,
|
|
|
+ ImGui::BulletText("Monitor #%d: DPI %.0f%%\n MainMin (%.0f,%.0f), MainMax (%.0f,%.0f), MainSize (%.0f,%.0f)\n WorkMin (%.0f,%.0f), WorkMax (%.0f,%.0f), WorkSize (%.0f,%.0f)",
|
|
|
+ i, mon.DpiScale * 100.0f,
|
|
|
mon.MainPos.x, mon.MainPos.y, mon.MainPos.x + mon.MainSize.x, mon.MainPos.y + mon.MainSize.y, mon.MainSize.x, mon.MainSize.y,
|
|
|
mon.WorkPos.x, mon.WorkPos.y, mon.WorkPos.x + mon.WorkSize.x, mon.WorkPos.y + mon.WorkSize.y, mon.WorkSize.x, mon.WorkSize.y);
|
|
|
}
|