blob: 693409a45920cc8d3c3bafb81e30226242943066 [file] [log] [blame]
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package widget
import (
"image"
"golang.org/x/exp/shiny/screen"
"golang.org/x/exp/shiny/unit"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
"golang.org/x/mobile/event/size"
)
// TODO: how does RunWindow's caller inject or process events (whether general
// like lifecycle events or app-specific)? How does it stop the event loop when
// the app's work is done?
// TODO: how do widgets signal that they need repaint or relayout?
// TODO: propagate keyboard / mouse / touch events.
// RunWindow creates a new window for s, with the given widget tree, and runs
// its event loop.
func RunWindow(s screen.Screen, root *Node) error {
var (
buf screen.Buffer
t Theme
)
defer func() {
if buf != nil {
buf.Release()
}
}()
w, err := s.NewWindow(nil)
if err != nil {
return err
}
defer w.Release()
for {
switch e := w.NextEvent().(type) {
case lifecycle.Event:
if e.To == lifecycle.StageDead {
return nil
}
case paint.Event:
if buf != nil {
w.Upload(image.Point{}, buf, buf.Bounds())
}
w.Publish()
case size.Event:
if buf != nil {
buf.Release()
}
var err error
buf, err = s.NewBuffer(e.Size())
if err != nil {
return err
}
t.DPI = float64(e.PixelsPerPt) * unit.PointsPerInch
root.Measure(&t)
root.Rect = e.Bounds()
root.Layout(&t)
root.Paint(&t, buf.RGBA(), image.Point{})
case error:
return e
}
}
}