Files
gio/cmd/gogio/testdata/red.go
T
Daniel Martí 023e022255 cmd/gogio: make e2e test output consistent
Fix a long-standing TODO: instead of each sub-test handling its own
output separately, just make each expose its output via an io.Reader.
Then, the shared driverBase code can tell if any of the lines contain
the magic "gio frame ready" string.

Reduces the amount of code a bit, but most importantly, it keeps the "is
a frame ready?" logic in a single place.

In the future, this also enables us to do more with all the e2e test app
output consistently. For example, we might want to add a -debug flag to
always log output lines as they happen.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
2020-05-10 20:32:57 +02:00

132 lines
2.9 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
// A simple app used for gogio's end-to-end tests.
package main
import (
"fmt"
"image"
"image/color"
"log"
"gioui.org/app"
"gioui.org/f32"
"gioui.org/io/pointer"
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op/paint"
)
func main() {
go func() {
w := app.NewWindow()
if err := loop(w); err != nil {
log.Fatal(err)
}
}()
app.Main()
}
type notifyFrame int
const (
notifyNone notifyFrame = iota
notifyInvalidate
notifyPrint
)
// notify keeps track of whether we want to print to stdout to notify the user
// when a frame is ready. Initially we want to notify about the first frame.
var notify = notifyInvalidate
func loop(w *app.Window) error {
topLeft := quarterWidget{
color: color.RGBA{R: 0xde, G: 0xad, B: 0xbe, A: 0xff},
}
topRight := quarterWidget{
color: color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
}
botLeft := quarterWidget{
color: color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff},
}
botRight := quarterWidget{
color: color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x80},
}
gtx := new(layout.Context)
for {
e := <-w.Events()
switch e := e.(type) {
case system.DestroyEvent:
return e.Err
case system.FrameEvent:
gtx.Reset(e.Queue, e.Config, e.Size)
layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Flexed(0.5, func() {
layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
// r1c1
layout.Flexed(0.5, func() { topLeft.Layout(gtx) }),
// r1c2
layout.Flexed(0.5, func() { topRight.Layout(gtx) }),
)
}),
layout.Flexed(0.5, func() {
layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
// r2c1
layout.Flexed(0.5, func() { botLeft.Layout(gtx) }),
// r2c2
layout.Flexed(0.5, func() { botRight.Layout(gtx) }),
)
}),
)
e.Frame(gtx.Ops)
switch notify {
case notifyInvalidate:
notify = notifyPrint
w.Invalidate()
case notifyPrint:
notify = notifyNone
fmt.Println("gio frame ready")
}
}
}
}
// quarterWidget paints a quarter of the screen with one color. When clicked, it
// turns red, going back to its normal color when clicked again.
type quarterWidget struct {
color color.RGBA
clicked bool
}
var red = color.RGBA{R: 0xff, G: 0x00, B: 0x00, A: 0xff}
func (w *quarterWidget) Layout(gtx *layout.Context) {
if w.clicked {
paint.ColorOp{Color: red}.Add(gtx.Ops)
} else {
paint.ColorOp{Color: w.color}.Add(gtx.Ops)
}
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{
X: float32(gtx.Constraints.Width.Max),
Y: float32(gtx.Constraints.Height.Max),
}}}.Add(gtx.Ops)
pointer.Rect(image.Rectangle{
Max: image.Pt(gtx.Constraints.Width.Max, gtx.Constraints.Height.Max),
}).Add(gtx.Ops)
pointer.InputOp{Key: w}.Add(gtx.Ops)
for _, e := range gtx.Events(w) {
if e, ok := e.(pointer.Event); ok && e.Type == pointer.Press {
w.clicked = !w.clicked
// notify when we're done updating the frame.
notify = notifyInvalidate
}
}
}