diff --git a/internal/widget/scroller.go b/internal/widget/scroller.go index 76c6321192..ee380b1f1e 100644 --- a/internal/widget/scroller.go +++ b/internal/widget/scroller.go @@ -222,7 +222,7 @@ func (a *scrollBarArea) CreateRenderer() fyne.WidgetRenderer { func (a *scrollBarArea) MouseIn(*desktop.MouseEvent) { a.isMouseIn = true - a.scroll.Refresh() + a.scroll.refreshBars() } func (a *scrollBarArea) MouseMoved(*desktop.MouseEvent) { @@ -234,7 +234,7 @@ func (a *scrollBarArea) MouseOut() { return } - a.scroll.Refresh() + a.scroll.refreshBars() } func (a *scrollBarArea) moveBar(offset float32, barSize fyne.Size) { @@ -432,12 +432,13 @@ func (s *Scroll) CreateRenderer() fyne.WidgetRenderer { // ScrollToBottom will scroll content to container bottom - to show latest info which end user just added func (s *Scroll) ScrollToBottom() { s.scrollBy(0, -1*(s.Content.MinSize().Height-s.Size().Height-s.Offset.Y)) - s.Refresh() + s.refreshBars() } // ScrollToTop will scroll content to container top func (s *Scroll) ScrollToTop() { s.scrollBy(0, -s.Offset.Y) + s.refreshBars() } // DragEnd will stop scrolling on mobile has stopped @@ -478,8 +479,11 @@ func (s *Scroll) SetMinSize(size fyne.Size) { // Refresh causes this widget to be redrawn in it's current state func (s *Scroll) Refresh() { - s.updateOffset(0, 0) - s.refreshWithoutOffsetUpdate() + s.refreshBars() + + if s.Content != nil { + s.Content.Refresh() + } } // Resize is called when this scroller should change size. We refresh to ensure the scroll bars are updated. @@ -489,7 +493,19 @@ func (s *Scroll) Resize(sz fyne.Size) { } s.Base.Resize(sz) - s.Refresh() + s.refreshBars() +} + +// ScrollToOffset will update the location of the content of this scroll container. +// +// Since: 2.6 +func (s *Scroll) ScrollToOffset(p fyne.Position) { + if s.Offset.Subtract(p).IsZero() { + return + } + + s.Offset = p + s.refreshBars() } func (s *Scroll) refreshWithoutOffsetUpdate() { @@ -503,6 +519,11 @@ func (s *Scroll) Scrolled(ev *fyne.ScrollEvent) { } } +func (s *Scroll) refreshBars() { + s.updateOffset(0, 0) + s.refreshWithoutOffsetUpdate() +} + func (s *Scroll) scrollBy(dx, dy float32) { min := s.Content.MinSize() size := s.Size() @@ -530,10 +551,12 @@ func (s *Scroll) updateOffset(deltaX, deltaY float32) bool { min := s.Content.MinSize() s.Offset.X = computeOffset(s.Offset.X, -deltaX, size.Width, min.Width) s.Offset.Y = computeOffset(s.Offset.Y, -deltaY, size.Height, min.Height) - if f := s.OnScrolled; f != nil && (s.Offset.X != oldX || s.Offset.Y != oldY) { + + moved := s.Offset.X != oldX || s.Offset.Y != oldY + if f := s.OnScrolled; f != nil && moved { f(s.Offset) } - return true + return moved } func computeOffset(start, delta, outerWidth, innerWidth float32) float32 { diff --git a/widget/entry.go b/widget/entry.go index 436700fcc2..dbc7afdd1d 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -1996,8 +1996,7 @@ func (r *entryContentRenderer) ensureCursorVisible() { move.DY += cy2 - (offset.Y + size.Height) } if r.content.scroll.Content != nil { - r.content.scroll.Offset = r.content.scroll.Offset.Add(move) - r.content.scroll.Refresh() + r.content.scroll.ScrollToOffset(r.content.scroll.Offset.Add(move)) } } diff --git a/widget/widget.go b/widget/widget.go index 986333f154..fb38511750 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -4,7 +4,6 @@ package widget // import "fyne.io/fyne/v2/widget" import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/internal/async" "fyne.io/fyne/v2/internal/cache" internalWidget "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/theme" @@ -112,16 +111,14 @@ func (w *BaseWidget) Hide() { // Refresh causes this widget to be redrawn in its current state func (w *BaseWidget) Refresh() { - async.EnsureMain(func() { - impl := w.super() - if impl == nil { - return - } + impl := w.super() + if impl == nil { + return + } - w.themeCache = nil + w.themeCache = nil - cache.Renderer(impl).Refresh() - }) + cache.Renderer(impl).Refresh() } // Theme returns a cached Theme instance for this widget (or its extending widget).