enum.go raw

   1  package widget
   2  
   3  import (
   4  	"image"
   5  
   6  	"github.com/p9c/p9/pkg/gel/gio/gesture"
   7  	"github.com/p9c/p9/pkg/gel/gio/io/pointer"
   8  	"github.com/p9c/p9/pkg/gel/gio/layout"
   9  	"github.com/p9c/p9/pkg/gel/gio/op"
  10  )
  11  
  12  type Enum struct {
  13  	Value    string
  14  	hovered  string
  15  	hovering bool
  16  
  17  	changed bool
  18  
  19  	clicks []gesture.Click
  20  	values []string
  21  }
  22  
  23  func index(vs []string, t string) int {
  24  	for i, v := range vs {
  25  		if v == t {
  26  			return i
  27  		}
  28  	}
  29  	return -1
  30  }
  31  
  32  // Changed reports whether Value has changed by user interaction since the last
  33  // call to Changed.
  34  func (e *Enum) Changed() bool {
  35  	changed := e.changed
  36  	e.changed = false
  37  	return changed
  38  }
  39  
  40  // Hovered returns the key that is highlighted, or false if none are.
  41  func (e *Enum) Hovered() (string, bool) {
  42  	return e.hovered, e.hovering
  43  }
  44  
  45  // Layout adds the event handler for key.
  46  func (e *Enum) Layout(gtx layout.Context, key string) layout.Dimensions {
  47  	defer op.Save(gtx.Ops).Load()
  48  	pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops)
  49  
  50  	if index(e.values, key) == -1 {
  51  		e.values = append(e.values, key)
  52  		e.clicks = append(e.clicks, gesture.Click{})
  53  		e.clicks[len(e.clicks)-1].Add(gtx.Ops)
  54  	} else {
  55  		idx := index(e.values, key)
  56  		clk := &e.clicks[idx]
  57  		for _, ev := range clk.Events(gtx) {
  58  			switch ev.Type {
  59  			case gesture.TypeClick:
  60  				if new := e.values[idx]; new != e.Value {
  61  					e.Value = new
  62  					e.changed = true
  63  				}
  64  			}
  65  		}
  66  		if e.hovering && e.hovered == key {
  67  			e.hovering = false
  68  		}
  69  		if clk.Hovered() {
  70  			e.hovered = key
  71  			e.hovering = true
  72  		}
  73  		clk.Add(gtx.Ops)
  74  	}
  75  
  76  	return layout.Dimensions{Size: gtx.Constraints.Min}
  77  }
  78