From 89012a8fe8d10a52d339bd89e7e6e7055fd3a8a8 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Sun, 12 Jan 2025 10:42:33 -0800 Subject: [PATCH] debounce tracklist row rendering when fast scrolling --- ui/util/eventcounter.go | 43 ++++++++++++++++++++++++++++++++++++ ui/widgets/tracklistrow.go | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 ui/util/eventcounter.go diff --git a/ui/util/eventcounter.go b/ui/util/eventcounter.go new file mode 100644 index 0000000..ff06934 --- /dev/null +++ b/ui/util/eventcounter.go @@ -0,0 +1,43 @@ +package util + +import ( + "time" +) + +type EventCounter struct { + buf []time.Time + ptr int +} + +func NewEventCounter(maxN int) *EventCounter { + buffer := make([]time.Time, maxN) + return &EventCounter{ + buf: buffer, + } +} + +func (e *EventCounter) Add() { + e.buf[e.ptr] = time.Now() + e.ptr = (e.ptr + 1) % len(e.buf) +} + +func (e *EventCounter) NumEventsSince(t time.Time) int { + i := e.ptr - 1 + + count := 0 + for { + if i < 0 { + i = len(e.buf) - 1 + } + if !e.buf[i].IsZero() && e.buf[i].After(t) { + count++ + } else { + break + } + if count == len(e.buf) { + break + } + i-- + } + return count +} diff --git a/ui/widgets/tracklistrow.go b/ui/widgets/tracklistrow.go index 9662389..0f2e69b 100644 --- a/ui/widgets/tracklistrow.go +++ b/ui/widgets/tracklistrow.go @@ -5,6 +5,7 @@ import ( "image" "strconv" "sync" + "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" @@ -15,10 +16,31 @@ import ( "fyne.io/fyne/v2/widget" ttwidget "github.com/dweymouth/fyne-tooltip/widget" "github.com/dweymouth/supersonic/backend" + "github.com/dweymouth/supersonic/backend/mediaprovider" myTheme "github.com/dweymouth/supersonic/ui/theme" "github.com/dweymouth/supersonic/ui/util" ) +var ( + tracklistUpdateCounter = util.NewEventCounter(30) + + emptyTrack = util.TrackListModel{ + Item: &mediaprovider.Track{ + ID: "dummy", + Title: "—", + ArtistIDs: []string{"—"}, + ArtistNames: []string{"—"}, + Album: "—", + Genres: []string{"—"}, + ComposerNames: []string{"—"}, + ComposerIDs: []string{"—"}, + Comment: "—", + FilePath: "—", + ContentType: "—", + }, + } +) + const tracklistThumbnailSize = 48 type TracklistColumn struct { @@ -151,6 +173,9 @@ type tracklistRowBase struct { isFavorite bool playCount int + nextUpdateModel *util.TrackListModel + nextUpdateRowNum int + num *widget.Label name *ttwidget.RichText artist *MultiHyperlink @@ -318,6 +343,25 @@ func (t *tracklistRowBase) TrackID() string { } func (t *tracklistRowBase) Update(tm *util.TrackListModel, rowNum int) { + if tracklistUpdateCounter.NumEventsSince(time.Now().Add(-150*time.Millisecond)) > 20 { + t.doUpdate(&emptyTrack, 1) + if t.nextUpdateModel == nil { + go fyne.Do(func() { + if t.nextUpdateModel != nil { + t.doUpdate(t.nextUpdateModel, t.nextUpdateRowNum) + } + t.nextUpdateModel = nil + }) + } + t.nextUpdateModel = tm + t.nextUpdateRowNum = rowNum + } else { + t.nextUpdateModel = nil + t.doUpdate(tm, rowNum) + } +} + +func (t *tracklistRowBase) doUpdate(tm *util.TrackListModel, rowNum int) { changed := false if tm.Selected != t.Selected { t.Selected = tm.Selected @@ -415,6 +459,7 @@ func (t *tracklistRowBase) Update(tm *util.TrackListModel, rowNum int) { } if changed { + tracklistUpdateCounter.Add() t.Refresh() } }