@@ -391,8 +391,10 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
391
391
// - ArrowButton()
392
392
// - CloseButton() [Internal]
393
393
// - CollapseButton() [Internal]
394
- // - ScrollbarEx() [Internal]
394
+ // - GetWindowScrollbarID() [Internal]
395
+ // - GetWindowScrollbarRect() [Internal]
395
396
// - Scrollbar() [Internal]
397
+ // - ScrollbarEx() [Internal]
396
398
// - Image()
397
399
// - ImageButton()
398
400
// - Checkbox()
@@ -812,6 +814,49 @@ ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis)
812
814
return window->GetIDNoKeepAlive (axis == ImGuiAxis_X ? " #SCROLLX" : " #SCROLLY" );
813
815
}
814
816
817
+ // Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set.
818
+ ImRect ImGui::GetWindowScrollbarRect (ImGuiWindow* window, ImGuiAxis axis)
819
+ {
820
+ const ImRect outer_rect = window->Rect ();
821
+ const ImRect inner_rect = window->InnerRect ;
822
+ const float border_size = window->WindowBorderSize ;
823
+ const float scrollbar_size = window->ScrollbarSizes [axis ^ 1 ]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
824
+ IM_ASSERT (scrollbar_size > 0 .0f );
825
+ if (axis == ImGuiAxis_X)
826
+ return ImRect (inner_rect.Min .x , ImMax (outer_rect.Min .y , outer_rect.Max .y - border_size - scrollbar_size), inner_rect.Max .x , outer_rect.Max .y );
827
+ else
828
+ return ImRect (ImMax (outer_rect.Min .x , outer_rect.Max .x - border_size - scrollbar_size), inner_rect.Min .y , outer_rect.Max .x , inner_rect.Max .y );
829
+ }
830
+
831
+ void ImGui::Scrollbar (ImGuiAxis axis)
832
+ {
833
+ ImGuiContext& g = *GImGui;
834
+ ImGuiWindow* window = g.CurrentWindow ;
835
+
836
+ const ImGuiID id = GetWindowScrollbarID (window, axis);
837
+ KeepAliveID (id);
838
+
839
+ // Calculate scrollbar bounding box
840
+ ImRect bb = GetWindowScrollbarRect (window, axis);
841
+ ImDrawCornerFlags rounding_corners = 0 ;
842
+ if (axis == ImGuiAxis_X)
843
+ {
844
+ rounding_corners |= ImDrawCornerFlags_BotLeft;
845
+ if (!window->ScrollbarY )
846
+ rounding_corners |= ImDrawCornerFlags_BotRight;
847
+ }
848
+ else
849
+ {
850
+ if ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar))
851
+ rounding_corners |= ImDrawCornerFlags_TopRight;
852
+ if (!window->ScrollbarX )
853
+ rounding_corners |= ImDrawCornerFlags_BotRight;
854
+ }
855
+ float size_avail = window->InnerRect .Max [axis] - window->InnerRect .Min [axis];
856
+ float size_contents = window->ContentSize [axis] + window->WindowPadding [axis] * 2 .0f ;
857
+ ScrollbarEx (bb, id, axis, &window->Scroll [axis], size_avail, size_contents, rounding_corners);
858
+ }
859
+
815
860
// Vertical/Horizontal scrollbar
816
861
// The entire piece of code below is rather confusing because:
817
862
// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
@@ -830,7 +875,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
830
875
if (bb_frame_width <= 0 .0f || bb_frame_height <= 0 .0f )
831
876
return false ;
832
877
833
- // When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the resize grab)
878
+ // When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab)
834
879
float alpha = 1 .0f ;
835
880
if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style .FramePadding .y * 2 .0f )
836
881
alpha = ImSaturate ((bb_frame_height - g.FontSize ) / (g.Style .FramePadding .y * 2 .0f ));
@@ -839,13 +884,12 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
839
884
840
885
const ImGuiStyle& style = g.Style ;
841
886
const bool allow_interaction = (alpha >= 1 .0f );
842
- const bool horizontal = (axis == ImGuiAxis_X);
843
887
844
888
ImRect bb = bb_frame;
845
889
bb.Expand (ImVec2 (-ImClamp (IM_FLOOR ((bb_frame_width - 2 .0f ) * 0 .5f ), 0 .0f , 3 .0f ), -ImClamp (IM_FLOOR ((bb_frame_height - 2 .0f ) * 0 .5f ), 0 .0f , 3 .0f )));
846
890
847
891
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
848
- const float scrollbar_size_v = horizontal ? bb.GetWidth () : bb.GetHeight ();
892
+ const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth () : bb.GetHeight ();
849
893
850
894
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
851
895
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
@@ -861,11 +905,11 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
861
905
862
906
float scroll_max = ImMax (1 .0f , size_contents_v - size_avail_v);
863
907
float scroll_ratio = ImSaturate (*p_scroll_v / scroll_max);
864
- float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
908
+ float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space
865
909
if (held && allow_interaction && grab_h_norm < 1 .0f )
866
910
{
867
- float scrollbar_pos_v = horizontal ? bb.Min . x : bb. Min . y ;
868
- float mouse_pos_v = horizontal ? g.IO .MousePos . x : g. IO . MousePos . y ;
911
+ float scrollbar_pos_v = bb.Min [axis] ;
912
+ float mouse_pos_v = g.IO .MousePos [axis] ;
869
913
870
914
// Click position in scrollbar normalized space (0.0f->1.0f)
871
915
const float clicked_v_norm = ImSaturate ((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
@@ -882,7 +926,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
882
926
g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0 .5f ;
883
927
}
884
928
885
- // Apply scroll
929
+ // Apply scroll (p_scroll_v will generally point on one member of window->Scroll)
886
930
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
887
931
const float scroll_v_norm = ImSaturate ((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0 .5f ) / (1 .0f - grab_h_norm));
888
932
*p_scroll_v = IM_ROUND (scroll_v_norm * scroll_max);// (win_size_contents_v - win_size_v));
@@ -897,10 +941,11 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
897
941
}
898
942
899
943
// Render
900
- window-> DrawList -> AddRectFilled (bb_frame. Min , bb_frame. Max , GetColorU32 (ImGuiCol_ScrollbarBg), window-> WindowRounding , rounding_corners );
944
+ const ImU32 bg_col = GetColorU32 (ImGuiCol_ScrollbarBg);
901
945
const ImU32 grab_col = GetColorU32 (held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha);
946
+ window->DrawList ->AddRectFilled (bb_frame.Min , bb_frame.Max , bg_col, window->WindowRounding , rounding_corners);
902
947
ImRect grab_rect;
903
- if (horizontal )
948
+ if (axis == ImGuiAxis_X )
904
949
grab_rect = ImRect (ImLerp (bb.Min .x , bb.Max .x , grab_v_norm), bb.Min .y , ImLerp (bb.Min .x , bb.Max .x , grab_v_norm) + grab_h_pixels, bb.Max .y );
905
950
else
906
951
grab_rect = ImRect (bb.Min .x , ImLerp (bb.Min .y , bb.Max .y , grab_v_norm), bb.Max .x , ImLerp (bb.Min .y , bb.Max .y , grab_v_norm) + grab_h_pixels);
@@ -909,38 +954,6 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
909
954
return held;
910
955
}
911
956
912
- void ImGui::Scrollbar (ImGuiAxis axis)
913
- {
914
- ImGuiContext& g = *GImGui;
915
- ImGuiWindow* window = g.CurrentWindow ;
916
-
917
- const ImGuiID id = GetWindowScrollbarID (window, axis);
918
- KeepAliveID (id);
919
-
920
- // Calculate scrollbar bounding box
921
- const ImRect outer_rect = window->Rect ();
922
- const ImRect inner_rect = window->InnerRect ;
923
- const float border_size = window->WindowBorderSize ;
924
- const float scrollbar_size = window->ScrollbarSizes [axis ^ 1 ];
925
- IM_ASSERT (scrollbar_size > 0 .0f );
926
- const float other_scrollbar_size = window->ScrollbarSizes [axis];
927
- ImDrawCornerFlags rounding_corners = (other_scrollbar_size <= 0 .0f ) ? ImDrawCornerFlags_BotRight : 0 ;
928
- ImRect bb;
929
- if (axis == ImGuiAxis_X)
930
- {
931
- bb.Min = ImVec2 (inner_rect.Min .x , ImMax (outer_rect.Min .y , outer_rect.Max .y - border_size - scrollbar_size));
932
- bb.Max = ImVec2 (inner_rect.Max .x , outer_rect.Max .y );
933
- rounding_corners |= ImDrawCornerFlags_BotLeft;
934
- }
935
- else
936
- {
937
- bb.Min = ImVec2 (ImMax (outer_rect.Min .x , outer_rect.Max .x - border_size - scrollbar_size), inner_rect.Min .y );
938
- bb.Max = ImVec2 (outer_rect.Max .x , window->InnerRect .Max .y );
939
- rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0 ;
940
- }
941
- 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);
942
- }
943
-
944
957
void ImGui::Image (ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
945
958
{
946
959
ImGuiWindow* window = GetCurrentWindow ();
0 commit comments