mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
widget,widget/material: scroll using only drag position delta
This commit is based on a patch by Elias that improved drag scrolling on the scrollbar by locking some parameters of the math at the start of the scroll event. I discovered while playing with that implementation that there was an even simpler approach within his changeset. You can actually use no information other than the delta between the current and previous frame's scroll position to compute the scroll distance. By simplifying the math to rely on no other inputs, the jitter that we've been fighting simply disappears (it came from other inputs). Turns out my attempts to make the logic smart were the problem. Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
+18
-2
@@ -24,6 +24,9 @@ type Scrollbar struct {
|
||||
track, indicator gesture.Click
|
||||
drag gesture.Drag
|
||||
delta float32
|
||||
|
||||
dragging bool
|
||||
oldDragPos float32
|
||||
}
|
||||
|
||||
// Layout updates the internal state of the scrollbar based on events
|
||||
@@ -60,12 +63,25 @@ 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
|
||||
case pointer.Cancel:
|
||||
s.dragging = false
|
||||
continue
|
||||
default:
|
||||
continue
|
||||
}
|
||||
dragOffset := axis.FConvert(event.Position).X
|
||||
normalizedDragOffset := dragOffset / trackHeight
|
||||
s.delta += normalizedDragOffset - viewportStart
|
||||
|
||||
if !s.dragging {
|
||||
s.dragging = true
|
||||
s.oldDragPos = normalizedDragOffset
|
||||
}
|
||||
s.delta += normalizedDragOffset - s.oldDragPos
|
||||
s.oldDragPos = normalizedDragOffset
|
||||
}
|
||||
|
||||
// Process events from the indicator so that hover is
|
||||
|
||||
@@ -285,8 +285,7 @@ func (l ListStyle) Layout(gtx layout.Context, length int, w layout.ListElement)
|
||||
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
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user