context.go raw

   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