// +build darwin linux package main import ( "fmt" "image/color" "log" "time" "gioui.org/app" "gioui.org/f32" "gioui.org/io/system" "gioui.org/layout" "gioui.org/op" "gioui.org/op/clip" "gioui.org/op/paint" "gioui.org/unit" "gioui.org/widget/material" "gioui.org/font/gofont" ) type vector struct { x, y, z float64 } var ( labchan chan string senschan chan vector ) type ( D = layout.Dimensions C = layout.Context ) func main() { labchan = make(chan string) senschan = make(chan vector) log.Print("Staring event loop") go eventloop() app.Main() log.Print("App closed") } func diffInsets(x, y system.Insets) bool { return x.Top != y.Top || x.Bottom != y.Bottom || x.Left != y.Left || x.Right != y.Right } func eventloop() { w := app.NewWindow( app.Size(unit.Dp(400), unit.Dp(400)), app.Title("Hello")) th := material.NewTheme(gofont.Collection()) var ops op.Ops sysinset := &layout.Inset{} margin := layout.UniformInset(unit.Dp(10)) labels := []material.LabelStyle{} list := &layout.List{Axis: layout.Vertical} resetSysinset := func(x system.Insets) { sysinset.Top = x.Top sysinset.Bottom = x.Bottom sysinset.Left = x.Left sysinset.Right = x.Right } go func() { labchan <- "Starting" }() var accel vector accel.y = 1 lablist := func(gtx C) D { return list.Layout(gtx, len(labels), func(gtx C, i int) D { return labels[i].Layout(gtx) }) } vecview := func(gtx C) D { f := layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceEvenly} return f.Layout(gtx, layout.Rigid(func(gtx C) D { return material.Body1(th, fmt.Sprintf("x = %f", accel.x)).Layout(gtx) }), layout.Rigid(func(gtx C) D { return material.Body1(th, fmt.Sprintf("y = %f", accel.y)).Layout(gtx) }), layout.Rigid(func(gtx C) D { return material.Body1(th, fmt.Sprintf("z = %f", accel.z)).Layout(gtx) }), ) } var cx, cy, cvx, cvy, cs float32 // circle position cx = 200 cy = 200 cs = 50 // circle size (radius) circle := func(gtx C, width, height float32) D { // clip circle position and bounce off of the edges if (cx < cs) { cx = cs; cvx = (-0.5) * cvx } if (cy < cs) { cy = cs; cvy = (-0.5) * cvy } if (cx > width - cs) { cx = width - cs; cvx = (-0.5) * cvx } if (cy > height - cs) { cy = height - cs; cvy = (-0.5) * cvy } blue := color.RGBA{0x3f, 0x51, 0xb5, 0x80} r1 := f32.Rectangle{f32.Point{cx - cs, cy - cs}, f32.Point{cx + cs, cy + cs}} clip.Rect{ Rect: r1, NE: cs, NW: cs, SE: cs, SW: cs}.Op(gtx.Ops).Add(gtx.Ops) paint.ColorOp{Color: blue}.Add(gtx.Ops) paint.PaintOp{Rect: r1}.Add(gtx.Ops) var ret D ret.Size.X = int(cs * 2) ret.Size.Y = int(cs * 2) return ret } ticker := time.NewTicker(time.Second / 60) var t, told int64 t = time.Now().UnixNano() for { select { case <- ticker.C: told = t t = time.Now().UnixNano() elapsed := float32((t - told) / 1000000) cvx = cvx - float32(accel.x/1000) * elapsed cvy = cvy + float32(accel.y/1000) * elapsed cx = cx + cvx * elapsed cy = cy + cvy * elapsed w.Invalidate() case x := <-labchan: labels = append(labels, material.Body1(th, x)) case x := <-senschan: accel = x case e := <-w.Events(): switch e := e.(type) { case system.DestroyEvent: return case system.FrameEvent: gtx := layout.NewContext(&ops, e) resetSysinset(e.Insets) sysinset.Layout(gtx, func(gtx C) D { ret := margin.Layout(gtx, func(gtx C) D { f1 := layout.Flex{Axis: layout.Vertical} ret := f1.Layout(gtx, layout.Rigid(vecview), layout.Flexed(1, lablist), ) circle(gtx, float32(ret.Size.X), float32(ret.Size.Y)) return ret }) return ret }) e.Frame(gtx.Ops) } } } }