M ui/layout/doc.go => ui/layout/doc.go +7 -7
@@ 13,17 13,17 @@ in an implicit Context to keep the Widget declaration short.
For example, to add space above a widget:
- ctx := new(layout.Context)
- ctx.Constraints = ...
+ c := &layout.Context{...}
+ c.Reset(...)
// Configure a top inset.
inset := layout.Inset{Top: ui.Dp(8), ...}
// Use the inset to lay out a widget.
- inset.Layout(..., ctx, func() {
+ inset.Layout(c, func() {
// Lay out widget and determine its size given the constraints.
...
dims := layout.Dimensions{...}
- ctx.Dimensions = dims
+ c.Dimensions = dims
})
Note that the example does not generate any garbage even though the
@@ 37,10 37,10 @@ be created from a few generic layouts.
This example both aligns and insets a child:
inset := layout.Inset{...}
- inset.Layout(..., ctx, func() {
+ inset.Layout(c, func() {
align := layout.Align(...)
- align.Layout(..., ctx, func() {
- widget.Layout(..., ctx)
+ align.Layout(c, func() {
+ widget.Layout(c, ...)
})
})
M ui/layout/flex.go => ui/layout/flex.go +6 -8
@@ 22,7 22,6 @@ type Flex struct {
ctx *Context
macro ui.MacroOp
- ops *ui.Ops
mode flexMode
size int
rigidSize int
@@ 69,13 68,12 @@ const (
)
// Init must be called before Rigid or Flexible.
-func (f *Flex) Init(ops *ui.Ops, ctx *Context) *Flex {
+func (f *Flex) Init(c *Context) *Flex {
if f.mode > modeBegun {
panic("must End the current child before calling Init again")
}
f.mode = modeBegun
- f.ops = ops
- f.ctx = ctx
+ f.ctx = c
f.size = 0
f.rigidSize = 0
f.maxCross = 0
@@ 91,7 89,7 @@ func (f *Flex) begin(mode flexMode) {
panic("must End before adding a child")
}
f.mode = mode
- f.macro.Record(f.ops)
+ f.macro.Record(f.ctx.Ops)
}
// Rigid lays out a widget with the main axis constrained to the range
@@ 192,9 190,9 @@ func (f *Flex) Layout(children ...FlexChild) {
}
}
var stack ui.StackOp
- stack.Push(f.ops)
- ui.TransformOp{}.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))).Add(f.ops)
- child.macro.Add(f.ops)
+ stack.Push(f.ctx.Ops)
+ ui.TransformOp{}.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))).Add(f.ctx.Ops)
+ child.macro.Add(f.ctx.Ops)
stack.Pop()
mainSize += axisMain(f.Axis, dims.Size)
if i < len(children)-1 {
M ui/layout/layout.go => ui/layout/layout.go +36 -18
@@ 6,6 6,7 @@ import (
"image"
"gioui.org/ui"
+ "gioui.org/ui/input"
)
// Constraints represent a set of acceptable ranges for
@@ 41,11 42,18 @@ type Direction uint8
// computing dimensions for a user interface element.
type Widget func()
-// Context tracks the current constraints and dimensions during
-// layout.
+// Context carry the state needed by almost all layouts and widgets.
type Context struct {
+ // Constraints track the constraints for the active widget or
+ // layout.
Constraints Constraints
- Dimensions Dimensions
+ // Dimensions track the result of the most recent layout
+ // operation.
+ Dimensions Dimensions
+
+ ui.Config
+ input.Queue
+ *ui.Ops
}
const (
@@ 83,6 91,16 @@ func (s *Context) Layout(cs Constraints, w Widget) Dimensions {
return s.Dimensions
}
+// Reset the context.
+func (c *Context) Reset(cfg ui.Config, cs Constraints) {
+ c.Constraints = cs
+ c.Config = cfg
+ if c.Ops == nil {
+ c.Ops = new(ui.Ops)
+ }
+ c.Ops.Reset()
+}
+
// Constrain a value to the range [Min; Max].
func (c Constraint) Constrain(v int) int {
if v < c.Min {
@@ 116,12 134,12 @@ type Inset struct {
type Align Direction
// Layout a widget.
-func (in Inset) Layout(c ui.Config, ops *ui.Ops, ctx *Context, w Widget) {
+func (in Inset) Layout(c *Context, w Widget) {
top := c.Px(in.Top)
right := c.Px(in.Right)
bottom := c.Px(in.Bottom)
left := c.Px(in.Left)
- mcs := ctx.Constraints
+ mcs := c.Constraints
mcs.Width.Min -= left + right
mcs.Width.Max -= left + right
if mcs.Width.Min < 0 {
@@ 139,12 157,12 @@ func (in Inset) Layout(c ui.Config, ops *ui.Ops, ctx *Context, w Widget) {
mcs.Height.Max = mcs.Height.Min
}
var stack ui.StackOp
- stack.Push(ops)
- ui.TransformOp{}.Offset(toPointF(image.Point{X: left, Y: top})).Add(ops)
- dims := ctx.Layout(mcs, w)
+ stack.Push(c.Ops)
+ ui.TransformOp{}.Offset(toPointF(image.Point{X: left, Y: top})).Add(c.Ops)
+ dims := c.Layout(mcs, w)
stack.Pop()
- ctx.Dimensions = Dimensions{
- Size: ctx.Constraints.Constrain(dims.Size.Add(image.Point{X: right + left, Y: top + bottom})),
+ c.Dimensions = Dimensions{
+ Size: c.Constraints.Constrain(dims.Size.Add(image.Point{X: right + left, Y: top + bottom})),
Baseline: dims.Baseline + top,
}
}
@@ 156,14 174,14 @@ func UniformInset(v ui.Value) Inset {
}
// Layout a widget.
-func (a Align) Layout(ops *ui.Ops, st *Context, w Widget) {
+func (a Align) Layout(c *Context, w Widget) {
var macro ui.MacroOp
- macro.Record(ops)
- cs := st.Constraints
+ macro.Record(c.Ops)
+ cs := c.Constraints
mcs := cs
mcs.Width.Min = 0
mcs.Height.Min = 0
- dims := st.Layout(mcs, w)
+ dims := c.Layout(mcs, w)
macro.Stop()
sz := dims.Size
if sz.X < cs.Width.Min {
@@ 186,11 204,11 @@ func (a Align) Layout(ops *ui.Ops, st *Context, w Widget) {
p.Y = sz.Y - dims.Size.Y
}
var stack ui.StackOp
- stack.Push(ops)
- ui.TransformOp{}.Offset(toPointF(p)).Add(ops)
- macro.Add(ops)
+ stack.Push(c.Ops)
+ ui.TransformOp{}.Offset(toPointF(p)).Add(c.Ops)
+ macro.Add(c.Ops)
stack.Pop()
- st.Dimensions = Dimensions{
+ c.Dimensions = Dimensions{
Size: sz,
Baseline: dims.Baseline,
}
M ui/layout/layout_test.go => ui/layout/layout_test.go +36 -40
@@ 18,22 18,22 @@ var q queue
var cfg = new(config)
func ExampleInset() {
- ops := new(ui.Ops)
- ctx := new(layout.Context)
-
+ c := &layout.Context{Queue: q}
// Loose constraints with no minimal size.
- ctx.Constraints.Width.Max = 100
- ctx.Constraints.Height.Max = 100
+ var cs layout.Constraints
+ cs.Width.Max = 100
+ cs.Height.Max = 100
+ c.Reset(cfg, cs)
// Inset all edges by 10.
inset := layout.UniformInset(ui.Dp(10))
- inset.Layout(cfg, ops, ctx, func() {
+ inset.Layout(c, func() {
// Lay out a 50x50 sized widget.
- layoutWidget(ctx, 50, 50)
- fmt.Println(ctx.Dimensions.Size)
+ layoutWidget(c, 50, 50)
+ fmt.Println(c.Dimensions.Size)
})
- fmt.Println(ctx.Dimensions.Size)
+ fmt.Println(c.Dimensions.Size)
// Output:
// (50,50)
@@ 41,20 41,19 @@ func ExampleInset() {
}
func ExampleAlign() {
- ops := new(ui.Ops)
- ctx := new(layout.Context)
-
+ c := &layout.Context{Queue: q}
// Rigid constraints with both minimum and maximum set.
- ctx.Constraints = layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ cs := layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c.Reset(cfg, cs)
align := layout.Align(layout.Center)
- align.Layout(ops, ctx, func() {
+ align.Layout(c, func() {
// Lay out a 50x50 sized widget.
- layoutWidget(ctx, 50, 50)
- fmt.Println(ctx.Dimensions.Size)
+ layoutWidget(c, 50, 50)
+ fmt.Println(c.Dimensions.Size)
})
- fmt.Println(ctx.Dimensions.Size)
+ fmt.Println(c.Dimensions.Size)
// Output:
// (50,50)
@@ 62,24 61,23 @@ func ExampleAlign() {
}
func ExampleFlex() {
- ops := new(ui.Ops)
- ctx := new(layout.Context)
-
- ctx.Constraints = layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c := &layout.Context{Queue: q}
+ cs := layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c.Reset(cfg, cs)
flex := layout.Flex{}
- flex.Init(ops, ctx)
+ flex.Init(c)
// Rigid 10x10 widget.
child1 := flex.Rigid(func() {
- fmt.Printf("Rigid: %v\n", ctx.Constraints.Width)
- layoutWidget(ctx, 10, 10)
+ fmt.Printf("Rigid: %v\n", c.Constraints.Width)
+ layoutWidget(c, 10, 10)
})
// Child with 50% space allowance.
child2 := flex.Flexible(0.5, func() {
- fmt.Printf("50%%: %v\n", ctx.Constraints.Width)
- layoutWidget(ctx, 10, 10)
+ fmt.Printf("50%%: %v\n", c.Constraints.Width)
+ layoutWidget(c, 10, 10)
})
flex.Layout(child1, child2)
@@ 90,23 88,22 @@ func ExampleFlex() {
}
func ExampleStack() {
- ops := new(ui.Ops)
- ctx := new(layout.Context)
-
- ctx.Constraints = layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c := &layout.Context{Queue: q}
+ cs := layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c.Reset(cfg, cs)
stack := layout.Stack{}
- stack.Init(ops, ctx)
+ stack.Init(c)
// Rigid 50x50 widget.
child1 := stack.Rigid(func() {
- layoutWidget(ctx, 50, 50)
+ layoutWidget(c, 50, 50)
})
// Force widget to the same size as the first.
child2 := stack.Expand(func() {
- fmt.Printf("Expand: %v\n", ctx.Constraints)
- layoutWidget(ctx, 10, 10)
+ fmt.Printf("Expand: %v\n", c.Constraints)
+ layoutWidget(c, 10, 10)
})
stack.Layout(child1, child2)
@@ 116,19 113,18 @@ func ExampleStack() {
}
func ExampleList() {
- ops := new(ui.Ops)
- ctx := new(layout.Context)
-
- ctx.Constraints = layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c := &layout.Context{Queue: q}
+ cs := layout.RigidConstraints(image.Point{X: 100, Y: 100})
+ c.Reset(cfg, cs)
// The list is 1e6 elements, but only 5 fit the constraints.
const listLen = 1e6
var list layout.List
count := 0
- list.Layout(cfg, q, ops, ctx, listLen, func(i int) {
+ list.Layout(c, listLen, func(i int) {
count++
- layoutWidget(ctx, 20, 20)
+ layoutWidget(c, 20, 20)
})
fmt.Println(count)
M ui/layout/list.go => ui/layout/list.go +15 -23
@@ 7,7 7,6 @@ import (
"gioui.org/ui"
"gioui.org/ui/gesture"
- "gioui.org/ui/input"
"gioui.org/ui/paint"
"gioui.org/ui/pointer"
)
@@ 33,9 32,7 @@ type List struct {
// the very end.
beforeEnd bool
- config ui.Config
- ops *ui.Ops
- queue input.Queue
+ ctx *Context
macro ui.MacroOp
child ui.MacroOp
scroll gesture.Scroll
@@ 47,7 44,6 @@ type List struct {
// to the child with index first.
offset int
- cs Constraints
len int
// maxSize is the total size of visible children.
@@ 71,18 67,15 @@ const (
const inf = 1e6
// Init prepares the list for iterating through its children with Next.
-func (l *List) init(cfg ui.Config, q input.Queue, ops *ui.Ops, cs Constraints, len int) {
+func (l *List) init(c *Context, len int) {
if l.more() {
panic("unfinished child")
}
- l.config = cfg
- l.queue = q
- l.update()
- l.ops = ops
+ l.ctx = c
l.maxSize = 0
l.children = l.children[:0]
- l.cs = cs
l.len = len
+ l.update()
if l.scrollToEnd() {
l.offset = 0
l.first = len
@@ 91,21 84,20 @@ func (l *List) init(cfg ui.Config, q input.Queue, ops *ui.Ops, cs Constraints, l
l.offset = 0
l.first = len
}
- l.macro.Record(ops)
+ l.macro.Record(c.Ops)
l.next()
}
// Layout the List and return its dimensions.
-func (l *List) Layout(c ui.Config, q input.Queue, ops *ui.Ops, ctx *Context, len int, w ListElement) {
- cs := ctx.Constraints
- for l.init(c, q, ops, cs, len); l.more(); l.next() {
- cs := axisConstraints(l.Axis, Constraint{Max: inf}, axisCrossConstraint(l.Axis, l.cs))
+func (l *List) Layout(c *Context, len int, w ListElement) {
+ for l.init(c, len); l.more(); l.next() {
+ cs := axisConstraints(l.Axis, Constraint{Max: inf}, axisCrossConstraint(l.Axis, l.ctx.Constraints))
i := l.index()
- l.end(ctx.Layout(cs, func() {
+ l.end(c.Layout(cs, func() {
w(i)
}))
}
- ctx.Dimensions = l.layout()
+ c.Dimensions = l.layout()
}
func (l *List) scrollToEnd() bool {
@@ 118,7 110,7 @@ func (l *List) Dragging() bool {
}
func (l *List) update() {
- d := l.scroll.Scroll(l.config, l.queue, gesture.Axis(l.Axis))
+ d := l.scroll.Scroll(l.ctx.Config, l.ctx.Queue, gesture.Axis(l.Axis))
l.scrollDelta = d
l.offset += d
}
@@ 134,7 126,7 @@ func (l *List) next() {
l.dir = l.nextDir()
}
if l.more() {
- l.child.Record(l.ops)
+ l.child.Record(l.ctx.Ops)
}
}
@@ 156,7 148,7 @@ func (l *List) more() bool {
}
func (l *List) nextDir() iterationDir {
- vsize := axisMainConstraint(l.Axis, l.cs).Max
+ vsize := axisMainConstraint(l.Axis, l.ctx.Constraints).Max
last := l.first + len(l.children)
// Clamp offset.
if l.maxSize-l.offset < vsize && last == l.len {
@@ 200,7 192,7 @@ func (l *List) layout() Dimensions {
if l.more() {
panic("unfinished child")
}
- mainc := axisMainConstraint(l.Axis, l.cs)
+ mainc := axisMainConstraint(l.Axis, l.ctx.Constraints)
children := l.children
// Skip invisible children
for len(children) > 0 {
@@ 226,7 218,7 @@ func (l *List) layout() Dimensions {
break
}
}
- ops := l.ops
+ ops := l.ctx.Ops
pos := -l.offset
// ScrollToEnd lists lists are end aligned.
if space := mainc.Max - size; l.ScrollToEnd && space > 0 {
M ui/layout/stack.go => ui/layout/stack.go +6 -8
@@ 16,7 16,6 @@ type Stack struct {
Alignment Direction
macro ui.MacroOp
- ops *ui.Ops
constrained bool
ctx *Context
maxSZ image.Point
@@ 30,9 29,8 @@ type StackChild struct {
}
// Init a stack before calling Rigid or Expand.
-func (s *Stack) Init(ops *ui.Ops, ctx *Context) *Stack {
- s.ops = ops
- s.ctx = ctx
+func (s *Stack) Init(c *Context) *Stack {
+ s.ctx = c
s.constrained = true
s.maxSZ = image.Point{}
s.baseline = 0
@@ 43,7 41,7 @@ func (s *Stack) begin() {
if !s.constrained {
panic("must Init before adding a child")
}
- s.macro.Record(s.ops)
+ s.macro.Record(s.ctx.Ops)
}
// Rigid lays out a widget with the same constraints that were
@@ 102,9 100,9 @@ func (s *Stack) Layout(children ...StackChild) {
p.Y = s.maxSZ.Y - sz.Y
}
var stack ui.StackOp
- stack.Push(s.ops)
- ui.TransformOp{}.Offset(toPointF(p)).Add(s.ops)
- ch.macro.Add(s.ops)
+ stack.Push(s.ctx.Ops)
+ ui.TransformOp{}.Offset(toPointF(p)).Add(s.ctx.Ops)
+ ch.macro.Add(s.ctx.Ops)
stack.Pop()
}
b := s.baseline
M ui/text/editor.go => ui/text/editor.go +37 -38
@@ 11,7 11,6 @@ import (
"gioui.org/ui"
"gioui.org/ui/gesture"
- "gioui.org/ui/input"
"gioui.org/ui/key"
"gioui.org/ui/layout"
"gioui.org/ui/paint"
@@ 82,9 81,9 @@ const (
)
// Next returns the next available editor event, or false if none are available.
-func (e *Editor) Next(cfg ui.Config, queue input.Queue) (EditorEvent, bool) {
+func (e *Editor) Next(c *layout.Context) (EditorEvent, bool) {
// Crude configuration change detection.
- if scale := cfg.Px(ui.Sp(100)); scale != e.oldScale {
+ if scale := c.Px(ui.Sp(100)); scale != e.oldScale {
e.invalidate()
e.oldScale = scale
}
@@ 98,7 97,7 @@ func (e *Editor) Next(cfg ui.Config, queue input.Queue) (EditorEvent, bool) {
axis = gesture.Vertical
smin, smax = sbounds.Min.Y, sbounds.Max.Y
}
- sdist := e.scroller.Scroll(cfg, queue, axis)
+ sdist := e.scroller.Scroll(c.Config, c.Queue, axis)
var soff int
if e.SingleLine {
e.scrollOff.X += sdist
@@ 107,26 106,26 @@ func (e *Editor) Next(cfg ui.Config, queue input.Queue) (EditorEvent, bool) {
e.scrollOff.Y += sdist
soff = e.scrollOff.Y
}
- for evt, ok := e.clicker.Next(queue); ok; evt, ok = e.clicker.Next(queue) {
+ for evt, ok := e.clicker.Next(c.Queue); ok; evt, ok = e.clicker.Next(c.Queue) {
switch {
case evt.Type == gesture.TypePress && evt.Source == pointer.Mouse,
evt.Type == gesture.TypeClick && evt.Source == pointer.Touch:
- e.blinkStart = cfg.Now()
+ e.blinkStart = c.Now()
e.moveCoord(image.Point{
X: int(math.Round(float64(evt.Position.X))),
Y: int(math.Round(float64(evt.Position.Y))),
})
e.requestFocus = true
if e.scroller.State() != gesture.StateFlinging {
- e.scrollToCaret(cfg)
+ e.scrollToCaret(c)
}
}
}
if (sdist > 0 && soff >= smax) || (sdist < 0 && soff <= smin) {
e.scroller.Stop()
}
- for ke, ok := queue.Next(e); ok; ke, ok = queue.Next(e) {
- e.blinkStart = cfg.Now()
+ for ke, ok := c.Queue.Next(e); ok; ke, ok = c.Queue.Next(e) {
+ e.blinkStart = c.Now()
switch ke := ke.(type) {
case key.FocusEvent:
e.focused = ke.Focus
@@ 140,11 139,11 @@ func (e *Editor) Next(cfg ui.Config, queue input.Queue) (EditorEvent, bool) {
}
}
if e.command(ke) {
- e.scrollToCaret(cfg)
+ e.scrollToCaret(c.Config)
e.scroller.Stop()
}
case key.EditEvent:
- e.scrollToCaret(cfg)
+ e.scrollToCaret(c)
e.scroller.Stop()
e.append(ke.Text)
}
@@ 165,11 164,11 @@ func (e *Editor) Focus() {
e.requestFocus = true
}
-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) {
+func (e *Editor) Layout(c *layout.Context) {
+ cs := c.Constraints
+ for _, ok := e.Next(c); ok; _, ok = e.Next(c) {
}
- twoDp := cfg.Px(ui.Dp(2))
+ twoDp := c.Px(ui.Dp(2))
e.padLeft, e.padRight = twoDp, twoDp
maxWidth := cs.Width.Max
if e.SingleLine {
@@ 197,7 196,7 @@ func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, ctx *layo
Min: image.Point{X: 0, Y: 0},
Max: image.Point{X: e.viewSize.X, Y: e.viewSize.Y},
}
- key.InputOp{Key: e, Focus: e.requestFocus}.Add(ops)
+ key.InputOp{Key: e, Focus: e.requestFocus}.Add(c.Ops)
e.requestFocus = false
e.it = lineIterator{
Lines: lines,
@@ 207,14 206,14 @@ func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, ctx *layo
Offset: off,
}
var stack ui.StackOp
- stack.Push(ops)
+ stack.Push(c.Ops)
// Apply material. Set a default color in case the material is empty.
if e.rr.len() > 0 {
- paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(ops)
- e.Material.Add(ops)
+ paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(c.Ops)
+ e.Material.Add(c.Ops)
} else {
- paint.ColorOp{Color: color.RGBA{A: 0xaa}}.Add(ops)
- e.HintMaterial.Add(ops)
+ paint.ColorOp{Color: color.RGBA{A: 0xaa}}.Add(c.Ops)
+ e.HintMaterial.Add(c.Ops)
}
for {
str, lineOff, ok := e.it.Next()
@@ 222,21 221,21 @@ func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, ctx *layo
break
}
var stack ui.StackOp
- stack.Push(ops)
- ui.TransformOp{}.Offset(lineOff).Add(ops)
- e.Face.Path(str).Add(ops)
- paint.PaintOp{Rect: toRectF(clip).Sub(lineOff)}.Add(ops)
+ stack.Push(c.Ops)
+ ui.TransformOp{}.Offset(lineOff).Add(c.Ops)
+ e.Face.Path(str).Add(c.Ops)
+ paint.PaintOp{Rect: toRectF(clip).Sub(lineOff)}.Add(c.Ops)
stack.Pop()
}
if e.focused {
- now := cfg.Now()
+ now := c.Now()
dt := now.Sub(e.blinkStart)
blinking := dt < maxBlinkDuration
const timePerBlink = time.Second / blinksPerSecond
nextBlink := now.Add(timePerBlink/2 - dt%(timePerBlink/2))
on := !blinking || dt%timePerBlink < timePerBlink/2
if on {
- carWidth := e.caretWidth(cfg)
+ carWidth := e.caretWidth(c)
carX -= carWidth / 2
carAsc, carDesc := -lines[carLine].Bounds.Min.Y, lines[carLine].Bounds.Max.Y
carRect := image.Rectangle{
@@ 249,29 248,29 @@ func (e *Editor) Layout(cfg ui.Config, queue input.Queue, ops *ui.Ops, ctx *layo
})
carRect = clip.Intersect(carRect)
if !carRect.Empty() {
- paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(ops)
- e.Material.Add(ops)
- paint.PaintOp{Rect: toRectF(carRect)}.Add(ops)
+ paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(c.Ops)
+ e.Material.Add(c.Ops)
+ paint.PaintOp{Rect: toRectF(carRect)}.Add(c.Ops)
}
}
if blinking {
redraw := ui.InvalidateOp{At: nextBlink}
- redraw.Add(ops)
+ redraw.Add(c.Ops)
}
}
stack.Pop()
baseline := e.padTop + e.dims.Baseline
- pointerPadding := cfg.Px(ui.Dp(4))
+ pointerPadding := c.Px(ui.Dp(4))
r := image.Rectangle{Max: e.viewSize}
r.Min.X -= pointerPadding
r.Min.Y -= pointerPadding
r.Max.X += pointerPadding
r.Max.X += pointerPadding
- pointer.RectAreaOp{Rect: r}.Add(ops)
- e.scroller.Add(ops)
- e.clicker.Add(ops)
- ctx.Dimensions = layout.Dimensions{Size: e.viewSize, Baseline: baseline}
+ pointer.RectAreaOp{Rect: r}.Add(c.Ops)
+ e.scroller.Add(c.Ops)
+ e.clicker.Add(c.Ops)
+ c.Dimensions = layout.Dimensions{Size: e.viewSize, Baseline: baseline}
}
// Text returns the contents of the editor.
@@ 550,8 549,8 @@ func (e *Editor) moveEnd() {
e.carXOff = l.Width + a - x
}
-func (e *Editor) scrollToCaret(cfg ui.Config) {
- carWidth := e.caretWidth(cfg)
+func (e *Editor) scrollToCaret(c ui.Config) {
+ carWidth := e.caretWidth(c)
carLine, _, x, y := e.layoutCaret()
l := e.lines[carLine]
if e.SingleLine {
M ui/text/label.go => ui/text/label.go +9 -9
@@ 92,8 92,8 @@ func (l *lineIterator) Next() (String, f32.Point, bool) {
return String{}, f32.Point{}, false
}
-func (l Label) Layout(ops *ui.Ops, ctx *layout.Context) {
- cs := ctx.Constraints
+func (l Label) Layout(c *layout.Context) {
+ cs := c.Constraints
textLayout := l.Face.Layout(l.Text, LayoutOptions{MaxWidth: cs.Width.Max})
lines := textLayout.Lines
if max := l.MaxLines; max > 0 && len(lines) > max {
@@ 119,16 119,16 @@ func (l Label) Layout(ops *ui.Ops, ctx *layout.Context) {
}
lclip := toRectF(clip).Sub(off)
var stack ui.StackOp
- stack.Push(ops)
- ui.TransformOp{}.Offset(off).Add(ops)
- l.Face.Path(str).Add(ops)
+ stack.Push(c.Ops)
+ ui.TransformOp{}.Offset(off).Add(c.Ops)
+ l.Face.Path(str).Add(c.Ops)
// Set a default color in case the material is empty.
- paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(ops)
- l.Material.Add(ops)
- paint.PaintOp{Rect: lclip}.Add(ops)
+ paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(c.Ops)
+ l.Material.Add(c.Ops)
+ paint.PaintOp{Rect: lclip}.Add(c.Ops)
stack.Pop()
}
- ctx.Dimensions = dims
+ c.Dimensions = dims
}
func toRectF(r image.Rectangle) f32.Rectangle {
M ui/widget/image.go => ui/widget/image.go +5 -5
@@ 25,7 25,7 @@ type Image struct {
Scale float32
}
-func (im Image) Layout(c ui.Config, ops *ui.Ops, ctx *layout.Context) {
+func (im Image) Layout(c *layout.Context) {
size := im.Src.Bounds()
wf, hf := float32(size.Dx()), float32(size.Dy())
var w, h int
@@ 35,7 35,7 @@ func (im Image) Layout(c ui.Config, ops *ui.Ops, ctx *layout.Context) {
} else {
w, h = int(wf*im.Scale+.5), int(hf*im.Scale+.5)
}
- cs := ctx.Constraints
+ cs := c.Constraints
d := image.Point{X: cs.Width.Constrain(w), Y: cs.Height.Constrain(h)}
aspect := float32(w) / float32(h)
dw, dh := float32(d.X), float32(d.Y)
@@ 48,7 48,7 @@ func (im Image) Layout(c ui.Config, ops *ui.Ops, ctx *layout.Context) {
dr := f32.Rectangle{
Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
}
- paint.ImageOp{Src: im.Src, Rect: im.Rect}.Add(ops)
- paint.PaintOp{Rect: dr}.Add(ops)
- ctx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y}
+ paint.ImageOp{Src: im.Src, Rect: im.Rect}.Add(c.Ops)
+ paint.PaintOp{Rect: dr}.Add(c.Ops)
+ c.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y}
}