Skip to content

Commit

Permalink
Merge pull request #115 from mat007/fix-scroll-container
Browse files Browse the repository at this point in the history
Fix list scrolling
  • Loading branch information
mcarpenter622 committed Feb 23, 2024
2 parents e976834 + 623b347 commit 8006cb0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 36 deletions.
2 changes: 1 addition & 1 deletion _examples/widget_demos/scrollcontainer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func main() {

//Create a function to return the page size used by the slider
pageSizeFunc := func() int {
return int(math.Round(float64(scrollContainer.ContentRect().Dy()) / float64(content.GetWidget().Rect.Dy()) * 1000))
return int(math.Round(float64(scrollContainer.ViewRect().Dy()) / float64(content.GetWidget().Rect.Dy()) * 1000))
}
//Create a vertical Slider bar to control the ScrollableContainer
vSlider := widget.NewSlider(
Expand Down
54 changes: 27 additions & 27 deletions widget/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ func (l *List) createWidget() {

if !l.hideVerticalSlider {
pageSizeFunc := func() int {
return int(math.Round(float64(l.scrollContainer.ContentRect().Dy()) / float64(l.listContent.GetWidget().Rect.Dy()) * 1000))
return int(math.Round(float64(l.scrollContainer.ViewRect().Dy()) / float64(l.listContent.GetWidget().Rect.Dy()) * 1000))
}

l.vSlider = NewSlider(append(l.sliderOpts, []SliderOpt{
Expand Down Expand Up @@ -416,7 +416,7 @@ func (l *List) createWidget() {
SliderOpts.Direction(DirectionHorizontal),
SliderOpts.MinMax(0, 1000),
SliderOpts.PageSizeFunc(func() int {
return int(math.Round(float64(l.scrollContainer.ContentRect().Dx()) / float64(l.listContent.GetWidget().Rect.Dx()) * 1000))
return int(math.Round(float64(l.scrollContainer.ViewRect().Dx()) / float64(l.listContent.GetWidget().Rect.Dx()) * 1000))
}),
SliderOpts.ChangedHandler(func(args *SliderChangedEventArgs) {
l.scrollContainer.ScrollLeft = float64(args.Slider.Current) / 1000
Expand Down Expand Up @@ -556,35 +556,35 @@ func (l *List) setScrollLeft(left float64) {
l.scrollContainer.ScrollLeft = left
}

func scrollClamp(scroll float64) float64 {
min, max := -0.1, 0.1
if scroll < min {
scroll = min
} else if scroll > max {
scroll = max
}
return scroll
}

func (l *List) scrollVisible(w HasWidget) {
rect := l.scrollContainer.ContentRect()
vrect := l.scrollContainer.ViewRect()
wrect := w.GetWidget().Rect
if !wrect.In(rect) {
ScrollTop := 0.0
ScrollLeft := 0.0
if wrect.Max.Y > rect.Max.Y {
ScrollTop = float64(wrect.Max.Y - rect.Max.Y)
} else if wrect.Min.Y < rect.Min.Y {
ScrollTop = float64(wrect.Min.Y - rect.Min.Y)
if !wrect.In(vrect) {
crect := l.scrollContainer.ContentRect()
scrollTop := l.scrollContainer.ScrollTop
scrollHeight := crect.Dy() - vrect.Dy()
if wrect.Max.Y > vrect.Max.Y {
scrollTop = float64(wrect.Max.Y-vrect.Dy() - crect.Min.Y) / float64(scrollHeight)
} else if wrect.Min.Y < vrect.Min.Y {
scrollTop = float64(wrect.Min.Y - crect.Min.Y) / float64(scrollHeight)
}
if wrect.Max.X > rect.Max.X {
ScrollLeft = float64(wrect.Max.X - rect.Max.X)
} else if wrect.Min.X < rect.Min.X {
ScrollLeft = -float64(wrect.Min.X - rect.Min.X)
scrollLeft := l.scrollContainer.ScrollLeft
scrollWidth := crect.Dx() - vrect.Dx()
if wrect.Max.X > vrect.Max.X {
scrollLeft = float64(wrect.Max.X-vrect.Dx() - crect.Min.X) / float64(scrollWidth)
} else if wrect.Min.X < vrect.Min.X {
scrollLeft = float64(wrect.Min.X - crect.Min.X) / float64(scrollWidth)
}
l.setScrollTop(l.scrollContainer.ScrollTop + scrollClamp(ScrollTop/1000))
l.setScrollLeft(l.scrollContainer.ScrollLeft + scrollClamp(ScrollLeft/1000))
} else if wrect != rect {
l.setScrollTop(scrollClamp(scrollTop, l.scrollContainer.ScrollTop))
l.setScrollLeft(scrollClamp(scrollLeft, l.scrollContainer.ScrollLeft))
} else if wrect != vrect {
l.prevFocusIndex = l.focusIndex
}
}

func scrollClamp(targetScroll, currentScroll float64) float64 {
const maxScrollStep = 0.1
minScroll := currentScroll - maxScrollStep
maxScroll := currentScroll + maxScrollStep
return math.Max(minScroll, math.Min(targetScroll, maxScroll))
}
16 changes: 10 additions & 6 deletions widget/scrollcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (s *ScrollContainer) SetupInputLayer(def input.DeferredSetupInputLayerFunc)
EventTypes: input.LayerEventTypeAll ^ input.LayerEventTypeWheel,
BlockLower: true,
FullScreen: false,
RectFunc: s.ContentRect,
RectFunc: s.ViewRect,
})

if il, ok := s.content.(input.Layerer); ok {
Expand Down Expand Up @@ -228,16 +228,16 @@ func (s *ScrollContainer) renderContent(screen *ebiten.Image, def DeferredRender
cw, ch = p.PreferredSize()
}

crect := s.ContentRect()
if s.stretchContentWidth && cw < crect.Dx() {
cw = crect.Dx()
vrect := s.ViewRect()
if s.stretchContentWidth && cw < vrect.Dx() {
cw = vrect.Dx()
}

rect := img.Rect(0, 0, cw, ch)
rect = rect.Add(s.widget.Rect.Min)
rect = rect.Add(img.Point{s.padding.Left, s.padding.Top})

rect = rect.Sub(img.Point{int(math.Round(float64(cw-crect.Dx()) * s.ScrollLeft)), int(math.Round(float64(ch-crect.Dy()) * s.ScrollTop))})
rect = rect.Sub(img.Point{int(math.Round(float64(cw-vrect.Dx()) * s.ScrollLeft)), int(math.Round(float64(ch-vrect.Dy()) * s.ScrollTop))})

if rect != s.content.GetWidget().Rect {
l.SetLocation(rect)
Expand All @@ -260,11 +260,15 @@ func (s *ScrollContainer) renderContent(screen *ebiten.Image, def DeferredRender
})
}

func (s *ScrollContainer) ContentRect() img.Rectangle {
func (s *ScrollContainer) ViewRect() img.Rectangle {
s.init.Do()
return s.padding.Apply(s.widget.Rect)
}

func (s *ScrollContainer) ContentRect() img.Rectangle {
return s.content.GetWidget().Rect
}

func (s *ScrollContainer) clampScroll() {
if s.ScrollTop < 0 {
s.ScrollTop = 0
Expand Down
4 changes: 2 additions & 2 deletions widget/textarea.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func (l *TextArea) createWidget() {

if l.showVerticalSlider {
pageSizeFunc := func() int {
return int(math.Round(float64(l.scrollContainer.ContentRect().Dy()) / float64(content.GetWidget().Rect.Dy()) * 1000))
return int(math.Round(float64(l.scrollContainer.ViewRect().Dy()) / float64(content.GetWidget().Rect.Dy()) * 1000))
}

l.vSlider = NewSlider(append(l.sliderOpts, []SliderOpt{
Expand Down Expand Up @@ -303,7 +303,7 @@ func (l *TextArea) createWidget() {

if l.showHorizontalSlider {
pageSizeFunc := func() int {
return int(math.Round(float64(l.scrollContainer.ContentRect().Dx()) / float64(content.GetWidget().Rect.Dx()) * 1000))
return int(math.Round(float64(l.scrollContainer.ViewRect().Dx()) / float64(content.GetWidget().Rect.Dx()) * 1000))
}

l.hSlider = NewSlider(append(l.sliderOpts, []SliderOpt{
Expand Down

0 comments on commit 8006cb0

Please sign in to comment.