Browse Source

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.

pull/1608/head
omar 7 years ago
parent
commit
7d09a0ae99
  1. 23
      imgui.cpp
  2. 1
      imgui_internal.h

23
imgui.cpp

@ -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();

1
imgui_internal.h

@ -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; }

Loading…
Cancel
Save