package main import ( "log" "time" "gioui.org/ui" "gioui.org/ui/app" "gioui.org/ui/input" "gioui.org/ui/layout" "gioui.org/ui/measure" "gioui.org/ui/text" //"gioui.org/ui/input" "golang.org/x/image/font/gofont/goregular" "golang.org/x/image/font/sfnt" ) type Context struct { c *app.Config q input.Queue ops *ui.Ops cs layout.Constraints dims layout.Dimens faces measure.Faces } func NewContext() *Context { return &Context{ops: new(ui.Ops)} } func (ctx *Context) Reset(w *app.Window, e app.DrawEvent) { ctx.c = &e.Config ctx.q = w.Queue() ctx.ops.Reset() ctx.cs = layout.RigidConstraints(e.Size) ctx.faces.Reset(ctx.c) } func (fw fWidget) Layout(c ui.Config, q input.Queue, ops *ui.Ops, cs layout.Constraints) layout.Dimens { return fw.l(c, q, ops, cs) } type Widget interface { Layout(ui.Config, input.Queue, *ui.Ops, layout.Constraints) layout.Dimens } type fWidget struct { l Layout } type WidgetCombinator func(...Widget) Widget type Layout func(ui.Config, input.Queue, *ui.Ops, layout.Constraints) layout.Dimens func (ctx *Context) Do(ls ...Layout) { for _, l := range ls { ctx.dims = l(ctx.c, ctx.q, ctx.ops, ctx.cs) } } func main() { go func() { w := app.NewWindow(nil) regular, err := sfnt.Parse(goregular.TTF) if err != nil { log.Fatal("Cannot parse font.") } ctx := NewContext() t := time.NewTicker(time.Second/30) e1 := &text.Editor{ Face: ctx.faces.For(regular, ui.Sp(24)), SingleLine: true, } e1.SetText("hi there") e1.Focus() e2 := &text.Editor{ Face: ctx.faces.For(regular, ui.Sp(24)), SingleLine: true, } e2.SetText("ok bye") for { select { case <-t.C: w.Invalidate() case e := <-w.Events(): switch e := e.(type) { case app.DestroyEvent: return case app.DrawEvent: ctx.Reset(w,e) f := Flex(layout.Vertical, layout.Start, layout.Start) //f(e1,e2).Layout(ctx.c, ctx.q, ctx.ops, ctx.cs) ctx.Do(f(e1,e2).Layout) w.Draw(ctx.ops) } } } }() app.Main() } func Flex(axis layout.Axis, mainAxisAlignment layout.MainAxisAlignment, crossAxisAlignment layout.CrossAxisAlignment) WidgetCombinator { f := layout.Flex{ Axis: axis, MainAxisAlignment: mainAxisAlignment, CrossAxisAlignment: crossAxisAlignment, } return func(ws ...Widget) Widget { ret := fWidget{} ret.l = func(c ui.Config, q input.Queue, ops *ui.Ops, cs layout.Constraints) layout.Dimens { f.Init(ops, cs) cs = f.Rigid() var dims layout.Dimens fcs := make([]layout.FlexChild,len(ws)) for i, w := range ws { if i > 0 { cs = f.Flexible(1) } dims = w.Layout(c, q, ops, cs) fcs[i] = f.End(dims) } return f.Layout(fcs...) } return ret } }