Add form example, add /examples directory.
This commit is contained in:
parent
dfc3f618c0
commit
f134a1f21e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,5 +2,6 @@ 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*
|
memprofile*
|
||||||
|
|
227
cmd/form/main.go
Normal file
227
cmd/form/main.go
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
36
examples/ctx.go
Normal file
36
examples/ctx.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user