175 lines
3.7 KiB
Go
175 lines
3.7 KiB
Go
// +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)
|
|
}
|
|
}
|
|
}
|
|
}
|