apps/gophers: upgrade to simpler layout API

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-06-03 16:12:43 +02:00
parent df791f2e9b
commit 13f69a28ac
2 changed files with 91 additions and 86 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ module gioui.org/apps
go 1.12 go 1.12
require ( require (
gioui.org/ui v0.0.0-20190603132211-955fe1bc7705 gioui.org/ui v0.0.0-20190603140838-df791f2e9b17
github.com/google/go-github/v24 v24.0.1 github.com/google/go-github/v24 v24.0.1
golang.org/x/exp v0.0.0-20190321205749-f0864edee7f3 golang.org/x/exp v0.0.0-20190321205749-f0864edee7f3
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f
+90 -85
View File
@@ -230,8 +230,8 @@ func (a *App) run() error {
txt := fmt.Sprintf("m: %d %s", mallocs, a.w.Timings()) txt := fmt.Sprintf("m: %d %s", mallocs, a.w.Timings())
gdraw.OpColor{Col: textColor}.Add(ops) gdraw.OpColor{Col: textColor}.Add(ops)
dims := text.Label{Face: a.face(fonts.mono, 8), Text: txt}.Layout(ops, cs) dims := text.Label{Face: a.face(fonts.mono, 8), Text: txt}.Layout(ops, cs)
dims = in.End(ops, dims) dims = in.End(dims)
al.End(ops, dims) al.End(dims)
} }
a.w.Draw(ops) a.w.Draw(ops)
a.w.SetTextInput(a.kqueue.Frame(ops)) a.w.SetTextInput(a.kqueue.Frame(ops))
@@ -417,15 +417,15 @@ func (up *userPage) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
up.commits = commits up.commits = commits
default: default:
} }
l.Init(cs, len(up.commits)) l.Init(ops, cs, len(up.commits))
for { for {
i, cs, ok := l.Next(ops) i, cs, ok := l.Next()
if !ok { if !ok {
break break
} }
l.End(ops, up.commit(ops, cs, i)) l.End(up.commit(ops, cs, i))
} }
return l.Layout(ops) return l.Layout()
} }
func (up *userPage) commit(ops *ui.Ops, cs layout.Constraints, index int) layout.Dimens { func (up *userPage) commit(ops *ui.Ops, cs layout.Constraints, index int) layout.Dimens {
@@ -437,22 +437,22 @@ func (up *userPage) commit(ops *ui.Ops, cs layout.Constraints, index int) layout
in := layout.Insets{Top: c.Dp(16), Right: c.Dp(8), Left: c.Dp(8)} in := layout.Insets{Top: c.Dp(16), Right: c.Dp(8), Left: c.Dp(8)}
cs = in.Begin(ops, cs) cs = in.Begin(ops, cs)
f := layout.Flex{Axis: layout.Horizontal, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Start} f := layout.Flex{Axis: layout.Horizontal, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Start}
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
sz := c.Dp(48) sz := c.Dp(48)
cc := clipCircle{} cc := clipCircle{}
cs = cc.Begin(ops, cs) cs = cc.Begin(ops, cs)
dims := widget.Image{Src: u.avatar, Rect: u.avatar.Bounds()}.Layout(ops, layout.Sized{Width: sz, Height: sz}.Constrain(cs)) dims := widget.Image{Src: u.avatar, Rect: u.avatar.Bounds()}.Layout(ops, layout.Sized{Width: sz, Height: sz}.Constrain(cs))
dims = cc.End(ops, dims) dims = cc.End(dims)
c1 := f.End(ops, dims) c1 := f.End(dims)
cs = f.Flexible(ops, 1, layout.Fit) cs = f.Flexible(1, layout.Fit)
in = layout.Insets{Left: c.Dp(8)} in = layout.Insets{Left: c.Dp(8)}
cs = in.Begin(ops, cs) cs = in.Begin(ops, cs)
dims = label.Layout(ops, cs) dims = label.Layout(ops, cs)
dims = in.End(ops, dims) dims = in.End(dims)
c2 := f.End(ops, dims) c2 := f.End(dims)
dims = f.Layout(ops, c1, c2) dims = f.Layout(c1, c2)
return in.End(ops, dims) return in.End(dims)
} }
func (up *userPage) fetchCommits(ctx context.Context) { func (up *userPage) fetchCommits(ctx context.Context) {
@@ -482,60 +482,60 @@ func (a *App) layoutUsers(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
a.edit.Update(c, a.pqueue, a.kqueue) a.edit.Update(c, a.pqueue, a.kqueue)
a.edit2.Update(c, a.pqueue, a.kqueue) a.edit2.Update(c, a.pqueue, a.kqueue)
st := layout.Stack{Alignment: layout.Center} st := layout.Stack{Alignment: layout.Center}
st.Init(cs) st.Init(ops, cs)
cs = st.Rigid(ops) cs = st.Rigid()
al := layout.Align{Alignment: layout.SE} al := layout.Align{Alignment: layout.SE}
in := layout.EqualInsets(c.Dp(16)) in := layout.EqualInsets(c.Dp(16))
cs = in.Begin(ops, al.Begin(ops, cs)) cs = in.Begin(ops, al.Begin(ops, cs))
dims := a.fab.Layout(ops, cs) dims := a.fab.Layout(ops, cs)
dims = al.End(ops, in.End(ops, dims)) dims = al.End(in.End(dims))
c2 := st.End(ops, dims) c2 := st.End(dims)
cs = st.Expand(ops) cs = st.Expand()
{ {
f := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Stretch} f := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Stretch}
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
in := layout.EqualInsets(c.Dp(16)) in := layout.EqualInsets(c.Dp(16))
cs = layout.Sized{Height: c.Dp(200)}.Constrain(cs) cs = layout.Sized{Height: c.Dp(200)}.Constrain(cs)
gdraw.OpColor{Col: textColor}.Add(ops) gdraw.OpColor{Col: textColor}.Add(ops)
dims = a.edit.Layout(ops, in.Begin(ops, cs)) dims = a.edit.Layout(ops, in.Begin(ops, cs))
dims = in.End(ops, dims) dims = in.End(dims)
} }
c1 := f.End(ops, dims) c1 := f.End(dims)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
in := layout.Insets{Bottom: c.Dp(16), Left: c.Dp(16), Right: c.Dp(16)} in := layout.Insets{Bottom: c.Dp(16), Left: c.Dp(16), Right: c.Dp(16)}
gdraw.OpColor{Col: textColor}.Add(ops) gdraw.OpColor{Col: textColor}.Add(ops)
dims = a.edit2.Layout(ops, in.Begin(ops, cs)) dims = a.edit2.Layout(ops, in.Begin(ops, cs))
dims = in.End(ops, dims) dims = in.End(dims)
} }
c2 := f.End(ops, dims) c2 := f.End(dims)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
s := layout.Stack{Alignment: layout.Center} s := layout.Stack{Alignment: layout.Center}
s.Init(cs) s.Init(ops, cs)
cs = s.Rigid(ops) cs = s.Rigid()
in := layout.Insets{Top: c.Dp(16), Right: c.Dp(8), Bottom: c.Dp(8), Left: c.Dp(8)} in := layout.Insets{Top: c.Dp(16), Right: c.Dp(8), Bottom: c.Dp(8), Left: c.Dp(8)}
gdraw.OpColor{Col: rgb(0x888888)}.Add(ops) gdraw.OpColor{Col: rgb(0x888888)}.Add(ops)
lbl := text.Label{Face: a.face(fonts.regular, 9), Text: "GOPHERS"} lbl := text.Label{Face: a.face(fonts.regular, 9), Text: "GOPHERS"}
dims = in.End(ops, lbl.Layout(ops, in.Begin(ops, cs))) dims = in.End(lbl.Layout(ops, in.Begin(ops, cs)))
c2 := s.End(ops, dims) c2 := s.End(dims)
c1 := s.End(ops, fill{color: rgb(0xf2f2f2)}.Layout(ops, s.Expand(ops))) c1 := s.End(fill{color: rgb(0xf2f2f2)}.Layout(ops, s.Expand()))
dims = s.Layout(ops, c1, c2) dims = s.Layout(c1, c2)
} }
c3 := f.End(ops, dims) c3 := f.End(dims)
dims = a.layoutContributors(ops, f.Flexible(ops, 1, layout.Fit)) dims = a.layoutContributors(ops, f.Flexible(1, layout.Fit))
c4 := f.End(ops, dims) c4 := f.End(dims)
dims = f.Layout(ops, c1, c2, c3, c4) dims = f.Layout(c1, c2, c3, c4)
} }
c1 := st.End(ops, dims) c1 := st.End(dims)
return st.Layout(ops, c1, c2) return st.Layout(c1, c2)
} }
func (a *ActionButton) Update(c *ui.Config, q pointer.Events) { func (a *ActionButton) Update(c *ui.Config, q pointer.Events) {
@@ -548,15 +548,15 @@ func (a *ActionButton) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens
c := a.cfg c := a.cfg
fabCol := brandColor fabCol := brandColor
f := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.End, MainAxisSize: layout.Min} f := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.End, MainAxisSize: layout.Min}
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
in := layout.Insets{Top: c.Dp(4)} in := layout.Insets{Top: c.Dp(4)}
cs = in.Begin(ops, cs) cs = in.Begin(ops, cs)
dims := fab(ops, cs, a.sendIco.image(c), fabCol, c.Dp(56)) dims := fab(ops, cs, a.sendIco.image(c), fabCol, c.Dp(56))
pointer.AreaEllipse(dims.Size).Add(ops) pointer.AreaEllipse(dims.Size).Add(ops)
a.btnClicker.Add(ops) a.btnClicker.Add(ops)
dims = in.End(ops, dims) dims = in.End(dims)
return f.Layout(ops, f.End(ops, dims)) return f.Layout(f.End(dims))
} }
func (a *App) layoutContributors(ops *ui.Ops, cs layout.Constraints) layout.Dimens { func (a *App) layoutContributors(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
@@ -566,15 +566,15 @@ func (a *App) layoutContributors(ops *ui.Ops, cs layout.Constraints) layout.Dime
if l.Dragging() { if l.Dragging() {
key.OpHideInput{}.Add(ops) key.OpHideInput{}.Add(ops)
} }
l.Init(cs, len(a.users)) l.Init(ops, cs, len(a.users))
for { for {
i, cs, ok := l.Next(ops) i, cs, ok := l.Next()
if !ok { if !ok {
break break
} }
l.End(ops, a.user(ops, cs, c, i)) l.End(a.user(ops, cs, c, i))
} }
dims := l.Layout(ops) dims := l.Layout()
return dims return dims
} }
@@ -587,63 +587,63 @@ func (a *App) user(ops *ui.Ops, cs layout.Constraints, c *ui.Config, index int)
} }
} }
elem := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Start} elem := layout.Flex{Axis: layout.Vertical, MainAxisAlignment: layout.Start, CrossAxisAlignment: layout.Start}
elem.Init(cs) elem.Init(ops, cs)
cs = elem.Rigid(ops) cs = elem.Rigid()
var dims layout.Dimens var dims layout.Dimens
{ {
in := layout.EqualInsets(c.Dp(8)) in := layout.EqualInsets(c.Dp(8))
cs = in.Begin(ops, cs) cs = in.Begin(ops, cs)
f := centerRowOpts() f := centerRowOpts()
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
in := layout.Insets{Right: c.Dp(8)} in := layout.Insets{Right: c.Dp(8)}
cc := clipCircle{} cc := clipCircle{}
cs = cc.Begin(ops, in.Begin(ops, cs)) cs = cc.Begin(ops, in.Begin(ops, cs))
dims = widget.Image{Src: u.avatar, Rect: u.avatar.Bounds()}.Layout(ops, layout.Sized{Width: c.Dp(48), Height: c.Dp(48)}.Constrain(cs)) dims = widget.Image{Src: u.avatar, Rect: u.avatar.Bounds()}.Layout(ops, layout.Sized{Width: c.Dp(48), Height: c.Dp(48)}.Constrain(cs))
dims = in.End(ops, cc.End(ops, dims)) dims = in.End(cc.End(dims))
} }
c1 := f.End(ops, dims) c1 := f.End(dims)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
f := column() f := column()
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
{ {
f := baseline() f := baseline()
f.Init(cs) f.Init(ops, cs)
cs = f.Rigid(ops) cs = f.Rigid()
gdraw.OpColor{Col: textColor}.Add(ops) gdraw.OpColor{Col: textColor}.Add(ops)
dims = text.Label{Face: a.face(fonts.regular, 11), Text: u.name}.Layout(ops, cs) dims = text.Label{Face: a.face(fonts.regular, 11), Text: u.name}.Layout(ops, cs)
c1 := f.End(ops, dims) c1 := f.End(dims)
cs = f.Rigid(ops) cs = f.Rigid()
al := layout.Align{Alignment: layout.E} al := layout.Align{Alignment: layout.E}
in := layout.Insets{Left: c.Dp(2)} in := layout.Insets{Left: c.Dp(2)}
cs = in.Begin(ops, al.Begin(ops, cs)) cs = in.Begin(ops, al.Begin(ops, cs))
gdraw.OpColor{Col: textColor}.Add(ops) gdraw.OpColor{Col: textColor}.Add(ops)
dims = text.Label{Face: a.face(fonts.regular, 8), Text: "3 hours ago"}.Layout(ops, cs) dims = text.Label{Face: a.face(fonts.regular, 8), Text: "3 hours ago"}.Layout(ops, cs)
dims = al.End(ops, in.End(ops, dims)) dims = al.End(in.End(dims))
c2 := f.End(ops, dims) c2 := f.End(dims)
dims = f.Layout(ops, c1, c2) dims = f.Layout(c1, c2)
} }
c1 := f.End(ops, dims) c1 := f.End(dims)
cs = f.Rigid(ops) cs = f.Rigid()
in := layout.Insets{Top: c.Dp(4)} in := layout.Insets{Top: c.Dp(4)}
cs = in.Begin(ops, cs) cs = in.Begin(ops, cs)
gdraw.OpColor{Col: tertTextColor}.Add(ops) gdraw.OpColor{Col: tertTextColor}.Add(ops)
dims = text.Label{Face: a.face(fonts.regular, 10), Text: u.company}.Layout(ops, cs) dims = text.Label{Face: a.face(fonts.regular, 10), Text: u.company}.Layout(ops, cs)
dims = in.End(ops, dims) dims = in.End(dims)
c2 := f.End(ops, dims) c2 := f.End(dims)
dims = f.Layout(ops, c1, c2) dims = f.Layout(c1, c2)
} }
c2 := f.End(ops, dims) c2 := f.End(dims)
dims = f.Layout(ops, c1, c2) dims = f.Layout(c1, c2)
dims = in.End(ops, dims) dims = in.End(dims)
pointer.AreaRect(dims.Size).Add(ops) pointer.AreaRect(dims.Size).Add(ops)
click.Add(ops) click.Add(ops)
} }
c1 := elem.End(ops, dims) c1 := elem.End(dims)
return elem.Layout(ops, c1) return elem.Layout(c1)
} }
type fill struct { type fill struct {
@@ -678,14 +678,18 @@ func baseline() layout.Flex {
return layout.Flex{Axis: layout.Horizontal, CrossAxisAlignment: layout.Baseline, MainAxisSize: layout.Min} return layout.Flex{Axis: layout.Horizontal, CrossAxisAlignment: layout.Baseline, MainAxisSize: layout.Min}
} }
type clipCircle struct{} type clipCircle struct {
ops *ui.Ops
}
func (c *clipCircle) Begin(ops *ui.Ops, cs layout.Constraints) layout.Constraints { func (c *clipCircle) Begin(ops *ui.Ops, cs layout.Constraints) layout.Constraints {
c.ops = ops
ops.Begin() ops.Begin()
return cs return cs
} }
func (c *clipCircle) End(ops *ui.Ops, dims layout.Dimens) layout.Dimens { func (c *clipCircle) End(dims layout.Dimens) layout.Dimens {
ops := c.ops
block := ops.End() block := ops.End()
max := dims.Size.X max := dims.Size.X
if dy := dims.Size.Y; dy > max { if dy := dims.Size.Y; dy > max {
@@ -747,15 +751,16 @@ func rrect(ops *ui.Ops, width, height, se, sw, nw, ne float32) {
w, h := float32(width), float32(height) w, h := float32(width), float32(height)
const c = 0.55228475 // 4*(sqrt(2)-1)/3 const c = 0.55228475 // 4*(sqrt(2)-1)/3
var b gdraw.PathBuilder var b gdraw.PathBuilder
b.Move(ops, f32.Point{X: w, Y: h - se}) b.Init(ops)
b.Cube(ops, f32.Point{X: 0, Y: se * c}, f32.Point{X: -se + se*c, Y: se}, f32.Point{X: -se, Y: se}) // SE b.Move(f32.Point{X: w, Y: h - se})
b.Line(ops, f32.Point{X: sw - w + se, Y: 0}) b.Cube(f32.Point{X: 0, Y: se * c}, f32.Point{X: -se + se*c, Y: se}, f32.Point{X: -se, Y: se}) // SE
b.Cube(ops, f32.Point{X: -sw * c, Y: 0}, f32.Point{X: -sw, Y: -sw + sw*c}, f32.Point{X: -sw, Y: -sw}) // SW b.Line(f32.Point{X: sw - w + se, Y: 0})
b.Line(ops, f32.Point{X: 0, Y: nw - h + sw}) b.Cube(f32.Point{X: -sw * c, Y: 0}, f32.Point{X: -sw, Y: -sw + sw*c}, f32.Point{X: -sw, Y: -sw}) // SW
b.Cube(ops, f32.Point{X: 0, Y: -nw * c}, f32.Point{X: nw - nw*c, Y: -nw}, f32.Point{X: nw, Y: -nw}) // NW b.Line(f32.Point{X: 0, Y: nw - h + sw})
b.Line(ops, f32.Point{X: w - ne - nw, Y: 0}) b.Cube(f32.Point{X: 0, Y: -nw * c}, f32.Point{X: nw - nw*c, Y: -nw}, f32.Point{X: nw, Y: -nw}) // NW
b.Cube(ops, f32.Point{X: ne * c, Y: 0}, f32.Point{X: ne, Y: ne - ne*c}, f32.Point{X: ne, Y: ne}) // NE b.Line(f32.Point{X: w - ne - nw, Y: 0})
b.End(ops) b.Cube(f32.Point{X: ne * c, Y: 0}, f32.Point{X: ne, Y: ne - ne*c}, f32.Point{X: ne, Y: ne}) // NE
b.End()
} }
const longTextSample = `1. I learned from my grandfather, Verus, to use good manners, and to const longTextSample = `1. I learned from my grandfather, Verus, to use good manners, and to