Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
This commit is contained in:
omar
2019-03-28 15:44:04 +01:00
8 changed files with 93 additions and 69 deletions

121
imgui.cpp
View File

@ -2582,7 +2582,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
AutoFitOnlyGrows = false;
AutoFitChildAxises = 0x00;
AutoPosLastDirection = ImGuiDir_None;
HiddenFramesRegular = HiddenFramesForResize = 0;
HiddenFramesCanSkipItems = HiddenFramesCannotSkipItems = 0;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
@ -3411,41 +3411,52 @@ void ImGui::UpdateMouseWheel()
return;
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return;
// If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
ImGuiWindow* window = g.HoveredWindow;
ImGuiWindow* scroll_window = window;
while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoMouseInputs) && scroll_window->ParentWindow)
scroll_window = scroll_window->ParentWindow;
const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoMouseInputs);
if (g.IO.MouseWheel != 0.0f)
// Zoom / Scale window
// FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
{
if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
const float scale = new_font_scale / window->FontWindowScale;
window->FontWindowScale = new_font_scale;
if (!(window->Flags & ImGuiWindowFlags_ChildWindow))
{
// Zoom / Scale window
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
const float scale = new_font_scale / window->FontWindowScale;
window->FontWindowScale = new_font_scale;
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
window->Pos += offset;
window->Size *= scale;
window->SizeFull *= scale;
}
else if (!g.IO.KeyCtrl && scroll_allowed)
{
// Mouse wheel vertical scrolling
float scroll_amount = 5 * scroll_window->CalcFontSize();
scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f);
SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount);
window->Pos = ImFloor(window->Pos + offset);
window->Size = ImFloor(window->Size * scale);
window->SizeFull = ImFloor(window->SizeFull * scale);
}
return;
}
if (g.IO.MouseWheelH != 0.0f && scroll_allowed && !g.IO.KeyCtrl)
// Mouse wheel scrolling
// If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs) && window->ParentWindow)
window = window->ParentWindow;
const bool scroll_allowed = !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs);
if (scroll_allowed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f) && !g.IO.KeyCtrl)
{
// Mouse wheel horizontal scrolling (for hardware that supports it)
float scroll_amount = scroll_window->CalcFontSize();
SetWindowScrollX(scroll_window, scroll_window->Scroll.x - g.IO.MouseWheelH * scroll_amount);
ImVec2 max_step = (window->ContentsRegionRect.GetSize() + window->WindowPadding * 2.0f) * 0.67f;
// Vertical Mouse Wheel Scrolling (hold Shift to scroll horizontally)
if (g.IO.MouseWheel != 0.0f && !g.IO.KeyShift)
{
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step.y));
SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * scroll_step);
}
else if (g.IO.MouseWheel != 0.0f && g.IO.KeyShift)
{
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step.x));
SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheel * scroll_step);
}
// Horizontal Mouse Wheel Scrolling (for hardware that supports it)
if (g.IO.MouseWheelH != 0.0f && !g.IO.KeyShift)
{
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step.x));
SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_step);
}
}
}
@ -4941,7 +4952,7 @@ static ImVec2 CalcSizeContents(ImGuiWindow* window)
if (window->Collapsed)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
return window->SizeContents;
if (window->Hidden && window->HiddenFramesForResize == 0 && window->HiddenFramesRegular > 0)
if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
return window->SizeContents;
ImVec2 sz;
@ -5293,7 +5304,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update the Appearing flag
bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesForResize > 0);
const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0);
if (flags & ImGuiWindowFlags_Popup)
{
ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
@ -5429,20 +5440,20 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update contents size from last frame for auto-fitting (or use explicit size)
window->SizeContents = CalcSizeContents(window);
if (window->HiddenFramesRegular > 0)
window->HiddenFramesRegular--;
if (window->HiddenFramesForResize > 0)
window->HiddenFramesForResize--;
if (window->HiddenFramesCanSkipItems > 0)
window->HiddenFramesCanSkipItems--;
if (window->HiddenFramesCannotSkipItems > 0)
window->HiddenFramesCannotSkipItems--;
// Hide new windows for one frame until they calculate their size
if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api))
window->HiddenFramesForResize = 1;
window->HiddenFramesCannotSkipItems = 1;
// Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows)
// We reset Size/SizeContents for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size.
if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0)
{
window->HiddenFramesForResize = 1;
window->HiddenFramesCannotSkipItems = 1;
if (flags & ImGuiWindowFlags_AlwaysAutoResize)
{
if (!window_size_x_set_by_api)
@ -5559,7 +5570,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Pos = parent_window->DC.CursorPos;
}
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFramesForResize == 0);
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFramesCannotSkipItems == 0);
if (window_pos_with_pivot)
SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); // Position given a pivot (e.g. for centering)
else if ((flags & ImGuiWindowFlags_ChildMenu) != 0)
@ -5729,7 +5740,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
PushClipRect(viewport_rect.Min, viewport_rect.Max, true);
// Draw modal or window list full viewport dimming background (for other viewports we'll render them in EndFrame)
const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetFrontMostPopupModal() && window->HiddenFramesForResize <= 0;
const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetFrontMostPopupModal() && window->HiddenFramesCannotSkipItems <= 0;
const bool dim_bg_for_window_list = g.NavWindowingTargetAnim && ((window == g.NavWindowingTargetAnim->RootWindow) || (g.NavWindowingList && (window == g.NavWindowingList) && g.NavWindowingList->Viewport != g.NavWindowingTargetAnim->Viewport));
if (dim_bg_for_modal || dim_bg_for_window_list)
{
@ -6059,7 +6070,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
g.NextWindowData.Clear();
if (window->DockIsActive && !window->DockTabIsVisible)
window->HiddenFramesRegular = 1;
window->HiddenFramesCanSkipItems = 1;
if (flags & ImGuiWindowFlags_ChildWindow)
{
@ -6068,24 +6079,28 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
window->HiddenFramesRegular = 1;
window->HiddenFramesCanSkipItems = 1;
// Completely hide along with parent or if parent is collapsed
if (parent_window && (parent_window->Collapsed || parent_window->Hidden))
window->HiddenFramesRegular = 1;
window->HiddenFramesCanSkipItems = 1;
}
// Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point)
if (style.Alpha <= 0.0f)
window->HiddenFramesRegular = 1;
window->HiddenFramesCanSkipItems = 1;
// Update the Hidden flag
window->Hidden = (window->HiddenFramesRegular > 0) || (window->HiddenFramesForResize > 0);
window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0);
// Return false if we don't intend to display anything to allow user to perform an early out optimization
window->SkipItems = (window->Collapsed || !window->Active || window->Hidden) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesForResize <= 0;
// Update the SkipItems flag, used to early out of all items functions (no layout required)
bool skip_items = false;
if (window->Collapsed || !window->Active || window->Hidden)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0)
skip_items = true;
window->SkipItems = skip_items;
return !window->SkipItems;
return !skip_items;
}
// Old Begin() API with 5 parameters, avoid calling this version directly! Use SetNextWindowSize()/SetNextWindowBgAlpha() + Begin() instead.
@ -7369,7 +7384,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_
{
// Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one.
window->Hidden = true;
window->HiddenFramesRegular = 1;
window->HiddenFramesCanSkipItems = 1;
ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount);
}
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoDocking;
@ -9311,7 +9326,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
{
ImGuiWindow* tooltip_window = g.CurrentWindow;
tooltip_window->SkipItems = true;
tooltip_window->HiddenFramesRegular = 1;
tooltip_window->HiddenFramesCanSkipItems = 1;
}
}
@ -11403,7 +11418,7 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b
if (node->HostWindow == NULL && node->Windows.Size == 2 && node->Windows[0]->WasActive == false)
{
node->Windows[0]->Hidden = true;
node->Windows[0]->HiddenFramesRegular = 1;
node->Windows[0]->HiddenFramesCanSkipItems = 1;
}
// When reactivating a node with one or two loose window, the window pos/size/viewport are authoritative over the node storage.
@ -13505,13 +13520,13 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
if (node->VisibleWindow == window)
window->DockTabIsVisible = true;
// When we are about to select this tab (which will only be visible on the _next frame_), flag it with a non-zero HiddenFramesForResize.
// 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. It is especially important as nested TabBars would otherwise generate flicker in the form
// of one empty frame.
// Note that we set HiddenFramesForResize=2 because BeginDocked() is called just before Begin() has a chance to decrement the value. Effectively it'll be a 1 frame thing.
// Note that we set HiddenFramesCannotSkipItems=2 because BeginDocked() is called just before Begin() has a chance to decrement the value. Effectively it'll be a 1 frame thing.
if (!window->DockTabIsVisible && node->TabBar && node->TabBar->NextSelectedTabId == window->ID)
window->HiddenFramesForResize = 2;
window->HiddenFramesCannotSkipItems = 2;
// Update window flag
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) == 0);
@ -14058,7 +14073,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
(flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : "");
ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetWindowScrollMaxX(window), window->Scroll.y, GetWindowScrollMaxY(window));
ImGui::BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1);
ImGui::BulletText("Appearing: %d, Hidden: %d (Reg %d Resize %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesRegular, window->HiddenFramesForResize, window->SkipItems);
ImGui::BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems);
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL");
if (!window->NavRectRel[0].IsInverted())