Menu bar: better software clipping to handle small windows, in particular child window don't have the minimum constraint added in e9a7e73bba so we need to render clipped menus better.

This commit is contained in:
omar 2017-11-22 12:26:50 +01:00
parent aafa6cece5
commit 7d09a0ae99
2 changed files with 15 additions and 9 deletions

View File

@ -4460,16 +4460,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot);
// Title bar // Title bar
const bool is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; const bool window_is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow;
if (!(flags & ImGuiWindowFlags_NoTitleBar)) if (!(flags & ImGuiWindowFlags_NoTitleBar))
window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top);
// Menu bar // Menu bar
if (flags & ImGuiWindowFlags_MenuBar) if (flags & ImGuiWindowFlags_MenuBar)
{ {
ImRect menu_bar_rect = window->MenuBarRect(); ImRect menu_bar_rect = window->MenuBarRect();
window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
if (style.FrameBorderSize > 0.0f) window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top);
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
} }
@ -9231,14 +9232,18 @@ bool ImGui::BeginMenuBar()
if (!(window->Flags & ImGuiWindowFlags_MenuBar)) if (!(window->Flags & ImGuiWindowFlags_MenuBar))
return false; return false;
ImGuiContext& g = *GImGui;
IM_ASSERT(!window->DC.MenuBarAppending); IM_ASSERT(!window->DC.MenuBarAppending);
BeginGroup(); // Save position BeginGroup(); // Save position
PushID("##menubar"); PushID("##menubar");
ImRect rect = window->MenuBarRect();
rect.Max.x = ImMax(rect.Min.x, rect.Max.x - g.Style.WindowRounding); // We don't clip with regular window clipping rectangle as it is already set to the area below. However we clip with window full rect.
PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->WindowBorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy.
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); ImRect bar_rect = window->MenuBarRect();
ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f));
clip_rect.ClipWith(window->Rect());
PushClipRect(clip_rect.Min, clip_rect.Max, false);
window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y);// + g.Style.FramePadding.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.MenuBarAppending = true; window->DC.MenuBarAppending = true;
AlignTextToFramePadding(); AlignTextToFramePadding();

View File

@ -746,6 +746,7 @@ public:
ImGuiID GetID(const void* ptr); ImGuiID GetID(const void* ptr);
ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL);
// We don't use g.FontSize because the window may be != g.CurrentWidow.
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); }
float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; }
float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; }