Compare commits
No commits in common. "f134a1f21e862813ce08da69ad35fe640b3d82be" and "cf56e8c47eeaff437870eea1f93f27607ff5a11d" have entirely different histories.
f134a1f21e
...
cf56e8c47e
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,6 +2,4 @@ cmd/hello/hello
|
||||||
cmd/cal/cal
|
cmd/cal/cal
|
||||||
cmd/scroll/scroll
|
cmd/scroll/scroll
|
||||||
cmd/grid/grid
|
cmd/grid/grid
|
||||||
cmd/form/form
|
|
||||||
*.apk
|
*.apk
|
||||||
memprofile*
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
sel int32
|
||||||
face text.Face
|
face text.Face
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
227
cmd/form/main.go
227
cmd/form/main.go
|
@ -1,227 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.wow.st/gmp/giowrap"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
//"image"
|
|
||||||
"image/color"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"runtime/pprof"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"gioui.org/ui"
|
|
||||||
"gioui.org/ui/app"
|
|
||||||
"gioui.org/ui/text"
|
|
||||||
|
|
||||||
"golang.org/x/image/font/gofont/goregular"
|
|
||||||
"golang.org/x/image/font/sfnt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
FPS int = 100
|
|
||||||
frames int64
|
|
||||||
frametime int64 // nanoseconds
|
|
||||||
maxframetime int64
|
|
||||||
mux sync.Mutex
|
|
||||||
Profile bool = true
|
|
||||||
RecordMallocs bool = false
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewButton(face text.Face, t string, c color.RGBA) giowrap.Clickable {
|
|
||||||
lbl := giowrap.NewLabel(t, giowrap.Face(face), giowrap.Align(text.Middle))
|
|
||||||
bg := giowrap.NewBackground(giowrap.Color(c), giowrap.Radius(ui.Dp(4)))
|
|
||||||
ins := giowrap.NewInset(giowrap.Size(ui.Dp(4)))
|
|
||||||
return giowrap.AsClickable(ins(bg(lbl)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
go func() {
|
|
||||||
ms := &runtime.MemStats{}
|
|
||||||
var a1 uint64
|
|
||||||
for {
|
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
mux.Lock()
|
|
||||||
if frames == 0 {
|
|
||||||
mux.Unlock()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
runtime.ReadMemStats(ms)
|
|
||||||
a1 = ms.Alloc
|
|
||||||
runtime.GC()
|
|
||||||
runtime.ReadMemStats(ms)
|
|
||||||
log.Printf("Alloc: %d - %d = %d (%d per frame)", a1, ms.Alloc, a1-ms.Alloc, (a1-ms.Alloc)/(3*uint64(FPS)))
|
|
||||||
log.Printf("Frametime: %d max Frametime: %d us\n", frametime/(frames*1000), maxframetime/1000)
|
|
||||||
frames = 0
|
|
||||||
frametime = 0
|
|
||||||
maxframetime = 0
|
|
||||||
mux.Unlock()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go main1()
|
|
||||||
app.Main()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main1() {
|
|
||||||
w := app.NewWindow()
|
|
||||||
regular, err := sfnt.Parse(goregular.TTF)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Cannot parse font.")
|
|
||||||
}
|
|
||||||
ctx := giowrap.NewContext(w)
|
|
||||||
t := time.NewTicker(time.Second / time.Duration(FPS))
|
|
||||||
|
|
||||||
graybg := giowrap.NewBackground(
|
|
||||||
giowrap.Color(color.RGBA{A: 0xff, R: 0xd0, G: 0xd0, B: 0xd0}),
|
|
||||||
giowrap.Radius(ui.Dp(4)))
|
|
||||||
whitebg := giowrap.NewBackground(
|
|
||||||
giowrap.Color(color.RGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff}),
|
|
||||||
giowrap.Radius(ui.Dp(4)))
|
|
||||||
margin := giowrap.NewInset(giowrap.Size(ui.Dp(10)))
|
|
||||||
buffer := giowrap.NewInset(giowrap.Bottom(ui.Dp(10)))
|
|
||||||
f1 := giowrap.NewFlex(giowrap.Vertical)
|
|
||||||
row := giowrap.NewFlex(giowrap.Horizontal)
|
|
||||||
|
|
||||||
more := NewButton(ctx.Faces.For(regular, ui.Sp(24)),
|
|
||||||
"more", color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6})
|
|
||||||
submit := NewButton(ctx.Faces.For(regular, ui.Sp(24)),
|
|
||||||
"submit", color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6})
|
|
||||||
back := NewButton(ctx.Faces.For(regular, ui.Sp(24)),
|
|
||||||
"back", color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6})
|
|
||||||
|
|
||||||
numfields := 5
|
|
||||||
eds := make([]*giowrap.Editor,0)
|
|
||||||
btns := make([]giowrap.Clickable,0)
|
|
||||||
entryrows := make([]giowrap.Widget,0)
|
|
||||||
submitrows := make([]giowrap.Widget,0)
|
|
||||||
|
|
||||||
var entryPage giowrap.Widget
|
|
||||||
var submitPage giowrap.Widget
|
|
||||||
|
|
||||||
newRow := func(i int) {
|
|
||||||
eds = append(eds, giowrap.NewEditor(fmt.Sprintf("text %d",i), giowrap.Face(ctx.Faces.For(regular, ui.Sp(24)))))
|
|
||||||
btns = append(btns, NewButton(ctx.Faces.For(regular, ui.Sp(18)), "X",
|
|
||||||
color.RGBA{A: 0xff, R: 0x80, G: 0x80, B: 0x80}))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < numfields; i++ {
|
|
||||||
newRow(i)
|
|
||||||
}
|
|
||||||
updatePages := func() {
|
|
||||||
entryrows = entryrows[0:0]
|
|
||||||
entryrows = append(entryrows, buffer(row(more, submit)))
|
|
||||||
for i := 0; i < len(btns); i++ {
|
|
||||||
entryrows = append(entryrows, row(btns[i], giowrap.FillWidth(whitebg(eds[i]))))
|
|
||||||
}
|
|
||||||
entryPage = graybg(margin(giowrap.VScroll(f1)(entryrows...)))
|
|
||||||
|
|
||||||
submitrows = submitrows[0:0]
|
|
||||||
submitrows = append(submitrows, buffer(row(back)))
|
|
||||||
for i := 0; i < len(btns); i++ {
|
|
||||||
submitrows = append(submitrows, giowrap.NewLabel(eds[i].Text(), giowrap.Face(ctx.Faces.For(regular, ui.Sp(24)))))
|
|
||||||
}
|
|
||||||
submitPage = graybg(margin(giowrap.VScroll(f1)(submitrows...)))
|
|
||||||
}
|
|
||||||
updatePages()
|
|
||||||
|
|
||||||
page := &entryPage
|
|
||||||
|
|
||||||
profiled := false
|
|
||||||
startTime := time.Now()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
w.Invalidate()
|
|
||||||
case e := <-w.Events():
|
|
||||||
mux.Lock()
|
|
||||||
stime := time.Now()
|
|
||||||
switch e := e.(type) {
|
|
||||||
case app.DestroyEvent:
|
|
||||||
return
|
|
||||||
case app.UpdateEvent:
|
|
||||||
profileNow := false
|
|
||||||
var ms runtime.MemStats
|
|
||||||
if Profile && time.Since(startTime) > time.Second*2 {
|
|
||||||
startTime = time.Now()
|
|
||||||
profileNow = true
|
|
||||||
}
|
|
||||||
if profileNow {
|
|
||||||
if !profiled {
|
|
||||||
prof(0)
|
|
||||||
}
|
|
||||||
runtime.ReadMemStats(&ms)
|
|
||||||
if RecordMallocs {
|
|
||||||
giowrap.RecordMallocs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx = ctx.Reset(&e)
|
|
||||||
giowrap.Mallocs("pre-layout")
|
|
||||||
ctx = (*page).Layout(ctx)
|
|
||||||
giowrap.Mallocs("post-layout")
|
|
||||||
ctx.Update()
|
|
||||||
for i, w := range btns {
|
|
||||||
if w.Clicked(ctx) {
|
|
||||||
log.Printf("%d clicked\n",i)
|
|
||||||
btns = append(btns[:i], btns[i+1:]...)
|
|
||||||
eds = append(eds[:i], eds[i+1:]...)
|
|
||||||
entryrows = append(entryrows[:i], entryrows[i+1:]...)
|
|
||||||
numfields--
|
|
||||||
updatePages()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if more.Clicked(ctx) {
|
|
||||||
log.Print("More")
|
|
||||||
newRow(len(btns))
|
|
||||||
updatePages()
|
|
||||||
}
|
|
||||||
if submit.Clicked(ctx) {
|
|
||||||
log.Print("Submit")
|
|
||||||
updatePages()
|
|
||||||
page = &submitPage
|
|
||||||
}
|
|
||||||
if back.Clicked(ctx) {
|
|
||||||
page = &entryPage
|
|
||||||
}
|
|
||||||
if profileNow {
|
|
||||||
for _, i := range giowrap.AllMallocs {
|
|
||||||
fmt.Printf("mallocs: %d (%s)\n", i.Value, i.Text)
|
|
||||||
}
|
|
||||||
giowrap.AllMallocs = nil
|
|
||||||
mallocs := ms.Mallocs
|
|
||||||
runtime.ReadMemStats(&ms)
|
|
||||||
mallocs = ms.Mallocs - mallocs
|
|
||||||
log.Printf("Mallocs = %d\n", mallocs)
|
|
||||||
if !profiled {
|
|
||||||
prof(1)
|
|
||||||
profiled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dur := time.Since(stime).Nanoseconds()
|
|
||||||
frames = frames + 1
|
|
||||||
frametime = frametime + dur
|
|
||||||
if dur > maxframetime {
|
|
||||||
maxframetime = dur
|
|
||||||
}
|
|
||||||
mux.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func prof(x int) {
|
|
||||||
names := []string{"memprofile-1.pprof", "memprofile-2.pprof"}
|
|
||||||
f1, err := os.Create(names[x])
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("could not create memory profile: ", err)
|
|
||||||
}
|
|
||||||
if err := pprof.WriteHeapProfile(f1); err != nil {
|
|
||||||
log.Fatal("could not write memory profile: ", err)
|
|
||||||
}
|
|
||||||
f1.Close()
|
|
||||||
log.Print("Memory profile written")
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
ctx.Reset(&e) // ctx keeps a pointer to e.Config, so we can do...
|
|
||||||
ctx.RigidConstraints()
|
|
||||||
{
|
|
||||||
f1 := layout.Flex{Axis: layout.Vertical} // maybe pass ctx in here?
|
|
||||||
ins := layout.UniformInset(ui.Dp(10))
|
|
||||||
ins.Begin(ctx) // containers like Insets and Flex keep a pointer to ctx
|
|
||||||
f1.Init(ctx)
|
|
||||||
f1.Rigid()
|
|
||||||
editor1.Layout(ctx)
|
|
||||||
f1.End()
|
|
||||||
{
|
|
||||||
f1.Flexible(0.33)
|
|
||||||
ins := layout.UniformInset(ui.Dp(10))
|
|
||||||
ins.Begin(ctx)
|
|
||||||
editor2.Layout(ctx)
|
|
||||||
ins.End()
|
|
||||||
}
|
|
||||||
f1.End()
|
|
||||||
{
|
|
||||||
f1.Flexible(0.67)
|
|
||||||
f2 := layout.Flex{Axis: layout.Horizontal}
|
|
||||||
f2.Init(ctx)
|
|
||||||
f2.Rigid()
|
|
||||||
button1.Layout(ctx)
|
|
||||||
c1 := f2.End()
|
|
||||||
f2.Flexible(0.5)
|
|
||||||
button2.Layout(ctx)
|
|
||||||
c2 := f2.End()
|
|
||||||
f2.Layout(c1, c2)
|
|
||||||
}
|
|
||||||
c3 := f1.End()
|
|
||||||
f1.Layout(c1, c2, c3)
|
|
||||||
ins.End()
|
|
||||||
}
|
|
||||||
}
|
|
28
main.go
28
main.go
|
@ -204,9 +204,8 @@ type List = WidgetCombinator
|
||||||
type AxisOpt struct{ axis layout.Axis }
|
type AxisOpt struct{ axis layout.Axis }
|
||||||
|
|
||||||
func Axis(x layout.Axis) AxisOpt { return AxisOpt{x} }
|
func Axis(x layout.Axis) AxisOpt { return AxisOpt{x} }
|
||||||
|
var Horizontal = AxisOpt{ layout.Horizontal }
|
||||||
var Horizontal = AxisOpt{layout.Horizontal}
|
var Vertical = AxisOpt{ layout.Vertical }
|
||||||
var Vertical = AxisOpt{layout.Vertical}
|
|
||||||
|
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
AxisOpt
|
AxisOpt
|
||||||
|
@ -511,29 +510,6 @@ func Rrect(ops *ui.Ops, width, height, se, sw, nw, ne float32) {
|
||||||
Mallocs("Rrect() end")
|
Mallocs("Rrect() end")
|
||||||
}
|
}
|
||||||
|
|
||||||
type fillWidget struct {
|
|
||||||
axis layout.Axis
|
|
||||||
}
|
|
||||||
|
|
||||||
func FillWidth(ws ...Widget) Widget {
|
|
||||||
return Enclose(fillWidget{layout.Horizontal}, ws...)
|
|
||||||
}
|
|
||||||
func FillHeight(ws ...Widget) Widget {
|
|
||||||
return Enclose(fillWidget{layout.Vertical}, ws...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fw fillWidget) Begin(ctx *Context) {
|
|
||||||
switch fw.axis {
|
|
||||||
case layout.Horizontal:
|
|
||||||
ctx.cs.Width.Min = ctx.cs.Width.Max
|
|
||||||
case layout.Vertical:
|
|
||||||
ctx.cs.Height.Min = ctx.cs.Height.Max
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fw fillWidget) End(*Context) {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Clickable interface {
|
type Clickable interface {
|
||||||
Widget
|
Widget
|
||||||
Clicked(*Context) bool
|
Clicked(*Context) bool
|
||||||
|
|
Loading…
Reference in New Issue
Block a user