github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/cmd/gogio/testdata/testdata.go_ (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  // A simple app used for gogio's end-to-end tests.
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"image"
     9  	"image/color"
    10  	"log"
    11  
    12  	"github.com/cybriq/giocore/app"
    13  	"github.com/cybriq/giocore/io/pointer"
    14  	"github.com/cybriq/giocore/io/system"
    15  	"github.com/cybriq/giocore/op"
    16  	"github.com/cybriq/giocore/op/clip"
    17  	"github.com/cybriq/giocore/op/paint"
    18  )
    19  
    20  func main() {
    21  	go func() {
    22  		w := app.NewWindow()
    23  		if err := loop(w); err != nil {
    24  			log.Fatal(err)
    25  		}
    26  	}()
    27  	app.Main()
    28  }
    29  
    30  type notifyFrame int
    31  
    32  const (
    33  	notifyNone notifyFrame = iota
    34  	notifyInvalidate
    35  	notifyPrint
    36  )
    37  
    38  // notify keeps track of whether we want to print to stdout to notify the user
    39  // when a frame is ready. Initially we want to notify about the first frame.
    40  var notify = notifyInvalidate
    41  
    42  type (
    43  	C = layout.Context
    44  	D = layout.Dimensions
    45  )
    46  
    47  func loop(w *app.Window) error {
    48  	topLeft := quarterWidget{
    49  		color: color.NRGBA{R: 0xde, G: 0xad, B: 0xbe, A: 0xff},
    50  	}
    51  	topRight := quarterWidget{
    52  		color: color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
    53  	}
    54  	botLeft := quarterWidget{
    55  		color: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff},
    56  	}
    57  	botRight := quarterWidget{
    58  		color: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x80},
    59  	}
    60  
    61  	var ops op.Ops
    62  	for {
    63  		e := <-w.Events()
    64  		switch e := e.(type) {
    65  		case system.DestroyEvent:
    66  			return e.Err
    67  		case system.FrameEvent:
    68  			gtx := layout.NewContext(&ops, e)
    69  			// Clear background to white, even on embedded platforms such as webassembly.
    70  			paint.Fill(gtx.Ops, color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
    71  			layout.Flex{Axis: layout.Vertical}.Layout(gtx,
    72  				layout.Flexed(1, func(gtx C) D {
    73  					return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
    74  						// r1c1
    75  						layout.Flexed(1, func(gtx C) D { return topLeft.Layout(gtx) }),
    76  						// r1c2
    77  						layout.Flexed(1, func(gtx C) D { return topRight.Layout(gtx) }),
    78  					)
    79  				}),
    80  				layout.Flexed(1, func(gtx C) D {
    81  					return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
    82  						// r2c1
    83  						layout.Flexed(1, func(gtx C) D { return botLeft.Layout(gtx) }),
    84  						// r2c2
    85  						layout.Flexed(1, func(gtx C) D { return botRight.Layout(gtx) }),
    86  					)
    87  				}),
    88  			)
    89  
    90  			e.Frame(gtx.Ops)
    91  
    92  			switch notify {
    93  			case notifyInvalidate:
    94  				notify = notifyPrint
    95  				w.Invalidate()
    96  			case notifyPrint:
    97  				notify = notifyNone
    98  				fmt.Println("gio frame ready")
    99  			}
   100  		}
   101  	}
   102  }
   103  
   104  // quarterWidget paints a quarter of the screen with one color. When clicked, it
   105  // turns red, going back to its normal color when clicked again.
   106  type quarterWidget struct {
   107  	color color.NRGBA
   108  
   109  	clicked bool
   110  }
   111  
   112  var red = color.NRGBA{R: 0xff, G: 0x00, B: 0x00, A: 0xff}
   113  
   114  func (w *quarterWidget) Layout(gtx layout.Context) layout.Dimensions {
   115  	var color color.NRGBA
   116  	if w.clicked {
   117  		color = red
   118  	} else {
   119  		color = w.color
   120  	}
   121  
   122  	r := image.Rectangle{Max: gtx.Constraints.Max}
   123  	paint.FillShape(gtx.Ops, color, clip.Rect(r).Op())
   124  
   125  	pointer.Rect(image.Rectangle{
   126  		Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y),
   127  	}).Add(gtx.Ops)
   128  	pointer.InputOp{
   129  		Tag:   w,
   130  		Types: pointer.Press,
   131  	}.Add(gtx.Ops)
   132  
   133  	for _, e := range gtx.Events(w) {
   134  		if e, ok := e.(pointer.Event); ok && e.Type == pointer.Press {
   135  			w.clicked = !w.clicked
   136  			// notify when we're done updating the frame.
   137  			notify = notifyInvalidate
   138  		}
   139  	}
   140  	return layout.Dimensions{Size: gtx.Constraints.Max}
   141  }