mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
layout: change Widget to take explicit Context and return explicit Dimensions
Change the definition of Widget from the implicit
type Widget func()
to the explicit functional
type Widget func(gtx layout.Context) layout.Dimensions
The advantages are numerous:
- Clearer connection between the incoming context and the output dimensions.
- Returning the Dimensions are impossible to omit.
- Contexts passed by value, so its fields can be exported
and freely mutated by the program.
The only disadvantage is the longer function literals and the many "returns".
What tipped the scales in favour of the explicit Widget variant is that type
aliases can dramatically shorten the literals:
type (
C = layout.Context
D = layout.Dimensions
)
widget := func(gtx C) D {
...
}
Note that the aliases are not part of the Gio API and it is up to each user
whether they want to use them.
Finally the Go proposal for lightweight function literals,
https://github.com/golang/go/issues/21498, may remove the disadvantage
completely in future.
Context becomes a plain struct with only public fields, and its Reset is
replaced by a NewContext convenience constructor.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+28
-37
@@ -20,63 +20,54 @@ type Context struct {
|
||||
// Constraints track the constraints for the active widget or
|
||||
// layout.
|
||||
Constraints Constraints
|
||||
// Dimensions track the result of the most recent layout
|
||||
// operation.
|
||||
Dimensions Dimensions
|
||||
|
||||
cfg system.Config
|
||||
queue event.Queue
|
||||
Config system.Config
|
||||
Queue event.Queue
|
||||
*op.Ops
|
||||
}
|
||||
|
||||
// layout a widget with a set of constraints and return its
|
||||
// dimensions. The widget dimensions are constrained and the previous
|
||||
// constraints are restored after layout.
|
||||
func ctxLayout(gtx *Context, cs Constraints, w Widget) Dimensions {
|
||||
saved := gtx.Constraints
|
||||
gtx.Constraints = cs
|
||||
gtx.Dimensions = Dimensions{}
|
||||
w()
|
||||
gtx.Dimensions.Size = cs.Constrain(gtx.Dimensions.Size)
|
||||
gtx.Constraints = saved
|
||||
return gtx.Dimensions
|
||||
}
|
||||
|
||||
// Reset the context. The constraints' minimum and maximum values are
|
||||
// set to the size.
|
||||
func (c *Context) Reset(q event.Queue, cfg system.Config, size image.Point) {
|
||||
c.Constraints = Constraints{Min: size, Max: size}
|
||||
c.Dimensions = Dimensions{}
|
||||
c.cfg = cfg
|
||||
c.queue = q
|
||||
if c.Ops == nil {
|
||||
c.Ops = new(op.Ops)
|
||||
// NewContext is a shorthand for
|
||||
//
|
||||
// Context{
|
||||
// Ops: ops,
|
||||
// Queue: q,
|
||||
// Config: cfg,
|
||||
// Constraints: Exact(size),
|
||||
// }
|
||||
//
|
||||
// NewContext calls ops.Reset.
|
||||
func NewContext(ops *op.Ops, q event.Queue, cfg system.Config, size image.Point) Context {
|
||||
ops.Reset()
|
||||
return Context{
|
||||
Ops: ops,
|
||||
Queue: q,
|
||||
Config: cfg,
|
||||
Constraints: Exact(size),
|
||||
}
|
||||
c.Ops.Reset()
|
||||
}
|
||||
|
||||
// Now returns the configuration time or the zero time.
|
||||
func (c *Context) Now() time.Time {
|
||||
if c.cfg == nil {
|
||||
func (c Context) Now() time.Time {
|
||||
if c.Config == nil {
|
||||
return time.Time{}
|
||||
}
|
||||
return c.cfg.Now()
|
||||
return c.Config.Now()
|
||||
}
|
||||
|
||||
// Px maps the value to pixels. If no configuration is set,
|
||||
// Px returns the rounded value of v.
|
||||
func (c *Context) Px(v unit.Value) int {
|
||||
if c.cfg == nil {
|
||||
func (c Context) Px(v unit.Value) int {
|
||||
if c.Config == nil {
|
||||
return int(math.Round(float64(v.V)))
|
||||
}
|
||||
return c.cfg.Px(v)
|
||||
return c.Config.Px(v)
|
||||
}
|
||||
|
||||
// Events returns the events available for the key. If no
|
||||
// queue is configured, Events returns nil.
|
||||
func (c *Context) Events(k event.Tag) []event.Event {
|
||||
if c.queue == nil {
|
||||
func (c Context) Events(k event.Tag) []event.Event {
|
||||
if c.Queue == nil {
|
||||
return nil
|
||||
}
|
||||
return c.queue.Events(k)
|
||||
return c.Queue.Events(k)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user