~eliasnaur/gio

gio: Alternative drag scroll approach v1 PROPOSED

~eliasnaur
Chris proposes a physics-based approach to get rid of the ugly drag
scroll artifacts we currently have. This patch proposes an alternative
that locks the heuristic for scroll distance, instead of trying to
improve it.

It works for me for Chris' scroll test program, and for
kitchen.

It is not mergeable as is, and I don't have time to finish
it; however, if the approach indeed works I propose holding off merging
the physics approach.

Elias Naur (1):
  widget,widget/material: lock drag scroll heuristic on first drag

 widget/list.go          | 24 +++++++++++++++++++++++-
 widget/material/list.go | 13 ++++++++++++-
 2 files changed, 35 insertions(+), 2 deletions(-)

-- 
2.32.0
#585902 apple.yml success
#585903 freebsd.yml success
#585904 linux.yml success
#585905 openbsd.yml success
builds.sr.ht
gio/patches: SUCCESS in 24m36s

[Alternative drag scroll approach][0] from [~eliasnaur][1]

[0]: https://lists.sr.ht/~eliasnaur/gio/patches/25116
[1]: mailto:mail@eliasnaur.com

✓ #585904 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/585904
✓ #585905 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/585905
✓ #585903 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/585903
✓ #585902 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/585902
Hey Elias,
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio/patches/25116/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio 1/1] widget,widget/material: lock drag scroll heuristic on first drag Export this patch

~eliasnaur
From: Elias Naur <mail@eliasnaur.com>

When dragging a scroll indicator, the distance scrolled is propoertional
to the indicator length/height. However, since the length is based on an
estimation (and content, for dynamic lists), the scale from distance
dragged to pixels scrolled would change every frame, leading to ugly
flickering artifacts.

This (hacky) change proposes a simple workaround: lock the
distance-to-scroll scale on the first drag.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
---
 widget/list.go          | 24 +++++++++++++++++++++++-
 widget/material/list.go | 13 ++++++++++++-
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/widget/list.go b/widget/list.go
index 1d0c2a6..b293c0e 100644
--- a/widget/list.go
+++ b/widget/list.go
@@ -24,6 +24,10 @@ type Scrollbar struct {
	track, indicator gesture.Click
	drag             gesture.Drag
	delta            float32

	dragging            bool
	scrollScale         float32
	dragPos, oldDragPos float32
}

// Layout updates the internal state of the scrollbar based on events
@@ -60,12 +64,23 @@ func (s *Scrollbar) Layout(gtx layout.Context, axis layout.Axis, viewportStart,

	// Offset to account for any drags.
	for _, event := range s.drag.Events(gtx.Metric, gtx, gesture.Axis(axis)) {
		if event.Type != pointer.Drag {
		switch event.Type {
		case pointer.Drag:
		case pointer.Release:
			s.dragging = false
		default:
			continue
		}
		dragOffset := axis.FConvert(event.Position).X
		normalizedDragOffset := dragOffset / trackHeight
		s.delta += normalizedDragOffset - viewportStart

		s.dragPos = dragOffset
		if !s.dragging {
			s.dragging = true
			s.scrollScale = 1.0 / trackHeight
			s.oldDragPos = s.dragPos
		}
	}

	// Process events from the indicator so that hover is
@@ -105,6 +120,13 @@ func (s *Scrollbar) ScrollDistance() float32 {
	return s.delta
}

func (s *Scrollbar) ScrollDistance2() float32 {
	d := s.dragPos - s.oldDragPos
	dscroll := float32(d) * s.scrollScale
	s.oldDragPos = s.dragPos
	return dscroll
}

// List holds the persistent state for a layout.List that has a
// scrollbar attached.
type List struct {
diff --git a/widget/material/list.go b/widget/material/list.go
index 220671e..b3f8b96 100644
--- a/widget/material/list.go
+++ b/widget/material/list.go
@@ -279,12 +279,23 @@ func (l ListStyle) Layout(gtx layout.Context, length int, w layout.ListElement)
		return l.ScrollbarStyle.Layout(gtx, l.state.Axis, start, end)
	})

	if delta := l.state.ScrollDistance(); delta != 0 {
	/*if delta := l.state.ScrollDistance(); delta != 0 {
		// Handle any changes to the list position as a result of user interaction
		// with the scrollbar.
		deltaPx := int(math.Round(float64(float32(l.state.Position.Length) * delta)))
		l.state.List.Position.Offset += deltaPx

		// Ensure that the list pays attention to the Offset field when the scrollbar drag
		// is started while the bar is at the end of the list. Without this, the scrollbar
		// cannot be dragged away from the end.
		l.state.List.Position.BeforeEnd = true
	}*/

	if delta := l.state.ScrollDistance2(); delta != 0 {
		// Handle any changes to the list position as a result of user interaction
		// with the scrollbar.
		l.state.List.Position.Offset += int(math.Round(float64(float32(l.state.Position.Length) * delta)))

		// Ensure that the list pays attention to the Offset field when the scrollbar drag
		// is started while the bar is at the end of the list. Without this, the scrollbar
		// cannot be dragged away from the end.
-- 
2.32.0
builds.sr.ht
gio/patches: SUCCESS in 24m36s

[Alternative drag scroll approach][0] from [~eliasnaur][1]

[0]: https://lists.sr.ht/~eliasnaur/gio/patches/25116
[1]: mailto:mail@eliasnaur.com

✓ #585904 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/585904
✓ #585905 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/585905
✓ #585903 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/585903
✓ #585902 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/585902
Hey Elias,