diff --git a/imgui.cpp b/imgui.cpp index f2a28de3d..8aa2f974c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -745,6 +745,7 @@ static inline ImVec2 ConvertViewportPosToOsDesktopPos(const ImVec2& imgui_pos static inline ImVec2 ConvertOsDesktopPosToViewportPos(const ImVec2& os_pos, ImGuiViewport* viewport) { return os_pos - viewport->PlatformOsDesktopPos + viewport->Pos; } static void UpdateViewports(); static void UpdateWindowViewport(ImGuiWindow* window, bool window_pos_set_by_api); +static void SetCurrentViewport(ImGuiViewport* viewport); static void SetWindowViewportTranslateToPreservePlatformPos(ImGuiWindow* window, ImGuiViewport* old_viewport, ImGuiViewport* new_viewport); static void ResizeViewport(ImGuiViewport* viewport, const ImVec2& size); static void ResizeViewportTranslateWindows(int viewport_idx_min, int viewport_idx_max, float pos_x_delta, int idx_delta, ImGuiViewport* viewport_to_erase); @@ -893,6 +894,9 @@ ImGuiIO::ImGuiIO() ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; ImeWindowHandle = NULL; + memset(&PlatformInterface, 0, sizeof(PlatformInterface)); + memset(&RendererInterface, 0, sizeof(RendererInterface)); + #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS RenderDrawListsFn = NULL; #endif @@ -3347,6 +3351,7 @@ static void ImGui::UpdateViewports() ImGuiViewport* viewport_ref = g.IO.MousePosViewport ? FindViewportByID(g.IO.MousePosViewport) : g.Viewports[0]; const ImVec2 mouse_os_pos = ConvertViewportPosToOsDesktopPos(g.IO.MousePos, viewport_ref); + g.CurrentViewport = NULL; for (int n = 1; n < g.Viewports.Size; n++) { // Erase unused viewports @@ -3953,7 +3958,7 @@ void ImGui::Shutdown(ImGuiContext* context) g.FontStack.clear(); g.OpenPopupStack.clear(); g.CurrentPopupStack.clear(); - g.MouseViewport = g.MouseLastHoveredViewport = NULL; + g.CurrentViewport = g.MouseViewport = g.MouseLastViewport = g.MouseLastHoveredViewport = NULL; DestroyViewportsPlaformData(context); DestroyViewportsRendererData(context); for (int i = 0; i < g.Viewports.Size; i++) @@ -4283,6 +4288,8 @@ void ImGui::EndFrame() g.CurrentWindow->Active = false; End(); + SetCurrentViewport(NULL); + if (g.ActiveId == 0 && g.HoveredId == 0) { if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear @@ -4465,6 +4472,7 @@ static void ImGui::ResizeViewportTranslateWindows(int viewport_idx_min, int view { ImGuiContext& g = *GImGui; IM_ASSERT(pos_x_delta != 0.0f || idx_delta != 0); + IM_ASSERT(g.CurrentViewport == NULL); // We only resize at the beginning of the frame for (int n = 0; n < g.Windows.Size; n++) { ImGuiWindow* window = g.Windows[n]; @@ -4486,14 +4494,9 @@ static void ImGui::ResizeViewportTranslateWindows(int viewport_idx_min, int view static void ImGui::ResizeViewport(ImGuiViewport* viewport, const ImVec2& size) { ImGuiContext& g = *GImGui; - if (viewport->Size.x != size.x || viewport->Size.y != size.y) - { - // We defer translating windows to the beginning of the frame. - // Our viewport system already works with fully overlapped viewports, it's only certain user interactions that don't and they can't be performed while resizing. - viewport->Size = size; - //if (viewport->Idx + 1 < g.Viewports.Size) // If this isn't the last viewport, translate following viewports - // ResizeViewportTranslateWindows(viewport->Idx + 1, g.Viewports.Size, viewport->GetNextX() - g.Viewports[viewport->Idx + 1]->Pos.x, 0, NULL); - } + // We defer translating windows to the beginning of the frame. + // Our viewport system already works with fully overlapped viewports, it's only certain user interactions that don't and they can't be performed while resizing. + viewport->Size = size; if (viewport == g.Viewports[0]) { g.IO.DisplayPos = viewport->Pos; @@ -4501,6 +4504,18 @@ static void ImGui::ResizeViewport(ImGuiViewport* viewport, const ImVec2& size) } } +void ImGui::SetCurrentViewport(ImGuiViewport* viewport) +{ + ImGuiContext& g = *GImGui; + if (g.CurrentViewport == viewport) + return; + if (g.CurrentViewport && g.IO.PlatformInterface.EndViewport) + g.IO.PlatformInterface.EndViewport(g.CurrentViewport); + g.CurrentViewport = viewport; + if (g.CurrentViewport && g.IO.PlatformInterface.BeginViewport) + g.IO.PlatformInterface.BeginViewport(g.CurrentViewport); +} + ImGuiViewport* ImGui::Viewport(ImGuiID id, ImGuiViewportFlags flags, const ImVec2& os_desktop_pos, const ImVec2& size) { ImGuiContext& g = *GImGui; @@ -6318,6 +6333,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // VIEWPORT UpdateWindowViewport(window, window_pos_set_by_api); + SetCurrentViewport(window->Viewport); flags = window->Flags; if (p_open != NULL && window->Viewport->PlatformRequestClose && !(window->Viewport->Flags & ImGuiViewportFlags_MainViewport)) { diff --git a/imgui.h b/imgui.h index abe755984..54baff058 100644 --- a/imgui.h +++ b/imgui.h @@ -958,6 +958,10 @@ struct ImGuiPlatformInterface void (*SetWindowAlpha)(ImGuiViewport* viewport, float alpha); void (*RenderViewport)(ImGuiViewport* viewport); void (*SwapBuffers)(ImGuiViewport* viewport); + + // FIXME-DPI + void (*BeginViewport)(ImGuiViewport* viewport); // (Optional) Called during Begin() every time the viewport we are outputting into changes (viewport = next viewport) + void (*EndViewport)(ImGuiViewport* viewport); // (Optional) Called during Begin() every time the viewport we are outputting into changes (viewport = previous viewport) }; // (Optional) Setup required only if (io.ConfigFlags & ImGuiConfigFlags_EnableMultiViewport) is enabled @@ -966,9 +970,8 @@ struct ImGuiRendererInterface void (*CreateViewport)(ImGuiViewport* viewport); void (*DestroyViewport)(ImGuiViewport* viewport); void (*ResizeViewport)(ImGuiViewport* viewport, int w, int h); - void (*RenderViewport)(ImGuiViewport* viewport); // Setup render output, clear targets, call Renderer_RenderDrawData - void (*RenderDrawData)(ImDrawData* draw_data); // Render a ImDrawList (collection of ImDrawList) for the area covering (io.DisplayPos) to (io.DisplayPos + io.DisplaySize) - void (*SwapBuffers)(ImGuiViewport* viewport); // Call Present/SwapBuffers + void (*RenderViewport)(ImGuiViewport* viewport); // Setup render output, clear targets, call Renderer_RenderDrawData + void (*SwapBuffers)(ImGuiViewport* viewport); // Call Present/SwapBuffers }; // You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame(). diff --git a/imgui_internal.h b/imgui_internal.h index 11089ee53..56f20b0f9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -654,6 +654,7 @@ struct ImGuiContext // Viewports ImVectorViewports; + ImGuiViewport* CurrentViewport; ImGuiViewport* MouseViewport; ImGuiViewport* MouseLastViewport; ImGuiViewport* MouseLastHoveredViewport; @@ -783,6 +784,7 @@ struct ImGuiContext NextTreeNodeOpenVal = false; NextTreeNodeOpenCond = 0; + CurrentViewport = NULL; MouseViewport = NULL; MouseLastViewport = MouseLastHoveredViewport = NULL;