Skip to content

Commit

Permalink
Merge pull request #5191 from andydotxyz/feature/mobilescroll
Browse files Browse the repository at this point in the history
  • Loading branch information
andydotxyz authored Oct 19, 2024
2 parents 0a260f1 + 2dcc530 commit e88cc1f
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 15 deletions.
11 changes: 8 additions & 3 deletions internal/driver/mobile/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type canvas struct {
initialized bool
lastTapDown map[int]time.Time
lastTapDownPos map[int]fyne.Position
lastTapDelta map[int]fyne.Delta
menu fyne.CanvasObject
padded bool
scale float32
Expand Down Expand Up @@ -54,6 +55,7 @@ func newCanvas(dev fyne.Device) fyne.Canvas {
device: d,
lastTapDown: make(map[int]time.Time),
lastTapDownPos: make(map[int]fyne.Position),
lastTapDelta: make(map[int]fyne.Delta),
padded: true,
scale: dev.SystemScaleForWindow(nil), // we don't need a window parameter on mobile,
touched: make(map[int]mobile.Touchable),
Expand Down Expand Up @@ -258,6 +260,8 @@ func (c *canvas) tapMove(pos fyne.Position, tapID int,
return
}
c.lastTapDownPos[tapID] = pos
offset := fyne.Delta{DX: deltaX, DY: deltaY}
c.lastTapDelta[tapID] = offset

co, objPos, _ := c.findObjectAtPositionMatching(pos, func(object fyne.CanvasObject) bool {
if _, ok := object.(fyne.Draggable); ok {
Expand Down Expand Up @@ -292,7 +296,7 @@ func (c *canvas) tapMove(pos fyne.Position, tapID int,
ev := &fyne.DragEvent{}
draggedObjDelta := c.dragStart.Subtract(c.dragging.(fyne.CanvasObject).Position())
ev.Position = pos.Subtract(c.dragOffset).Add(draggedObjDelta)
ev.Dragged = fyne.Delta{DX: deltaX, DY: deltaY}
ev.Dragged = offset

dragCallback(c.dragging, ev)
}
Expand All @@ -301,10 +305,11 @@ func (c *canvas) tapUp(pos fyne.Position, tapID int,
tapCallback func(fyne.Tappable, *fyne.PointEvent),
tapAltCallback func(fyne.SecondaryTappable, *fyne.PointEvent),
doubleTapCallback func(fyne.DoubleTappable, *fyne.PointEvent),
dragCallback func(fyne.Draggable)) {
dragCallback func(fyne.Draggable, *fyne.DragEvent)) {

if c.dragging != nil {
dragCallback(c.dragging)
previousDelta := c.lastTapDelta[tapID]
dragCallback(c.dragging, &fyne.DragEvent{Dragged: previousDelta})

c.dragging = nil
return
Expand Down
10 changes: 5 additions & 5 deletions internal/driver/mobile/canvas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ func Test_canvas_Tappable(t *testing.T) {
c.tapUp(fyne.NewPos(15, 15), 0, func(wid fyne.Tappable, ev *fyne.PointEvent) {
}, func(wid fyne.SecondaryTappable, ev *fyne.PointEvent) {
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
}, func(wid fyne.Draggable) {
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})
assert.True(t, content.up)

Expand Down Expand Up @@ -286,7 +286,7 @@ func Test_canvas_Tapped(t *testing.T) {
wid.TappedSecondary(ev)
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
wid.DoubleTapped(ev)
}, func(wid fyne.Draggable) {
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})

assert.True(t, tapped, "tap primary")
Expand Down Expand Up @@ -340,7 +340,7 @@ func Test_canvas_TappedMulti(t *testing.T) {
}, func(wid fyne.SecondaryTappable, ev *fyne.PointEvent) {
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
wid.DoubleTapped(ev)
}, func(wid fyne.Draggable) {
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})

assert.False(t, buttonTap, "button should not be tapped")
Expand Down Expand Up @@ -369,7 +369,7 @@ func Test_canvas_TappedSecondary(t *testing.T) {
wid.TappedSecondary(ev)
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
wid.DoubleTapped(ev)
}, func(wid fyne.Draggable) {
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})

assert.False(t, obj.tap, "don't tap primary")
Expand Down Expand Up @@ -464,7 +464,7 @@ func simulateTap(c *canvas) {
}, func(wid fyne.SecondaryTappable, ev *fyne.PointEvent) {
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
wid.DoubleTapped(ev)
}, func(wid fyne.Draggable) {
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})
}

Expand Down
2 changes: 1 addition & 1 deletion internal/driver/mobile/device_android.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package mobile

import "fyne.io/fyne/v2"

const tapYOffset = -12.0 // to compensate for how we hold our fingers on the device
const tapYOffset = -8.0 // to compensate for how we hold our fingers on the device

func (*device) SystemScaleForWindow(_ fyne.Window) float32 {
if currentDPI >= 600 {
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/mobile/device_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package mobile

import "fyne.io/fyne/v2"

const tapYOffset = -12.0 // to compensate for how we hold our fingers on the device
const tapYOffset = -8.0 // to compensate for how we hold our fingers on the device

func (*device) SystemScaleForWindow(_ fyne.Window) float32 {
if currentDPI >= 450 {
Expand Down
32 changes: 27 additions & 5 deletions internal/driver/mobile/driver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mobile

import (
"math"
"runtime"
"strconv"
"sync/atomic"
Expand Down Expand Up @@ -30,9 +31,11 @@ import (
)

const (
tapMoveThreshold = 4.0 // how far can we move before it is a drag
tapSecondaryDelay = 300 * time.Millisecond // how long before secondary tap
tapDoubleDelay = 500 * time.Millisecond // max duration between taps for a DoubleTap event
tapMoveDecay = 0.92 // how much should the scroll continue decay on each frame?
tapMoveEndThreshold = 2.0 // at what offset will we stop decaying?
tapMoveThreshold = 4.0 // how far can we move before it is a drag
tapSecondaryDelay = 300 * time.Millisecond // how long before secondary tap
tapDoubleDelay = 500 * time.Millisecond // max duration between taps for a DoubleTap event
)

// Configuration is the system information about the current device
Expand Down Expand Up @@ -399,8 +402,27 @@ func (d *driver) tapUpCanvas(w *window, x, y float32, tapID touch.Sequence) {
w.QueueEvent(func() { wid.TappedSecondary(ev) })
}, func(wid fyne.DoubleTappable, ev *fyne.PointEvent) {
w.QueueEvent(func() { wid.DoubleTapped(ev) })
}, func(wid fyne.Draggable) {
w.QueueEvent(wid.DragEnd)
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
if math.Abs(float64(ev.Dragged.DX)) <= tapMoveEndThreshold && math.Abs(float64(ev.Dragged.DY)) <= tapMoveEndThreshold {
w.QueueEvent(wid.DragEnd)
return
}

go func() {
for math.Abs(float64(ev.Dragged.DX)) > tapMoveEndThreshold || math.Abs(float64(ev.Dragged.DY)) > tapMoveEndThreshold {
if math.Abs(float64(ev.Dragged.DX)) > 0 {
ev.Dragged.DX *= tapMoveDecay
}
if math.Abs(float64(ev.Dragged.DY)) > 0 {
ev.Dragged.DY *= tapMoveDecay
}

w.QueueEvent(func() { wid.Dragged(ev) })
time.Sleep(time.Millisecond * 16)
}

w.QueueEvent(wid.DragEnd)
}()
})
}

Expand Down

0 comments on commit e88cc1f

Please sign in to comment.