diff --git a/imgui.cpp b/imgui.cpp index e926bf8e1..bc51d8aaa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5400,6 +5400,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; + // Decoration size + const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); + // SCROLLBAR STATUS // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). @@ -5407,7 +5410,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // When reading the current size we need to read it after size constraints have been applied. // When we use InnerRect here we are intentionally reading last frame size, same for ScrollbarSizes values before we set them again. - ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - window->TitleBarHeight() - window->MenuBarHeight()); + ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - decoration_up_height); ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + window->ScrollbarSizes; ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0,0) : window->ContentSize + window->WindowPadding * 2.0f; float size_x_for_scrollbars = (size_full_modified.x != FLT_MAX || window_just_created) ? avail_size_from_current_frame.x : avail_size_from_last_frame.x; @@ -5499,19 +5502,20 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // - FindHoveredWindow() (w/ extra padding when border resize is enabled) // - Begin() initial clipping rect for drawing window background and borders. // - Begin() clipping whole child - ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect; - ImRect outer_rect = window->Rect(); + const ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect; + const ImRect outer_rect = window->Rect(); + const ImRect title_bar_rect = window->TitleBarRect(); window->OuterRectClipped = outer_rect; window->OuterRectClipped.ClipWith(host_rect); // Inner rectangle // Not affected by window border size. Used by: + // - InnerClipRect // - NavScrollToBringItemIntoView() // - NavUpdatePageUpPageDown() // - Scrollbar() - const ImRect title_bar_rect = window->TitleBarRect(); - window->InnerRect.Min.x = title_bar_rect.Min.x; - window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight(); + window->InnerRect.Min.x = window->Pos.x; + window->InnerRect.Min.y = window->Pos.y + decoration_up_height; window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; @@ -5606,7 +5610,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Used by: // - Mouse wheel scrolling + many other things window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x; - window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); + window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height; window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->ScrollbarSizes.x + ImMin(window->ScrollbarSizes.x, window->WindowBorderSize))); window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->ScrollbarSizes.y + ImMin(window->ScrollbarSizes.y, window->WindowBorderSize))); @@ -5615,7 +5619,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x; window->DC.GroupOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f; - window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); + window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, decoration_up_height + window->WindowPadding.y - window->Scroll.y); window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPosPrevLine = window->DC.CursorPos; window->DC.CursorMaxPos = window->DC.CursorStartPos; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c8d7b83f8..58f1dbecb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2059,14 +2059,21 @@ static void ShowDemoWindowLayout() HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); static bool track = true; - static int track_line = 50, scroll_to_px = 200; + static int track_line = 50; + static float scroll_to_off_px = 0.0f; + static float scroll_to_pos_px = 200.0f; ImGui::Checkbox("Track", &track); ImGui::PushItemWidth(100); - ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d"); - bool scroll_to = ImGui::Button("Scroll To Pos"); - ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %d px"); + ImGui::SameLine(140); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d"); + + bool scroll_to_off = ImGui::Button("Scroll Offset"); + ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off_y", &scroll_to_off_px, 1.00f, 0, 9999, "+%.0f px"); + + bool scroll_to_pos = ImGui::Button("Scroll To Pos"); + ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos_y", &scroll_to_pos_px, 1.00f, 0, 9999, "Y = %.0f px"); + ImGui::PopItemWidth(); - if (scroll_to) + if (scroll_to_off || scroll_to_pos) track = false; ImGuiStyle& style = ImGui::GetStyle(); @@ -2076,9 +2083,13 @@ static void ShowDemoWindowLayout() if (i > 0) ImGui::SameLine(); ImGui::BeginGroup(); ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); - ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true); - if (scroll_to) - ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); + + ImGuiWindowFlags child_flags = ImGuiWindowFlags_MenuBar; + ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true, child_flags); + if (scroll_to_off) + ImGui::SetScrollY(scroll_to_off_px); + if (scroll_to_pos) + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f); for (int line = 0; line < 100; line++) { if (track && line == track_line) @@ -2094,7 +2105,7 @@ static void ShowDemoWindowLayout() float scroll_y = ImGui::GetScrollY(); float scroll_max_y = ImGui::GetScrollMaxY(); ImGui::EndChild(); - ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y); + ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y); ImGui::EndGroup(); } ImGui::TreePop(); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 351a558e0..becb5fe92 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -883,22 +883,25 @@ void ImGui::Scrollbar(ImGuiAxis axis) // Calculate scrollbar bounding box const ImRect outer_rect = window->Rect(); + const ImRect inner_rect = window->InnerRect; + const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; + IM_ASSERT(scrollbar_size > 0.0f); IM_UNUSED(scrollbar_size); const float other_scrollbar_size = window->ScrollbarSizes[axis]; ImDrawCornerFlags rounding_corners = (other_scrollbar_size <= 0.0f) ? ImDrawCornerFlags_BotRight : 0; ImRect bb; if (axis == ImGuiAxis_X) { - bb.Min = ImVec2(window->InnerRect.Min.x, window->InnerRect.Max.y); - bb.Max = ImVec2(window->InnerRect.Max.x, outer_rect.Max.y - window->WindowBorderSize); + bb.Min = ImVec2(inner_rect.Min.x, inner_rect.Max.y); + bb.Max = ImVec2(inner_rect.Max.x, outer_rect.Max.y - window->WindowBorderSize); rounding_corners |= ImDrawCornerFlags_BotLeft; } else { - bb.Min = ImVec2(window->InnerRect.Max.x, window->InnerRect.Min.y); + bb.Min = ImVec2(inner_rect.Max.x, inner_rect.Min.y); bb.Max = ImVec2(outer_rect.Max.x - window->WindowBorderSize, window->InnerRect.Max.y); rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0; } - ScrollbarEx(bb, id, axis, &window->Scroll[axis], window->InnerRect.Max[axis] - window->InnerRect.Min[axis], window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f, rounding_corners); + ScrollbarEx(bb, id, axis, &window->Scroll[axis], inner_rect.Max[axis] - inner_rect.Min[axis], window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f, rounding_corners); } void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)