diff --git a/imgui.cpp b/imgui.cpp index 5a725c9..ca13fcd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. @@ -704,12 +706,16 @@ Alpha = 1.0f; // Global alpha applies to everything in ImGui WindowPadding = ImVec2(8,8); // Padding within a window WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! @@ -3075,10 +3081,11 @@ ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3086,10 +3093,11 @@ { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->Flags & ImGuiWindowFlags_ShowBorders) + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3665,14 +3673,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; @@ -3682,9 +3688,7 @@ ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, flags); - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; - if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); return is_open; @@ -3698,7 +3702,7 @@ ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3747,8 +3751,6 @@ IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); End(); - if (!(window->Flags & ImGuiWindowFlags_Modal)) - PopStyleVar(); } bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) @@ -3774,7 +3776,7 @@ IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3786,7 +3788,7 @@ if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3796,11 +3798,12 @@ ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag @@ -3812,8 +3815,10 @@ size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); - if (border) - flags |= ImGuiWindowFlags_ShowBorders; + + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; flags |= extra_flags; char title[256]; @@ -3826,8 +3831,7 @@ bool ret = ImGui::Begin(title, NULL, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); child_window->AutoFitChildAxises = auto_fit_axises; - if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) - child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; + g.Style.ChildBorderSize = backup_border_size; return ret; } @@ -3876,14 +3880,15 @@ const ImGuiStyle& style = g.Style; PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { EndChild(); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); } @@ -4265,13 +4270,15 @@ } } - // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. + // Lock window padding so that altering the border sizes for children doesn't have side-effects. window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && style.WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + const ImVec2 window_padding = window->WindowPadding; const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); @@ -4405,7 +4412,10 @@ if (window->Collapsed) { // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; } else { @@ -4459,9 +4469,9 @@ if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - if (flags & ImGuiWindowFlags_ShowBorders) - window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border)); window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + if (style.FrameBorderSize > 0.0f) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -4475,20 +4485,17 @@ if (!(flags & ImGuiWindowFlags_NoResize)) { const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->WindowBorderSize)); - window->DrawList->PathLineTo(br + ImVec2(-window->WindowBorderSize, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->WindowBorderSize, br.y - window_rounding - window->WindowBorderSize), window_rounding, 0, 3); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window_border_size)); + window->DrawList->PathLineTo(br + ImVec2(-window_border_size, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window_border_size, br.y - window_rounding - window_border_size), window_rounding, 0, 3); window->DrawList->PathFillConvex(resize_col); } // Borders - if (flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding); - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,0), title_bar_rect.GetBR()-ImVec2(1,0), GetColorU32(ImGuiCol_Border)); - } + if (window_border_size > 0.0f) + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ~0, window_border_size); + if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Update ContentsRegionMax. All the variable it depends on are set above in this function. @@ -5042,11 +5049,15 @@ { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing @@ -7619,7 +7630,7 @@ // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-window->WindowBorderSize, -window->WindowBorderSize)); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); @@ -7742,10 +7753,10 @@ window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (style.FrameBorderSize > 0.0f) { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16); + window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); } if (g.LogEnabled) @@ -8884,18 +8895,17 @@ // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } else { // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (!BeginPopupEx(id, flags)) + if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) { IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; @@ -9361,7 +9371,7 @@ if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } @@ -9506,7 +9516,7 @@ else window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border diff --git a/imgui.cpp b/imgui.cpp index 5a725c9..ca13fcd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. @@ -704,12 +706,16 @@ Alpha = 1.0f; // Global alpha applies to everything in ImGui WindowPadding = ImVec2(8,8); // Padding within a window WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! @@ -3075,10 +3081,11 @@ ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3086,10 +3093,11 @@ { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->Flags & ImGuiWindowFlags_ShowBorders) + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3665,14 +3673,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; @@ -3682,9 +3688,7 @@ ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, flags); - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; - if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); return is_open; @@ -3698,7 +3702,7 @@ ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3747,8 +3751,6 @@ IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); End(); - if (!(window->Flags & ImGuiWindowFlags_Modal)) - PopStyleVar(); } bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) @@ -3774,7 +3776,7 @@ IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3786,7 +3788,7 @@ if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3796,11 +3798,12 @@ ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag @@ -3812,8 +3815,10 @@ size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); - if (border) - flags |= ImGuiWindowFlags_ShowBorders; + + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; flags |= extra_flags; char title[256]; @@ -3826,8 +3831,7 @@ bool ret = ImGui::Begin(title, NULL, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); child_window->AutoFitChildAxises = auto_fit_axises; - if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) - child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; + g.Style.ChildBorderSize = backup_border_size; return ret; } @@ -3876,14 +3880,15 @@ const ImGuiStyle& style = g.Style; PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { EndChild(); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); } @@ -4265,13 +4270,15 @@ } } - // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. + // Lock window padding so that altering the border sizes for children doesn't have side-effects. window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && style.WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + const ImVec2 window_padding = window->WindowPadding; const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); @@ -4405,7 +4412,10 @@ if (window->Collapsed) { // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; } else { @@ -4459,9 +4469,9 @@ if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - if (flags & ImGuiWindowFlags_ShowBorders) - window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border)); window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + if (style.FrameBorderSize > 0.0f) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -4475,20 +4485,17 @@ if (!(flags & ImGuiWindowFlags_NoResize)) { const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->WindowBorderSize)); - window->DrawList->PathLineTo(br + ImVec2(-window->WindowBorderSize, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->WindowBorderSize, br.y - window_rounding - window->WindowBorderSize), window_rounding, 0, 3); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window_border_size)); + window->DrawList->PathLineTo(br + ImVec2(-window_border_size, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window_border_size, br.y - window_rounding - window_border_size), window_rounding, 0, 3); window->DrawList->PathFillConvex(resize_col); } // Borders - if (flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding); - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,0), title_bar_rect.GetBR()-ImVec2(1,0), GetColorU32(ImGuiCol_Border)); - } + if (window_border_size > 0.0f) + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ~0, window_border_size); + if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Update ContentsRegionMax. All the variable it depends on are set above in this function. @@ -5042,11 +5049,15 @@ { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing @@ -7619,7 +7630,7 @@ // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-window->WindowBorderSize, -window->WindowBorderSize)); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); @@ -7742,10 +7753,10 @@ window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (style.FrameBorderSize > 0.0f) { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16); + window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); } if (g.LogEnabled) @@ -8884,18 +8895,17 @@ // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } else { // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (!BeginPopupEx(id, flags)) + if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) { IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; @@ -9361,7 +9371,7 @@ if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } @@ -9506,7 +9516,7 @@ else window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border diff --git a/imgui.h b/imgui.h index 5515940..98e016b 100644 --- a/imgui.h +++ b/imgui.h @@ -502,7 +502,7 @@ ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame - ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items + //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar @@ -672,11 +672,15 @@ ImGuiStyleVar_Alpha, // float Alpha ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize ImGuiStyleVar_FramePadding, // ImVec2 FramePadding ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing ImGuiStyleVar_IndentSpacing, // float IndentSpacing @@ -754,12 +758,16 @@ float Alpha; // Global alpha applies to everything in ImGui ImVec2 WindowPadding; // Padding within a window float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 WindowMinSize; // Minimum window size ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) float PopupRounding; // Radius of popup window corners rounding. + float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). + float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! diff --git a/imgui.cpp b/imgui.cpp index 5a725c9..ca13fcd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. @@ -704,12 +706,16 @@ Alpha = 1.0f; // Global alpha applies to everything in ImGui WindowPadding = ImVec2(8,8); // Padding within a window WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! @@ -3075,10 +3081,11 @@ ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3086,10 +3093,11 @@ { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->Flags & ImGuiWindowFlags_ShowBorders) + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3665,14 +3673,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; @@ -3682,9 +3688,7 @@ ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, flags); - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; - if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); return is_open; @@ -3698,7 +3702,7 @@ ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3747,8 +3751,6 @@ IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); End(); - if (!(window->Flags & ImGuiWindowFlags_Modal)) - PopStyleVar(); } bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) @@ -3774,7 +3776,7 @@ IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3786,7 +3788,7 @@ if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3796,11 +3798,12 @@ ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag @@ -3812,8 +3815,10 @@ size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); - if (border) - flags |= ImGuiWindowFlags_ShowBorders; + + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; flags |= extra_flags; char title[256]; @@ -3826,8 +3831,7 @@ bool ret = ImGui::Begin(title, NULL, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); child_window->AutoFitChildAxises = auto_fit_axises; - if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) - child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; + g.Style.ChildBorderSize = backup_border_size; return ret; } @@ -3876,14 +3880,15 @@ const ImGuiStyle& style = g.Style; PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { EndChild(); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); } @@ -4265,13 +4270,15 @@ } } - // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. + // Lock window padding so that altering the border sizes for children doesn't have side-effects. window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && style.WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + const ImVec2 window_padding = window->WindowPadding; const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); @@ -4405,7 +4412,10 @@ if (window->Collapsed) { // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; } else { @@ -4459,9 +4469,9 @@ if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - if (flags & ImGuiWindowFlags_ShowBorders) - window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border)); window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + if (style.FrameBorderSize > 0.0f) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -4475,20 +4485,17 @@ if (!(flags & ImGuiWindowFlags_NoResize)) { const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->WindowBorderSize)); - window->DrawList->PathLineTo(br + ImVec2(-window->WindowBorderSize, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->WindowBorderSize, br.y - window_rounding - window->WindowBorderSize), window_rounding, 0, 3); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window_border_size)); + window->DrawList->PathLineTo(br + ImVec2(-window_border_size, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window_border_size, br.y - window_rounding - window_border_size), window_rounding, 0, 3); window->DrawList->PathFillConvex(resize_col); } // Borders - if (flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding); - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,0), title_bar_rect.GetBR()-ImVec2(1,0), GetColorU32(ImGuiCol_Border)); - } + if (window_border_size > 0.0f) + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ~0, window_border_size); + if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Update ContentsRegionMax. All the variable it depends on are set above in this function. @@ -5042,11 +5049,15 @@ { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing @@ -7619,7 +7630,7 @@ // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-window->WindowBorderSize, -window->WindowBorderSize)); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); @@ -7742,10 +7753,10 @@ window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (style.FrameBorderSize > 0.0f) { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16); + window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); } if (g.LogEnabled) @@ -8884,18 +8895,17 @@ // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } else { // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (!BeginPopupEx(id, flags)) + if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) { IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; @@ -9361,7 +9371,7 @@ if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } @@ -9506,7 +9516,7 @@ else window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border diff --git a/imgui.h b/imgui.h index 5515940..98e016b 100644 --- a/imgui.h +++ b/imgui.h @@ -502,7 +502,7 @@ ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame - ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items + //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar @@ -672,11 +672,15 @@ ImGuiStyleVar_Alpha, // float Alpha ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize ImGuiStyleVar_FramePadding, // ImVec2 FramePadding ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing ImGuiStyleVar_IndentSpacing, // float IndentSpacing @@ -754,12 +758,16 @@ float Alpha; // Global alpha applies to everything in ImGui ImVec2 WindowPadding; // Padding within a window float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 WindowMinSize; // Minimum window size ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) float PopupRounding; // Radius of popup window corners rounding. + float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). + float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d6475d0..7ee7de8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -165,22 +165,20 @@ } static bool no_titlebar = false; - static bool no_border = true; - static bool no_resize = false; - static bool no_move = false; static bool no_scrollbar = false; - static bool no_collapse = false; static bool no_menu = false; + static bool no_move = false; + static bool no_resize = false; + static bool no_collapse = false; // Demonstrate the various window flags. Typically you would just use the default. ImGuiWindowFlags window_flags = 0; if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; - if (!no_border) window_flags |= ImGuiWindowFlags_ShowBorders; - if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; - if (no_move) window_flags |= ImGuiWindowFlags_NoMove; if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; - if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver); if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) { @@ -238,12 +236,11 @@ if (ImGui::CollapsingHeader("Window options")) { ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150); - ImGui::Checkbox("No border", &no_border); ImGui::SameLine(300); - ImGui::Checkbox("No resize", &no_resize); - ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300); - ImGui::Checkbox("No collapse", &no_collapse); ImGui::Checkbox("No menu", &no_menu); + ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); + ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300); + ImGui::Checkbox("No collapse", &no_collapse); if (ImGui::TreeNode("Style")) { @@ -685,7 +682,6 @@ ImGui::TreePop(); } - if (ImGui::TreeNode("Plots widgets")) { static bool animate = true; @@ -1878,6 +1874,17 @@ ref_saved_style = style; } + // Simplified Settings + if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) + style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding + bool window_border = (style.WindowBorderSize > 0.0f); + if (ImGui::Checkbox("WindowBorder", &window_border)) + style.WindowBorderSize = window_border ? 1.0f : 0.0f; + ImGui::SameLine(); + bool frame_border = (style.FrameBorderSize > 0.0f); + if (ImGui::Checkbox("FrameBorder", &frame_border)) + style.FrameBorderSize = frame_border ? 1.0f : 0.0f; + // Save/Revert button if (ImGui::Button("Save Ref")) *ref = ref_saved_style = style; @@ -1902,19 +1909,25 @@ if (ImGui::TreeNode("Settings")) { ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 16.0f, "%.0f"); + ImGui::Text("BorderSize"); + ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::Text("Rounding"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 14.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); ImGui::Text("Alignment"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content.");