Files
gio/layout/list_test.go
T
Elias Naur 508330e818 layout: layout one invisible child at each end of a List
A recent change added automatic scrolling to move focused widgets
into view. This change modifies List to layout an extra child at
each of its ends, to enable focus to move to them and trigger
automatic scrolling of the list.

For https://github.com/tailscale/tailscale/issues/4278.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:55:48 +02:00

161 lines
3.9 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
package layout
import (
"image"
"testing"
"gioui.org/f32"
"gioui.org/io/event"
"gioui.org/io/pointer"
"gioui.org/io/router"
"gioui.org/op"
)
func TestEmptyList(t *testing.T) {
var l List
gtx := Context{
Ops: new(op.Ops),
Constraints: Exact(image.Pt(20, 10)),
}
dims := l.Layout(gtx, 0, nil)
if got, want := dims.Size, gtx.Constraints.Min; got != want {
t.Errorf("got %v; want %v", got, want)
}
}
func TestListPosition(t *testing.T) {
_s := func(e ...event.Event) []event.Event { return e }
r := new(router.Router)
gtx := Context{
Ops: new(op.Ops),
Constraints: Constraints{
Max: image.Pt(20, 10),
},
Queue: r,
}
el := func(gtx Context, idx int) Dimensions {
return Dimensions{Size: image.Pt(10, 10)}
}
for _, tc := range []struct {
label string
num int
scroll []event.Event
first int
count int
offset int
last int
}{
{label: "no item", last: 20},
{label: "1 visible 0 hidden", num: 1, count: 1, last: 10},
{label: "2 visible 0 hidden", num: 2, count: 2},
{label: "2 visible 1 hidden", num: 3, count: 2},
{label: "3 visible 0 hidden small scroll", num: 3, count: 3, offset: 5, last: -5,
scroll: _s(
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Press,
Position: f32.Pt(0, 0),
},
pointer.Event{
Source: pointer.Mouse,
Type: pointer.Scroll,
Scroll: f32.Pt(5, 0),
},
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Release,
Position: f32.Pt(5, 0),
},
)},
{label: "3 visible 0 hidden small scroll 2", num: 3, count: 3, offset: 3, last: -7,
scroll: _s(
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Press,
Position: f32.Pt(0, 0),
},
pointer.Event{
Source: pointer.Mouse,
Type: pointer.Scroll,
Scroll: f32.Pt(3, 0),
},
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Release,
Position: f32.Pt(5, 0),
},
)},
{label: "2 visible 1 hidden large scroll", num: 3, count: 2, first: 1,
scroll: _s(
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Press,
Position: f32.Pt(0, 0),
},
pointer.Event{
Source: pointer.Mouse,
Type: pointer.Scroll,
Scroll: f32.Pt(10, 0),
},
pointer.Event{
Source: pointer.Mouse,
Buttons: pointer.ButtonPrimary,
Type: pointer.Release,
Position: f32.Pt(15, 0),
},
)},
} {
t.Run(tc.label, func(t *testing.T) {
gtx.Ops.Reset()
var list List
// Initialize the list.
list.Layout(gtx, tc.num, el)
// Generate the scroll events.
r.Frame(gtx.Ops)
r.Queue(tc.scroll...)
// Let the list process the events.
list.Layout(gtx, tc.num, el)
pos := list.Position
if got, want := pos.First, tc.first; got != want {
t.Errorf("List: invalid first position: got %v; want %v", got, want)
}
if got, want := pos.Count, tc.count; got != want {
t.Errorf("List: invalid number of visible children: got %v; want %v", got, want)
}
if got, want := pos.Offset, tc.offset; got != want {
t.Errorf("List: invalid first visible offset: got %v; want %v", got, want)
}
if got, want := pos.OffsetLast, tc.last; got != want {
t.Errorf("List: invalid last visible offset: got %v; want %v", got, want)
}
})
}
}
func TestExtraChildren(t *testing.T) {
var l List
l.Position.First = 1
gtx := Context{
Ops: new(op.Ops),
Constraints: Exact(image.Pt(10, 10)),
}
count := 0
const all = 3
l.Layout(gtx, all, func(gtx Context, idx int) Dimensions {
count++
return Dimensions{Size: image.Pt(10, 10)}
})
if count != all {
t.Errorf("laid out %d of %d children", count, all)
}
}