Skip to content

Commit

Permalink
Implement the Draggable interface for mobile driver
Browse files Browse the repository at this point in the history
This is not 'mobile dragging' as widgets will need to adapt to the form factor.
Progresses #65
  • Loading branch information
andydotxyz committed Sep 27, 2019
1 parent 17b62a1 commit 2713f73
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
50 changes: 46 additions & 4 deletions internal/driver/gomobile/canvas.go
Expand Up @@ -23,9 +23,11 @@ type canvas struct {
typedKey func(event *fyne.KeyEvent)
shortcut fyne.ShortcutHandler

inited, dirty bool
lastTapDown int64
refreshQueue chan fyne.CanvasObject
inited, dirty bool
lastTapDown int64
lastTapDownPos fyne.Position
dragging fyne.Draggable
refreshQueue chan fyne.CanvasObject
}

func (c *canvas) Content() fyne.CanvasObject {
Expand Down Expand Up @@ -170,11 +172,51 @@ func (c *canvas) walkTree(

func (c *canvas) tapDown(pos fyne.Position) {
c.lastTapDown = time.Now().UnixNano()
c.lastTapDownPos = pos
c.dragging = nil
}

func (c *canvas) tapMove(pos fyne.Position,
dragCallback func(fyne.Draggable, *fyne.DragEvent)) {

if c.dragging == nil {
co, _ := driver.FindObjectAtPositionMatching(c.lastTapDownPos, func(object fyne.CanvasObject) bool {
if _, ok := object.(fyne.Draggable); ok {
return true
}

return false
}, c.overlay, c.content)

if drag, ok := co.(fyne.Draggable); ok {
c.dragging = drag
} else {
return
}
}
deltaX := pos.X - c.lastTapDownPos.X
deltaY := pos.Y - c.lastTapDownPos.Y
objPos := pos.Subtract(c.dragging.(fyne.CanvasObject).Position())

ev := new(fyne.DragEvent)
ev.Position = objPos
ev.DraggedX = deltaX
ev.DraggedY = deltaY

dragCallback(c.dragging, ev)
c.lastTapDownPos = pos
}

func (c *canvas) tapUp(pos fyne.Position,
tapCallback func(fyne.Tappable, *fyne.PointEvent),
tapAltCallback func(fyne.Tappable, *fyne.PointEvent)) {
tapAltCallback func(fyne.Tappable, *fyne.PointEvent),
dragCallback func(fyne.Draggable, *fyne.DragEvent)) {
if c.dragging != nil {
c.dragging.DragEnd()

c.dragging = nil
}

duration := time.Now().UnixNano() - c.lastTapDown

co, objPos := driver.FindObjectAtPositionMatching(pos, func(object fyne.CanvasObject) bool {
Expand Down
28 changes: 28 additions & 0 deletions internal/driver/gomobile/canvas_test.go
Expand Up @@ -43,6 +43,7 @@ func TestCanvas_Tapped(t *testing.T) {
wid.Tapped(ev)
}, func(wid fyne.Tappable, ev *fyne.PointEvent) {
wid.TappedSecondary(ev)
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})

assert.True(t, tapped)
Expand Down Expand Up @@ -70,9 +71,36 @@ func TestCanvas_TappedSecondary(t *testing.T) {
tapped = true
tappedObj = wid
wid.TappedSecondary(ev)
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
})

assert.True(t, tapped)
assert.False(t, buttonTap)
assert.Equal(t, button, tappedObj)
}

func TestCanvas_Dragged(t *testing.T) {
dragged := false
var draggedObj fyne.Draggable
scroll := widget.NewScrollContainer(widget.NewLabel("Hi\nHi\nHi"))
c := &canvas{content: scroll}
c.Resize(fyne.NewSize(36, 24))
assert.Equal(t, 0, scroll.Offset.Y)

c.tapDown(fyne.NewPos(35, 3))
c.tapMove(fyne.NewPos(35, 10), func(wid fyne.Draggable, ev *fyne.DragEvent) {
wid.Dragged(ev)
dragged = true
draggedObj = wid
})

offset := scroll.Offset.Y
assert.True(t, dragged)
assert.NotNil(t, draggedObj)
assert.Greater(t, offset, 0)

c.tapMove(fyne.NewPos(35, 5), func(wid fyne.Draggable, ev *fyne.DragEvent) {
wid.Dragged(ev)
})
assert.Less(t, scroll.Offset.Y, offset)
}
14 changes: 14 additions & 0 deletions internal/driver/gomobile/driver.go
Expand Up @@ -152,6 +152,8 @@ func (d *mobileDriver) Run() {
switch e.Type {
case touch.TypeBegin:
d.tapDownCanvas(canvas, e.X, e.Y)
case touch.TypeMove:
d.tapMoveCanvas(canvas, e.X, e.Y)
case touch.TypeEnd:
d.tapUpCanvas(canvas, e.X, e.Y)
}
Expand Down Expand Up @@ -212,6 +214,16 @@ func (d *mobileDriver) tapDownCanvas(canvas *canvas, x, y float32) {
canvas.tapDown(pos)
}

func (d *mobileDriver) tapMoveCanvas(canvas *canvas, x, y float32) {
tapX := internal.UnscaleInt(canvas, int(x))
tapY := internal.UnscaleInt(canvas, int(y))
pos := fyne.NewPos(tapX, tapY)

canvas.tapMove(pos, func(wid fyne.Draggable, ev *fyne.DragEvent) {
go wid.Dragged(ev)
})
}

func (d *mobileDriver) tapUpCanvas(canvas *canvas, x, y float32) {
tapX := internal.UnscaleInt(canvas, int(x))
tapY := internal.UnscaleInt(canvas, int(y))
Expand All @@ -221,6 +233,8 @@ func (d *mobileDriver) tapUpCanvas(canvas *canvas, x, y float32) {
go wid.Tapped(ev)
}, func(wid fyne.Tappable, ev *fyne.PointEvent) {
go wid.TappedSecondary(ev)
}, func(wid fyne.Draggable, ev *fyne.DragEvent) {
go wid.DragEnd()
})
}

Expand Down

0 comments on commit 2713f73

Please sign in to comment.