From 77eed223ac873b70a48186a8bc252e6a343d554d Mon Sep 17 00:00:00 2001 From: Chris Waldon Date: Thu, 9 Sep 2021 15:07:57 -0400 Subject: [PATCH] widget/material: fix scrollbar indicator partially off-screen bug This commit fixes a problem that could force the scroll indicator to lay itself out outside of its configured bounds. This occurred when the scroll indicator size was increased to meet the minimum size configured on the style type while the scrollbar was near the end of the list. The increased size did not take the start position of the scroll indicator into account, which made the indicator begin in the correct place, but extend beyond the end of its track. This commit alters the logic to ensure that the scroll indicator can never extend beyond the end of its track. Signed-off-by: Chris Waldon --- widget/material/list.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/widget/material/list.go b/widget/material/list.go index 82f27a7f..49d7ddcb 100644 --- a/widget/material/list.go +++ b/widget/material/list.go @@ -179,12 +179,15 @@ func (s ScrollbarStyle) layout(gtx layout.Context, axis layout.Axis, viewportSta // Compute the pixel size and position of the scroll indicator within // the track. - trackLen := float32(gtx.Constraints.Min.X) - viewStart := viewportStart * trackLen - viewEnd := viewportEnd * trackLen - indicatorLen := unit.Max(gtx.Metric, unit.Px(viewEnd-viewStart), s.Indicator.MajorMinLen) + trackLen := gtx.Constraints.Min.X + viewStart := int(math.Round(float64(viewportStart) * float64(trackLen))) + viewEnd := int(math.Round(float64(viewportEnd) * float64(trackLen))) + indicatorLen := max(viewEnd-viewStart, gtx.Px(s.Indicator.MajorMinLen)) + if viewStart+indicatorLen > trackLen { + viewStart = trackLen - indicatorLen + } indicatorDims := axis.Convert(image.Point{ - X: gtx.Px(indicatorLen), + X: indicatorLen, Y: gtx.Px(s.Indicator.MinorWidth), }) indicatorDimsF := layout.FPt(indicatorDims) @@ -192,7 +195,7 @@ func (s ScrollbarStyle) layout(gtx layout.Context, axis layout.Axis, viewportSta // Lay out the indicator. defer op.Save(gtx.Ops).Load() - offset := axis.Convert(image.Pt(int(viewStart), 0)) + offset := axis.Convert(image.Pt(viewStart, 0)) op.Offset(layout.FPt(offset)).Add(gtx.Ops) paint.FillShape(gtx.Ops, s.Indicator.Color, clip.RRect{ Rect: f32.Rectangle{