1 // SPDX-License-Identifier: Unlicense OR MIT
2 3 package layout
4 5 import (
6 "time"
7 8 "github.com/p9c/p9/pkg/gel/gio/f32"
9 "github.com/p9c/p9/pkg/gel/gio/io/event"
10 "github.com/p9c/p9/pkg/gel/gio/io/system"
11 "github.com/p9c/p9/pkg/gel/gio/op"
12 "github.com/p9c/p9/pkg/gel/gio/unit"
13 )
14 15 // Context carries the state needed by almost all layouts and widgets.
16 // A zero value Context never returns events, map units to pixels
17 // with a scale of 1.0, and returns the zero time from Now.
18 type Context struct {
19 // Constraints track the constraints for the active widget or
20 // layout.
21 Constraints Constraints
22 23 Metric unit.Metric
24 // By convention, a nil Queue is a signal to widgets to draw themselves
25 // in a disabled state.
26 Queue event.Queue
27 // Now is the animation time.
28 Now time.Time
29 30 *op.Ops
31 }
32 33 // NewContext is a shorthand for
34 //
35 // Context{
36 // Ops: ops,
37 // Now: e.Now,
38 // Queue: e.Queue,
39 // Config: e.Config,
40 // Constraints: Exact(e.Size),
41 // }
42 //
43 // NewContext calls ops.Reset and adjusts ops for e.Insets.
44 func NewContext(ops *op.Ops, e system.FrameEvent) Context {
45 ops.Reset()
46 47 size := e.Size
48 49 if e.Insets != (system.Insets{}) {
50 left := e.Metric.Px(e.Insets.Left)
51 top := e.Metric.Px(e.Insets.Top)
52 op.Offset(f32.Point{
53 X: float32(left),
54 Y: float32(top),
55 }).Add(ops)
56 57 size.X -= left + e.Metric.Px(e.Insets.Right)
58 size.Y -= top + e.Metric.Px(e.Insets.Bottom)
59 }
60 61 return Context{
62 Ops: ops,
63 Now: e.Now,
64 Queue: e.Queue,
65 Metric: e.Metric,
66 Constraints: Exact(size),
67 }
68 }
69 70 // Px maps the value to pixels.
71 func (c Context) Px(v unit.Value) int {
72 return c.Metric.Px(v)
73 }
74 75 // Events returns the events available for the key. If no
76 // queue is configured, Events returns nil.
77 func (c Context) Events(k event.Tag) []event.Event {
78 if c.Queue == nil {
79 return nil
80 }
81 return c.Queue.Events(k)
82 }
83 84 // Disabled returns a copy of this context with a nil Queue,
85 // blocking events to widgets using it.
86 //
87 // By convention, a nil Queue is a signal to widgets to draw themselves
88 // in a disabled state.
89 func (c Context) Disabled() Context {
90 c.Queue = nil
91 return c
92 }
93