mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Reworked modal/ctrl+tab dimming system to be entirely processed at end of the frame (backported 1dc3af3 from docking)
				
					
				
			This commit is contained in:
		
							
								
								
									
										105
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -946,7 +946,8 @@ static bool             UpdateWindowManualResize(ImGuiWindow* window, const ImVe | ||||
| static void             RenderWindowOuterBorders(ImGuiWindow* window); | ||||
| static void             RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); | ||||
| static void             RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); | ||||
| static void             EndFrameDrawDimmedBackgrounds(); | ||||
| static void             RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col); | ||||
| static void             RenderDimmedBackgrounds(); | ||||
|  | ||||
| // Viewports | ||||
| static void             UpdateViewportsNewFrame(); | ||||
| @@ -4442,9 +4443,58 @@ void ImGui::PopClipRect() | ||||
|     window->ClipRect = window->DrawList->_ClipRectStack.back(); | ||||
| } | ||||
|  | ||||
| static void ImGui::EndFrameDrawDimmedBackgrounds() | ||||
| static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col) | ||||
| { | ||||
|     // (This is currently empty, left here to facilitate sync/merge with docking branch) | ||||
|     if ((col & IM_COL32_A_MASK) == 0) | ||||
|         return; | ||||
|  | ||||
|     ImGuiViewportP* viewport = (ImGuiViewportP*)GetMainViewport(); | ||||
|     ImRect viewport_rect = viewport->GetMainRect(); | ||||
|  | ||||
|     // Draw behind window by moving the draw command at the FRONT of the draw list | ||||
|     { | ||||
|         ImDrawList* draw_list = window->RootWindow->DrawList; | ||||
|         draw_list->AddDrawCmd(); | ||||
|         draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // Ensure ImDrawCmd are not merged | ||||
|         draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col); | ||||
|         ImDrawCmd cmd = draw_list->CmdBuffer.back(); | ||||
|         IM_ASSERT(cmd.ElemCount == 6); | ||||
|         draw_list->CmdBuffer.pop_back(); | ||||
|         draw_list->CmdBuffer.push_front(cmd); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void ImGui::RenderDimmedBackgrounds() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* modal_window = GetTopMostAndVisiblePopupModal(); | ||||
|     const bool dim_bg_for_modal = (modal_window != NULL); | ||||
|     const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL && g.NavWindowingTargetAnim->Active); | ||||
|     if (!dim_bg_for_modal && !dim_bg_for_window_list) | ||||
|         return; | ||||
|  | ||||
|     if (dim_bg_for_modal) | ||||
|     { | ||||
|         // Draw dimming behind modal | ||||
|         RenderDimmedBackgroundBehindWindow(modal_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio)); | ||||
|     } | ||||
|     else if (dim_bg_for_window_list) | ||||
|     { | ||||
|         // Draw dimming behind CTRL+Tab target window | ||||
|         RenderDimmedBackgroundBehindWindow(g.NavWindowingTargetAnim, GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio)); | ||||
|  | ||||
|         // Draw border around CTRL+Tab target window | ||||
|         ImGuiWindow* window = g.NavWindowingTargetAnim; | ||||
|         ImGuiViewport* viewport = GetMainViewport(); | ||||
|         float distance = g.FontSize; | ||||
|         ImRect bb = window->Rect(); | ||||
|         bb.Expand(distance); | ||||
|         if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y) | ||||
|             bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward | ||||
|         window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size); | ||||
|         window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); | ||||
|         window->DrawList->PopClipRect(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal. | ||||
| @@ -4502,9 +4552,6 @@ void ImGui::EndFrame() | ||||
|     // Initiate moving window + handle left-click and right-click focus | ||||
|     UpdateMouseMovingWindowEndFrame(); | ||||
|  | ||||
|     // Draw modal/window whitening backgrounds | ||||
|     EndFrameDrawDimmedBackgrounds(); | ||||
|  | ||||
|     // Sort the window list so that all child windows are after their parent | ||||
|     // We cannot do that on FocusWindow() because children may not exist yet | ||||
|     g.WindowsTempSortBuffer.resize(0); | ||||
| @@ -4574,6 +4621,10 @@ void ImGui::Render() | ||||
|         if (windows_to_render_top_most[n] && IsWindowActiveAndVisible(windows_to_render_top_most[n])) // NavWindowingTarget is always temporarily displayed as the top-most window | ||||
|             AddRootWindowToDrawData(windows_to_render_top_most[n]); | ||||
|  | ||||
|     // Draw modal/window whitening backgrounds | ||||
|     if (first_render_of_frame) | ||||
|         RenderDimmedBackgrounds(); | ||||
|  | ||||
|     // Setup ImDrawData structures for end-user | ||||
|     g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0; | ||||
|     for (int n = 0; n < g.Viewports.Size; n++) | ||||
| @@ -6248,24 +6299,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|         window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); | ||||
|         PushClipRect(host_rect.Min, host_rect.Max, false); | ||||
|  | ||||
|         // Draw modal window background (darkens what is behind them, all viewports) | ||||
|         const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetTopMostPopupModal() && window->HiddenFramesCannotSkipItems <= 0; | ||||
|         const bool dim_bg_for_window_list = g.NavWindowingTargetAnim && (window == g.NavWindowingTargetAnim->RootWindow); | ||||
|         if (dim_bg_for_modal || dim_bg_for_window_list) | ||||
|         { | ||||
|             const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio); | ||||
|             window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, dim_bg_col); | ||||
|         } | ||||
|  | ||||
|         // Draw navigation selection/windowing rectangle background | ||||
|         if (dim_bg_for_window_list && window == g.NavWindowingTargetAnim) | ||||
|         { | ||||
|             ImRect bb = window->Rect(); | ||||
|             bb.Expand(g.FontSize); | ||||
|             if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway | ||||
|                 window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); | ||||
|         } | ||||
|  | ||||
|         // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71) | ||||
|         // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order. | ||||
|         // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493) | ||||
| @@ -6293,20 +6326,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|                 window->DrawList = &window->DrawListInst; | ||||
|         } | ||||
|  | ||||
|         // Draw navigation selection/windowing rectangle border | ||||
|         if (g.NavWindowingTargetAnim == window) | ||||
|         { | ||||
|             float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding); | ||||
|             ImRect bb = window->Rect(); | ||||
|             bb.Expand(g.FontSize); | ||||
|             if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward | ||||
|             { | ||||
|                 bb.Expand(-g.FontSize - 1.0f); | ||||
|                 rounding = window->WindowRounding; | ||||
|             } | ||||
|             window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, 0, 3.0f); | ||||
|         } | ||||
|  | ||||
|         // UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING) | ||||
|  | ||||
|         // Work rectangle. | ||||
| @@ -8363,6 +8382,16 @@ ImGuiWindow* ImGui::GetTopMostPopupModal() | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--) | ||||
|         if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) | ||||
|             if ((popup->Flags & ImGuiWindowFlags_Modal) && IsWindowActiveAndVisible(popup)) | ||||
|                 return popup; | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|   | ||||
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -64,7 +64,7 @@ Index of this file: | ||||
| // Version | ||||
| // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) | ||||
| #define IMGUI_VERSION               "1.86 WIP" | ||||
| #define IMGUI_VERSION_NUM           18513 | ||||
| #define IMGUI_VERSION_NUM           18514 | ||||
| #define IMGUI_CHECKVERSION()        ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) | ||||
| #define IMGUI_HAS_TABLE | ||||
|  | ||||
|   | ||||
| @@ -2539,6 +2539,7 @@ namespace ImGui | ||||
|     IMGUI_API void          BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); | ||||
|     IMGUI_API ImRect        GetPopupAllowedExtentRect(ImGuiWindow* window); | ||||
|     IMGUI_API ImGuiWindow*  GetTopMostPopupModal(); | ||||
|     IMGUI_API ImGuiWindow*  GetTopMostAndVisiblePopupModal(); | ||||
|     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); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut