Viewport: Added ImGuiWindowClass / SetNextWindowClass() (concept imported from Docking ImGuiDockFamily), which currently allows to overwrite viewport flags on a per-window basis. Exposed FindViewportByID(). Win32: Support for ParentViewportId. (#1542)

This commit is contained in:
omar 2019-01-02 19:29:33 +01:00
parent cfcad42b89
commit 0cabe4dedf
4 changed files with 40 additions and 7 deletions

View File

@ -454,8 +454,11 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
viewport->PlatformUserData = data;
// Select style and parent window
HWND parent_window = g_hWnd;
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &data->DwStyle, &data->DwExStyle);
HWND parent_window = NULL;
if (viewport->ParentViewportId != 0)
if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId))
parent_window = (HWND)parent_viewport->PlatformHandle;
// Create window
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };

View File

@ -4982,6 +4982,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
window->SizeContentsExplicit = ImVec2(0.0f, 0.0f);
}
window->WindowClass = g.NextWindowData.WindowClass;
if (g.NextWindowData.CollapsedCond)
SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond);
if (g.NextWindowData.FocusCond)
@ -5180,6 +5181,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsDecoration) == 0 || (flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0)
viewport_flags |= ImGuiViewportFlags_NoDecoration;
// We can overwrite viewport flags using ImGuiWindowClass (advanced users)
window->Viewport->ParentViewportId = window->WindowClass.ParentViewportId ? window->WindowClass.ParentViewportId : IMGUI_VIEWPORT_DEFAULT_ID;
if (window->WindowClass.ViewportFlagsOverrideMask)
viewport_flags = (viewport_flags & ~window->WindowClass.ViewportFlagsOverrideMask) | (window->WindowClass.ViewportFlagsOverrideValue & window->WindowClass.ViewportFlagsOverrideMask);
// We also tell the back-end that clearing the platform window won't be necessary, as our window is filling the viewport and we have disabled BgAlpha
viewport_flags |= ImGuiViewportFlags_NoRendererClear;
window->Viewport->Flags = viewport_flags;
@ -6343,6 +6349,12 @@ void ImGui::SetNextWindowViewport(ImGuiID id)
g.NextWindowData.ViewportId = id;
}
void ImGui::SetNextWindowClass(const ImGuiWindowClass* window_class)
{
ImGuiContext& g = *GImGui;
g.NextWindowData.WindowClass = *window_class;
}
// In window space (not screen space!)
ImVec2 ImGui::GetContentRegionMax()
{
@ -7253,7 +7265,7 @@ ImGuiViewport* ImGui::GetMainViewport()
return g.Viewports[0];
}
ImGuiViewportP* ImGui::FindViewportByID(ImGuiID id)
ImGuiViewport* ImGui::FindViewportByID(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (int n = 0; n < g.Viewports.Size; n++)
@ -7493,7 +7505,7 @@ static void ImGui::UpdateViewportsNewFrame()
ImGuiViewportP* viewport_hovered = NULL;
if (g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
{
viewport_hovered = g.IO.MouseHoveredViewport ? FindViewportByID(g.IO.MouseHoveredViewport) : NULL;
viewport_hovered = g.IO.MouseHoveredViewport ? (ImGuiViewportP*)FindViewportByID(g.IO.MouseHoveredViewport) : NULL;
if (viewport_hovered && (viewport_hovered->Flags & ImGuiViewportFlags_NoInputs))
{
// Back-end failed at honoring its contract if it returned a viewport with the _NoInputs flag.
@ -7646,7 +7658,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
// Attempt to restore saved viewport id (= window that hasn't been activated yet), try to restore the viewport based on saved 'window->ViewportPos' restored from .ini file
if (window->Viewport == NULL && window->ViewportId != 0)
{
window->Viewport = FindViewportByID(window->ViewportId);
window->Viewport = (ImGuiViewportP*)FindViewportByID(window->ViewportId);
if (window->Viewport == NULL && window->ViewportPos.x != FLT_MAX && window->ViewportPos.y != FLT_MAX)
window->Viewport = AddUpdateViewport(window, window->ID, window->ViewportPos, window->Size, ImGuiViewportFlags_None);
}
@ -7655,7 +7667,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
if (g.NextWindowData.ViewportCond)
{
// Code explicitly request a viewport
window->Viewport = FindViewportByID(g.NextWindowData.ViewportId);
window->Viewport = (ImGuiViewportP*)FindViewportByID(g.NextWindowData.ViewportId);
window->ViewportId = g.NextWindowData.ViewportId; // Store ID even if Viewport isn't resolved yet.
}
else if ((flags & ImGuiWindowFlags_ChildWindow) || (flags & ImGuiWindowFlags_ChildMenu))

18
imgui.h
View File

@ -114,6 +114,7 @@ struct ImGuiStyle; // Runtime data for styling/colors
struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbb][,ccccc]")
struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder)
struct ImGuiViewport; // Viewport (generally ~1 per window to output to at the OS level. Need per-platform support to use multiple viewports)
struct ImGuiWindowClass; // Window class (rare/advanced uses: provide hints to the platform back-end via altered viewport flags and parent/child info)
// Typedefs and Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file)
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
@ -276,6 +277,7 @@ namespace ImGui
IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin()
IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.
IMGUI_API void SetNextWindowViewport(ImGuiID viewport_id); // set next window viewport
IMGUI_API void SetNextWindowClass(const ImGuiWindowClass* window_class); // set next window class (rare/advanced uses: provide hints to the platform back-end via altered viewport flags and parent/child info)
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects.
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects.
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed().
@ -688,6 +690,7 @@ namespace ImGui
IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
IMGUI_API void RenderPlatformWindowsDefault(void* platform_arg = NULL, void* renderer_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport. may be reimplemented by user for custom rendering needs.
IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from back-end Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
IMGUI_API ImGuiViewport* FindViewportByID(ImGuiID id); // this is a helper for back-ends.
IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for back-ends. the type platform_handle is decided by the back-end (e.g. HWND, MyWindow*, GLFWwindow* etc.)
} // namespace ImGui
@ -1430,6 +1433,18 @@ struct ImGuiPayload
bool IsDelivery() const { return Delivery; }
};
// [BETA] Rarely used / very advanced uses only. Use with SetNextWindowClass() function.
// Provide hints to the platform back-end via altered viewport flags (enable/disable OS decoration, OS task bar icons, etc.) and OS level parent/child relationships.
struct ImGuiWindowClass
{
ImGuiID ClassId; // User data. 0 = Default class (unclassed)
ImGuiID ParentViewportId; // Hint for the platform back-end. If non-zero, the platform back-end can create a parent<>child relationship between the platform windows. Not conforming back-ends are free to e.g. parent every viewport to the main viewport or not.
ImGuiViewportFlags ViewportFlagsOverrideMask; // Viewport flags to override when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis.
ImGuiViewportFlags ViewportFlagsOverrideValue; // Viewport flags values to override when a window of this class owns a viewport.
ImGuiWindowClass() { ClassId = 0; ParentViewportId = 0; ViewportFlagsOverrideMask = ViewportFlagsOverrideValue = 0x00; }
};
//-----------------------------------------------------------------------------
// Obsolete functions (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
//-----------------------------------------------------------------------------
@ -2235,6 +2250,7 @@ struct ImGuiViewport
ImVec2 Size; // Size of viewport in pixel
float DpiScale; // 1.0f = 96 DPI = No extra scale
ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame().
ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform back-end to setup a parent/child relationship between platform windows.
void* RendererUserData; // void* to hold custom data structure for the renderer (e.g. swap chain, frame-buffers etc.)
void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context)
@ -2243,7 +2259,7 @@ struct ImGuiViewport
bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position)
bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size)
ImGuiViewport() { ID = 0; Flags = 0; DpiScale = 0.0f; DrawData = NULL; RendererUserData = PlatformUserData = PlatformHandle = NULL; PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
ImGuiViewport() { ID = 0; Flags = 0; DpiScale = 0.0f; DrawData = NULL; ParentViewportId = 0; RendererUserData = PlatformUserData = PlatformHandle = NULL; PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); }
};

View File

@ -714,6 +714,7 @@ struct ImGuiNextWindowData
void* SizeCallbackUserData;
float BgAlphaVal;
ImGuiID ViewportId;
ImGuiWindowClass WindowClass;
ImVec2 MenuBarOffsetMinVal; // This is not exposed publicly, so we don't clear it.
ImGuiNextWindowData()
@ -733,6 +734,7 @@ struct ImGuiNextWindowData
void Clear()
{
PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = ViewportCond = 0;
WindowClass = ImGuiWindowClass();
}
};
@ -1121,6 +1123,7 @@ struct IMGUI_API ImGuiWindow
char* Name;
ImGuiID ID; // == ImHash(Name)
ImGuiWindowFlags Flags, FlagsPreviousFrame; // See enum ImGuiWindowFlags_
ImGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass()
ImGuiViewportP* Viewport; // Always set in Begin(), only inactive windows may have a NULL value here
ImGuiID ViewportId; // We backup the viewport id (since the viewport may disappear or never be created if the window is inactive)
ImVec2 ViewportPos; // We backup the viewport position (since the viewport may disappear or never be created if the window is inactive)
@ -1331,7 +1334,6 @@ namespace ImGui
IMGUI_API void UpdateMouseMovingWindow();
// Viewports
IMGUI_API ImGuiViewportP* FindViewportByID(ImGuiID id);
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
IMGUI_API void ShowViewportThumbnails();