buttonlayout.go raw

   1  package gel
   2  
   3  import (
   4  	"image/color"
   5  	
   6  	"github.com/p9c/gio/f32"
   7  	l "github.com/p9c/gio/layout"
   8  	"github.com/p9c/gio/op/clip"
   9  	"github.com/p9c/gio/unit"
  10  	
  11  	"github.com/p9c/gel/f32color"
  12  )
  13  
  14  type ButtonLayout struct {
  15  	*Window
  16  	background   color.NRGBA
  17  	cornerRadius unit.Value
  18  	button       *Clickable
  19  	w            l.Widget
  20  	corners      int
  21  }
  22  
  23  // ButtonLayout creates a button with a background and another widget over top
  24  func (w *Window) ButtonLayout(button *Clickable) *ButtonLayout {
  25  	return &ButtonLayout{
  26  		Window:       w,
  27  		button:       button,
  28  		background:   w.Colors.GetNRGBAFromName("ButtonBg"),
  29  		cornerRadius: w.TextSize.Scale(0.25),
  30  	}
  31  }
  32  
  33  // Corners sets which corners have the radius of rounding
  34  func (b *ButtonLayout) Corners(corners int) *ButtonLayout {
  35  	b.corners = corners
  36  	return b
  37  }
  38  
  39  // Background sets the background color of the button
  40  func (b *ButtonLayout) Background(color string) *ButtonLayout {
  41  	b.background = b.Theme.Colors.GetNRGBAFromName(color)
  42  	return b
  43  }
  44  
  45  // CornerRadius sets the radius of the corners of the button
  46  func (b *ButtonLayout) CornerRadius(radius float32) *ButtonLayout {
  47  	b.cornerRadius = b.Theme.TextSize.Scale(radius)
  48  	return b
  49  }
  50  
  51  // Embed a widget in the button
  52  func (b *ButtonLayout) Embed(w l.Widget) *ButtonLayout {
  53  	b.w = w
  54  	return b
  55  }
  56  
  57  func (b *ButtonLayout) SetClick(fn func()) *ButtonLayout {
  58  	b.button.SetClick(fn)
  59  	return b
  60  }
  61  
  62  func (b *ButtonLayout) SetCancel(fn func()) *ButtonLayout {
  63  	b.button.SetCancel(fn)
  64  	return b
  65  }
  66  
  67  func (b *ButtonLayout) SetPress(fn func()) *ButtonLayout {
  68  	b.button.SetPress(fn)
  69  	return b
  70  }
  71  
  72  // Fn is the function that draws the button and its child widget
  73  func (b *ButtonLayout) Fn(gtx l.Context) l.Dimensions {
  74  	min := gtx.Constraints.Min
  75  	return b.Stack().Alignment(l.Center).
  76  		Expanded(
  77  			func(gtx l.Context) l.Dimensions {
  78  				rr := float32(gtx.Px(b.cornerRadius))
  79  				clip.RRect{
  80  					Rect: f32.Rectangle{Max: f32.Point{
  81  						X: float32(gtx.Constraints.Min.X),
  82  						Y: float32(gtx.Constraints.Min.Y),
  83  					}},
  84  					NW: ifDir(rr, b.corners&NW),
  85  					NE: ifDir(rr, b.corners&NE),
  86  					SW: ifDir(rr, b.corners&SW),
  87  					SE: ifDir(rr, b.corners&SE),
  88  				}.Add(gtx.Ops)
  89  				background := b.background
  90  				if gtx.Queue == nil {
  91  					background = f32color.MulAlpha(b.background, 150)
  92  				}
  93  				dims := Fill(gtx, background)
  94  				for _, c := range b.button.History() {
  95  					drawInk(gtx, c)
  96  				}
  97  				return dims
  98  			}).
  99  		Stacked(
 100  			func(gtx l.Context) l.Dimensions {
 101  				gtx.Constraints.Min = min
 102  				return l.Center.Layout(gtx, b.w)
 103  			}).
 104  		Expanded(b.button.Fn).
 105  		Fn(gtx)
 106  }
 107