ui/layout: introduce Context

Context keeps the current Constraints and Dimensions so the layout
function scopes don't have to.

With

	ctx := new(layout.Context)

a label with margins and alignment goes from

	return al.Layout(ops, cs, func(cs layout.Constraints) layout.Dimensions {
		in := layout.Inset{...}
		return in.Layout(c, ops, cs, func(cs layout.Constraints) layout.Dimensions {
			return text.Label{...}.Layout(ops, cs)
		})
	})

to

	al.Layout(ops, ctx, func() {
		in := layout.Inset{...}
		in.Layout(c, ops, ctx, func() {
		       text.Label{...}.Layout(ops, ctx)
		})
	})

It was a difficult trade-off between the verbose functional approach
and the shorter but more complex Context.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-09-24 19:06:07 +02:00
parent 64add13d28
commit ce9bcee62b
9 changed files with 126 additions and 89 deletions
+3 -2
View File
@@ -165,7 +165,8 @@ func (e *Editor) Focus() {
e.requestFocus = true
}
func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, cs layout.Constraints) layout.Dimensions {
func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, ctx *layout.Context) {
cs := ctx.Constraints
for _, ok := e.Next(cfg, queue); ok; _, ok = e.Next(cfg, queue) {
}
twoDp := cfg.Px(ui.Dp(2))
@@ -270,7 +271,7 @@ func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, cs layout
pointer.RectAreaOp{Rect: r}.Add(ops)
e.scroller.Add(ops)
e.clicker.Add(ops)
return layout.Dimensions{Size: e.viewSize, Baseline: baseline}
ctx.Dimensions = layout.Dimensions{Size: e.viewSize, Baseline: baseline}
}
// Text returns the contents of the editor.
+3 -2
View File
@@ -92,7 +92,8 @@ func (l *lineIterator) Next() (String, f32.Point, bool) {
return String{}, f32.Point{}, false
}
func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimensions {
func (l Label) Layout(ops *ui.Ops, ctx *layout.Context) {
cs := ctx.Constraints
textLayout := l.Face.Layout(l.Text, LayoutOptions{MaxWidth: cs.Width.Max})
lines := textLayout.Lines
if max := l.MaxLines; max > 0 && len(lines) > max {
@@ -127,7 +128,7 @@ func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimensions {
paint.PaintOp{Rect: lclip}.Add(ops)
stack.Pop()
}
return dims
ctx.Dimensions = dims
}
func toRectF(r image.Rectangle) f32.Rectangle {