mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
app,io/system: extract system events to separate package
Package app is the only package that depends on native libraries and Cgo. Minimize its API, thereby minimizing Gio clients' dependency on it. In the future, a headless, testing or remote "Window" should be very easy to replace app.Window. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+4
-86
@@ -4,66 +4,14 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image"
|
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gioui.org/op"
|
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A FrameEvent asks for a new frame in the form of a list of
|
|
||||||
// operations.
|
|
||||||
type FrameEvent struct {
|
|
||||||
Config Config
|
|
||||||
// Size is the dimensions of the window.
|
|
||||||
Size image.Point
|
|
||||||
// Insets is the insets to apply.
|
|
||||||
Insets Insets
|
|
||||||
// Frame replaces the window's frame with the new
|
|
||||||
// frame.
|
|
||||||
Frame func(frame *op.Ops)
|
|
||||||
// Whether this draw is system generated and needs a complete
|
|
||||||
// frame before proceeding.
|
|
||||||
sync bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// DestroyEvent is the last event sent through
|
|
||||||
// a window event channel.
|
|
||||||
type DestroyEvent struct {
|
|
||||||
// Err is nil for normal window closures. If a
|
|
||||||
// window is prematurely closed, Err is the cause.
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insets is the space taken up by
|
|
||||||
// system decoration such as translucent
|
|
||||||
// system bars and software keyboards.
|
|
||||||
type Insets struct {
|
|
||||||
Top, Bottom, Left, Right unit.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// A StageEvent is generated whenever the stage of a
|
|
||||||
// Window changes.
|
|
||||||
type StageEvent struct {
|
|
||||||
Stage Stage
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommandEvent is a system event.
|
|
||||||
type CommandEvent struct {
|
|
||||||
Type CommandType
|
|
||||||
// Suppress the default action of the command.
|
|
||||||
Cancel bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stage of a Window.
|
|
||||||
type Stage uint8
|
|
||||||
|
|
||||||
// CommandType is the type of a CommandEvent.
|
|
||||||
type CommandType uint8
|
|
||||||
|
|
||||||
type windowRendezvous struct {
|
type windowRendezvous struct {
|
||||||
in chan windowAndOptions
|
in chan windowAndOptions
|
||||||
out chan windowAndOptions
|
out chan windowAndOptions
|
||||||
@@ -75,20 +23,6 @@ type windowAndOptions struct {
|
|||||||
opts *windowOptions
|
opts *windowOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
// StagePaused is the Stage for inactive Windows.
|
|
||||||
// Inactive Windows don't receive FrameEvents.
|
|
||||||
StagePaused Stage = iota
|
|
||||||
// StateRunning is for active Windows.
|
|
||||||
StageRunning
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// CommandBack is the command for a back action
|
|
||||||
// such as the Android back button.
|
|
||||||
CommandBack CommandType = iota
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
inchPrDp = 1.0 / 160
|
inchPrDp = 1.0 / 160
|
||||||
mmPrDp = 25.4 / 160
|
mmPrDp = 25.4 / 160
|
||||||
@@ -109,17 +43,6 @@ const (
|
|||||||
// Set with the go linker flag -X.
|
// Set with the go linker flag -X.
|
||||||
var extraArgs string
|
var extraArgs string
|
||||||
|
|
||||||
func (l Stage) String() string {
|
|
||||||
switch l {
|
|
||||||
case StagePaused:
|
|
||||||
return "StagePaused"
|
|
||||||
case StageRunning:
|
|
||||||
return "StageRunning"
|
|
||||||
default:
|
|
||||||
panic("unexpected Stage value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if extraArgs != "" {
|
if extraArgs != "" {
|
||||||
args := strings.Split(extraArgs, "|")
|
args := strings.Split(extraArgs, "|")
|
||||||
@@ -149,8 +72,8 @@ func Main() {
|
|||||||
main()
|
main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config implements the layout.Config interface.
|
// config implements the system.Config interface.
|
||||||
type Config struct {
|
type config struct {
|
||||||
// Device pixels per dp.
|
// Device pixels per dp.
|
||||||
pxPerDp float32
|
pxPerDp float32
|
||||||
// Device pixels per sp.
|
// Device pixels per sp.
|
||||||
@@ -158,11 +81,11 @@ type Config struct {
|
|||||||
now time.Time
|
now time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Now() time.Time {
|
func (c *config) Now() time.Time {
|
||||||
return c.now
|
return c.now
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Px(v unit.Value) int {
|
func (c *config) Px(v unit.Value) int {
|
||||||
var r float32
|
var r float32
|
||||||
switch v.U {
|
switch v.U {
|
||||||
case unit.UnitPx:
|
case unit.UnitPx:
|
||||||
@@ -202,8 +125,3 @@ func newWindowRendezvous() *windowRendezvous {
|
|||||||
}()
|
}()
|
||||||
return wr
|
return wr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ FrameEvent) ImplementsEvent() {}
|
|
||||||
func (_ StageEvent) ImplementsEvent() {}
|
|
||||||
func (_ *CommandEvent) ImplementsEvent() {}
|
|
||||||
func (_ DestroyEvent) ImplementsEvent() {}
|
|
||||||
|
|||||||
+26
-23
@@ -27,6 +27,7 @@ import (
|
|||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,9 +38,9 @@ type window struct {
|
|||||||
|
|
||||||
dpi int
|
dpi int
|
||||||
fontScale float32
|
fontScale float32
|
||||||
insets Insets
|
insets system.Insets
|
||||||
|
|
||||||
stage Stage
|
stage system.Stage
|
||||||
started bool
|
started bool
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -112,7 +113,7 @@ func onCreateView(env *C.JNIEnv, class C.jclass, view C.jobject) C.jlong {
|
|||||||
handle := C.jlong(view)
|
handle := C.jlong(view)
|
||||||
views[handle] = w
|
views[handle] = w
|
||||||
w.loadConfig(env, class)
|
w.loadConfig(env, class)
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
return handle
|
return handle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ func onDestroyView(env *C.JNIEnv, class C.jclass, handle C.jlong) {
|
|||||||
func onStopView(env *C.JNIEnv, class C.jclass, handle C.jlong) {
|
func onStopView(env *C.JNIEnv, class C.jclass, handle C.jlong) {
|
||||||
w := views[handle]
|
w := views[handle]
|
||||||
w.started = false
|
w.started = false
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export onStartView
|
//export onStartView
|
||||||
@@ -147,7 +148,7 @@ func onSurfaceDestroyed(env *C.JNIEnv, class C.jclass, handle C.jlong) {
|
|||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
w.win = nil
|
w.win = nil
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export onSurfaceChanged
|
//export onSurfaceChanged
|
||||||
@@ -171,7 +172,7 @@ func onLowMemory() {
|
|||||||
func onConfigurationChanged(env *C.JNIEnv, class C.jclass, view C.jlong) {
|
func onConfigurationChanged(env *C.JNIEnv, class C.jclass, view C.jlong) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
w.loadConfig(env, class)
|
w.loadConfig(env, class)
|
||||||
if w.stage >= StageRunning {
|
if w.stage >= system.StageRunning {
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +183,7 @@ func onFrameCallback(env *C.JNIEnv, class C.jclass, view C.jlong, nanos C.jlong)
|
|||||||
if !exist {
|
if !exist {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if w.stage < StageRunning {
|
if w.stage < system.StageRunning {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
@@ -199,7 +200,7 @@ func onFrameCallback(env *C.JNIEnv, class C.jclass, view C.jlong, nanos C.jlong)
|
|||||||
//export onBack
|
//export onBack
|
||||||
func onBack(env *C.JNIEnv, class C.jclass, view C.jlong) C.jboolean {
|
func onBack(env *C.JNIEnv, class C.jclass, view C.jlong) C.jboolean {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
ev := &CommandEvent{Type: CommandBack}
|
ev := &system.CommandEvent{Type: system.CommandBack}
|
||||||
w.event(ev)
|
w.event(ev)
|
||||||
if ev.Cancel {
|
if ev.Cancel {
|
||||||
return C.JNI_TRUE
|
return C.JNI_TRUE
|
||||||
@@ -216,13 +217,13 @@ func onFocusChange(env *C.JNIEnv, class C.jclass, view C.jlong, focus C.jboolean
|
|||||||
//export onWindowInsets
|
//export onWindowInsets
|
||||||
func onWindowInsets(env *C.JNIEnv, class C.jclass, view C.jlong, top, right, bottom, left C.jint) {
|
func onWindowInsets(env *C.JNIEnv, class C.jclass, view C.jlong, top, right, bottom, left C.jint) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
w.insets = Insets{
|
w.insets = system.Insets{
|
||||||
Top: unit.Px(float32(top)),
|
Top: unit.Px(float32(top)),
|
||||||
Right: unit.Px(float32(right)),
|
Right: unit.Px(float32(right)),
|
||||||
Bottom: unit.Px(float32(bottom)),
|
Bottom: unit.Px(float32(bottom)),
|
||||||
Left: unit.Px(float32(left)),
|
Left: unit.Px(float32(left)),
|
||||||
}
|
}
|
||||||
if w.stage >= StageRunning {
|
if w.stage >= system.StageRunning {
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,16 +234,16 @@ func (w *window) setVisible() {
|
|||||||
if width == 0 || height == 0 {
|
if width == 0 || height == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) setStage(stage Stage) {
|
func (w *window) setStage(stage system.Stage) {
|
||||||
if stage == w.stage {
|
if stage == w.stage {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.stage = stage
|
w.stage = stage
|
||||||
w.event(StageEvent{stage})
|
w.event(system.StageEvent{stage})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) nativeWindow(visID int) (*C.ANativeWindow, int, int) {
|
func (w *window) nativeWindow(visID int) (*C.ANativeWindow, int, int) {
|
||||||
@@ -296,16 +297,18 @@ func (w *window) draw(sync bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ppdp := float32(w.dpi) * inchPrDp
|
ppdp := float32(w.dpi) * inchPrDp
|
||||||
w.event(FrameEvent{
|
w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: int(width),
|
Size: image.Point{
|
||||||
Y: int(height),
|
X: int(width),
|
||||||
},
|
Y: int(height),
|
||||||
Insets: w.insets,
|
},
|
||||||
Config: Config{
|
Insets: w.insets,
|
||||||
pxPerDp: ppdp,
|
Config: &config{
|
||||||
pxPerSp: w.fontScale * ppdp,
|
pxPerDp: ppdp,
|
||||||
now: time.Now(),
|
pxPerSp: w.fontScale * ppdp,
|
||||||
|
now: time.Now(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
sync: sync,
|
sync: sync,
|
||||||
})
|
})
|
||||||
|
|||||||
+22
-19
@@ -25,6 +25,7 @@ import (
|
|||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ func onCreate(view C.CFTypeRef) {
|
|||||||
w.layer = C.CFTypeRef(layerFactory())
|
w.layer = C.CFTypeRef(layerFactory())
|
||||||
C.gio_addLayerToView(view, w.layer)
|
C.gio_addLayerToView(view, w.layer)
|
||||||
views[view] = w
|
views[view] = w
|
||||||
w.w.event(StageEvent{StagePaused})
|
w.w.event(system.StageEvent{Stage: system.StagePaused})
|
||||||
}
|
}
|
||||||
|
|
||||||
//export onDraw
|
//export onDraw
|
||||||
@@ -74,27 +75,29 @@ func onDraw(view C.CFTypeRef, dpi, sdpi, width, height C.CGFloat, sync C.int, to
|
|||||||
w.visible.Store(true)
|
w.visible.Store(true)
|
||||||
C.gio_updateView(view, w.layer)
|
C.gio_updateView(view, w.layer)
|
||||||
if !wasVisible {
|
if !wasVisible {
|
||||||
w.w.event(StageEvent{StageRunning})
|
w.w.event(system.StageEvent{Stage: system.StageRunning})
|
||||||
}
|
}
|
||||||
isSync := false
|
isSync := false
|
||||||
if sync != 0 {
|
if sync != 0 {
|
||||||
isSync = true
|
isSync = true
|
||||||
}
|
}
|
||||||
w.w.event(FrameEvent{
|
w.w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: int(width + .5),
|
Size: image.Point{
|
||||||
Y: int(height + .5),
|
X: int(width + .5),
|
||||||
},
|
Y: int(height + .5),
|
||||||
Insets: Insets{
|
},
|
||||||
Top: unit.Px(float32(top)),
|
Insets: system.Insets{
|
||||||
Right: unit.Px(float32(right)),
|
Top: unit.Px(float32(top)),
|
||||||
Bottom: unit.Px(float32(bottom)),
|
Right: unit.Px(float32(right)),
|
||||||
Left: unit.Px(float32(left)),
|
Bottom: unit.Px(float32(bottom)),
|
||||||
},
|
Left: unit.Px(float32(left)),
|
||||||
Config: Config{
|
},
|
||||||
pxPerDp: float32(dpi) * inchPrDp,
|
Config: &config{
|
||||||
pxPerSp: float32(sdpi) * inchPrDp,
|
pxPerDp: float32(dpi) * inchPrDp,
|
||||||
now: time.Now(),
|
pxPerSp: float32(sdpi) * inchPrDp,
|
||||||
|
now: time.Now(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
sync: isSync,
|
sync: isSync,
|
||||||
})
|
})
|
||||||
@@ -104,14 +107,14 @@ func onDraw(view C.CFTypeRef, dpi, sdpi, width, height C.CGFloat, sync C.int, to
|
|||||||
func onStop(view C.CFTypeRef) {
|
func onStop(view C.CFTypeRef) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
w.visible.Store(false)
|
w.visible.Store(false)
|
||||||
w.w.event(StageEvent{StagePaused})
|
w.w.event(system.StageEvent{Stage: system.StagePaused})
|
||||||
}
|
}
|
||||||
|
|
||||||
//export onDestroy
|
//export onDestroy
|
||||||
func onDestroy(view C.CFTypeRef) {
|
func onDestroy(view C.CFTypeRef) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
delete(views, view)
|
delete(views, view)
|
||||||
w.w.event(DestroyEvent{})
|
w.w.event(system.DestroyEvent{})
|
||||||
C.gio_removeLayer(w.layer)
|
C.gio_removeLayer(w.layer)
|
||||||
C.CFRelease(w.layer)
|
C.CFRelease(w.layer)
|
||||||
w.layer = 0
|
w.layer = 0
|
||||||
|
|||||||
+13
-10
@@ -11,6 +11,7 @@ import (
|
|||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
type window struct {
|
type window struct {
|
||||||
@@ -53,7 +54,7 @@ func createWindow(win *Window, opts *windowOptions) error {
|
|||||||
go func() {
|
go func() {
|
||||||
w.w.setDriver(w)
|
w.w.setDriver(w)
|
||||||
w.focus()
|
w.focus()
|
||||||
w.w.event(StageEvent{StageRunning})
|
w.w.event(system.StageEvent{Stage: system.StageRunning})
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
select {}
|
select {}
|
||||||
w.cleanup()
|
w.cleanup()
|
||||||
@@ -338,24 +339,26 @@ func (w *window) showTextInput(show bool) {
|
|||||||
|
|
||||||
func (w *window) draw(sync bool) {
|
func (w *window) draw(sync bool) {
|
||||||
width, height, scale, cfg := w.config()
|
width, height, scale, cfg := w.config()
|
||||||
if cfg == (Config{}) {
|
if cfg == (config{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
w.scale = float32(scale)
|
w.scale = float32(scale)
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
cfg.now = time.Now()
|
cfg.now = time.Now()
|
||||||
w.w.event(FrameEvent{
|
w.w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: width,
|
Size: image.Point{
|
||||||
Y: height,
|
X: width,
|
||||||
|
Y: height,
|
||||||
|
},
|
||||||
|
Config: &cfg,
|
||||||
},
|
},
|
||||||
Config: cfg,
|
sync: sync,
|
||||||
sync: sync,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) config() (int, int, float32, Config) {
|
func (w *window) config() (int, int, float32, config) {
|
||||||
rect := w.cnv.Call("getBoundingClientRect")
|
rect := w.cnv.Call("getBoundingClientRect")
|
||||||
width, height := rect.Get("width").Float(), rect.Get("height").Float()
|
width, height := rect.Get("width").Float(), rect.Get("height").Float()
|
||||||
scale := w.window.Get("devicePixelRatio").Float()
|
scale := w.window.Get("devicePixelRatio").Float()
|
||||||
@@ -368,7 +371,7 @@ func (w *window) config() (int, int, float32, Config) {
|
|||||||
w.cnv.Set("height", ih)
|
w.cnv.Set("height", ih)
|
||||||
}
|
}
|
||||||
const ppdp = 96 * inchPrDp * monitorScale
|
const ppdp = 96 * inchPrDp * monitorScale
|
||||||
return iw, ih, float32(scale), Config{
|
return iw, ih, float32(scale), config{
|
||||||
pxPerDp: ppdp * float32(scale),
|
pxPerDp: ppdp * float32(scale),
|
||||||
pxPerSp: ppdp * float32(scale),
|
pxPerSp: ppdp * float32(scale),
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-22
@@ -4,13 +4,6 @@
|
|||||||
|
|
||||||
package app
|
package app
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo CFLAGS: -DGL_SILENCE_DEPRECATION -Werror -Wno-deprecated-declarations -fmodules -fobjc-arc -x objective-c
|
|
||||||
|
|
||||||
#include <AppKit/AppKit.h>
|
|
||||||
#include "os_macos.h"
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image"
|
"image"
|
||||||
@@ -22,8 +15,17 @@ import (
|
|||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -DGL_SILENCE_DEPRECATION -Werror -Wno-deprecated-declarations -fmodules -fobjc-arc -x objective-c
|
||||||
|
|
||||||
|
#include <AppKit/AppKit.h>
|
||||||
|
#include "os_macos.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Darwin requires that UI operations happen on the main thread only.
|
// Darwin requires that UI operations happen on the main thread only.
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
@@ -32,7 +34,7 @@ func init() {
|
|||||||
type window struct {
|
type window struct {
|
||||||
view C.CFTypeRef
|
view C.CFTypeRef
|
||||||
w *Window
|
w *Window
|
||||||
stage Stage
|
stage system.Stage
|
||||||
ppdp float32
|
ppdp float32
|
||||||
scale float32
|
scale float32
|
||||||
}
|
}
|
||||||
@@ -89,12 +91,12 @@ func (w *window) setAnimating(anim bool) {
|
|||||||
C.gio_setAnimating(w.view, animb)
|
C.gio_setAnimating(w.view, animb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) setStage(stage Stage) {
|
func (w *window) setStage(stage system.Stage) {
|
||||||
if stage == w.stage {
|
if stage == w.stage {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.stage = stage
|
w.stage = stage
|
||||||
w.w.event(StageEvent{stage})
|
w.w.event(system.StageEvent{Stage: stage})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a top level func for onFrameCallback to avoid
|
// Use a top level func for onFrameCallback to avoid
|
||||||
@@ -197,14 +199,16 @@ func (w *window) draw(sync bool) {
|
|||||||
height := int(hf*w.scale + .5)
|
height := int(hf*w.scale + .5)
|
||||||
cfg := configFor(w.ppdp, w.scale)
|
cfg := configFor(w.ppdp, w.scale)
|
||||||
cfg.now = time.Now()
|
cfg.now = time.Now()
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
w.w.event(FrameEvent{
|
w.w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: width,
|
Size: image.Point{
|
||||||
Y: height,
|
X: width,
|
||||||
|
Y: height,
|
||||||
|
},
|
||||||
|
Config: &cfg,
|
||||||
},
|
},
|
||||||
Config: cfg,
|
sync: sync,
|
||||||
sync: sync,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,9 +221,9 @@ func getPixelsPerDp(scale float32) float32 {
|
|||||||
return ppdp / scale
|
return ppdp / scale
|
||||||
}
|
}
|
||||||
|
|
||||||
func configFor(ppdp, scale float32) Config {
|
func configFor(ppdp, scale float32) config {
|
||||||
ppdp = ppdp * scale
|
ppdp = ppdp * scale
|
||||||
return Config{
|
return config{
|
||||||
pxPerDp: ppdp,
|
pxPerDp: ppdp,
|
||||||
pxPerSp: ppdp,
|
pxPerSp: ppdp,
|
||||||
}
|
}
|
||||||
@@ -230,7 +234,7 @@ func gio_onTerminate(view C.CFTypeRef) {
|
|||||||
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
delete(views, view)
|
delete(views, view)
|
||||||
w.w.event(DestroyEvent{})
|
w.w.event(system.DestroyEvent{})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +242,7 @@ func gio_onTerminate(view C.CFTypeRef) {
|
|||||||
func gio_onHide(view C.CFTypeRef) {
|
func gio_onHide(view C.CFTypeRef) {
|
||||||
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +250,7 @@ func gio_onHide(view C.CFTypeRef) {
|
|||||||
func gio_onShow(view C.CFTypeRef) {
|
func gio_onShow(view C.CFTypeRef) {
|
||||||
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
viewDo(view, func(views viewMap, view C.CFTypeRef) {
|
||||||
w := views[view]
|
w := views[view]
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-16
@@ -21,6 +21,7 @@ import (
|
|||||||
"gioui.org/internal/fling"
|
"gioui.org/internal/fling"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
syscall "golang.org/x/sys/unix"
|
syscall "golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ type window struct {
|
|||||||
dir f32.Point
|
dir f32.Point
|
||||||
}
|
}
|
||||||
|
|
||||||
stage Stage
|
stage system.Stage
|
||||||
dead bool
|
dead bool
|
||||||
pendingErr error
|
pendingErr error
|
||||||
lastFrameCallback *C.struct_wl_callback
|
lastFrameCallback *C.struct_wl_callback
|
||||||
@@ -302,7 +303,7 @@ func gio_onXdgSurfaceConfigure(data unsafe.Pointer, wmSurf *C.struct_xdg_surface
|
|||||||
w.serial = serial
|
w.serial = serial
|
||||||
w.needAck = true
|
w.needAck = true
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,7 +773,7 @@ loop:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if w.dead {
|
if w.dead {
|
||||||
w.w.event(DestroyEvent{Err: w.pendingErr})
|
w.w.event(system.DestroyEvent{Err: w.pendingErr})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// Clear poll events.
|
// Clear poll events.
|
||||||
@@ -979,16 +980,16 @@ func (w *window) updateOutputs() {
|
|||||||
}
|
}
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
if !found {
|
if !found {
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
} else {
|
} else {
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) config() (int, int, Config) {
|
func (w *window) config() (int, int, config) {
|
||||||
width, height := w.width*w.scale, w.height*w.scale
|
width, height := w.width*w.scale, w.height*w.scale
|
||||||
return width, height, Config{
|
return width, height, config{
|
||||||
pxPerDp: w.ppdp * float32(w.scale),
|
pxPerDp: w.ppdp * float32(w.scale),
|
||||||
pxPerSp: w.ppsp * float32(w.scale),
|
pxPerSp: w.ppsp * float32(w.scale),
|
||||||
}
|
}
|
||||||
@@ -1015,7 +1016,7 @@ func (w *window) draw(sync bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
width, height, cfg := w.config()
|
width, height, cfg := w.config()
|
||||||
if cfg == (Config{}) {
|
if cfg == (config{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if animating && w.lastFrameCallback == nil {
|
if animating && w.lastFrameCallback == nil {
|
||||||
@@ -1024,22 +1025,24 @@ func (w *window) draw(sync bool) {
|
|||||||
C.gio_wl_callback_add_listener(w.lastFrameCallback, unsafe.Pointer(w.surf))
|
C.gio_wl_callback_add_listener(w.lastFrameCallback, unsafe.Pointer(w.surf))
|
||||||
}
|
}
|
||||||
cfg.now = time.Now()
|
cfg.now = time.Now()
|
||||||
w.w.event(FrameEvent{
|
w.w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: width,
|
Size: image.Point{
|
||||||
Y: height,
|
X: width,
|
||||||
|
Y: height,
|
||||||
|
},
|
||||||
|
Config: &cfg,
|
||||||
},
|
},
|
||||||
Config: cfg,
|
sync: sync,
|
||||||
sync: sync,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) setStage(s Stage) {
|
func (w *window) setStage(s system.Stage) {
|
||||||
if s == w.stage {
|
if s == w.stage {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.stage = s
|
w.stage = s
|
||||||
w.w.event(StageEvent{s})
|
w.w.event(system.StageEvent{s})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) display() *C.struct_wl_display {
|
func (w *window) display() *C.struct_wl_display {
|
||||||
|
|||||||
+17
-14
@@ -17,6 +17,7 @@ import (
|
|||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/io/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
var winMap = make(map[syscall.Handle]*window)
|
var winMap = make(map[syscall.Handle]*window)
|
||||||
@@ -60,7 +61,7 @@ type window struct {
|
|||||||
w *Window
|
w *Window
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
stage Stage
|
stage system.Stage
|
||||||
dead bool
|
dead bool
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -183,7 +184,7 @@ func createWindow(window *Window, opts *windowOptions) error {
|
|||||||
defer delete(winMap, w.hwnd)
|
defer delete(winMap, w.hwnd)
|
||||||
w.w = window
|
w.w = window
|
||||||
w.w.setDriver(w)
|
w.w.setDriver(w)
|
||||||
defer w.w.event(DestroyEvent{})
|
defer w.w.event(system.DestroyEvent{})
|
||||||
showWindow(w.hwnd, _SW_SHOWDEFAULT)
|
showWindow(w.hwnd, _SW_SHOWDEFAULT)
|
||||||
setForegroundWindow(w.hwnd)
|
setForegroundWindow(w.hwnd)
|
||||||
setFocus(w.hwnd)
|
setFocus(w.hwnd)
|
||||||
@@ -326,9 +327,9 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
|
|||||||
case _WM_SIZE:
|
case _WM_SIZE:
|
||||||
switch wParam {
|
switch wParam {
|
||||||
case _SIZE_MINIMIZED:
|
case _SIZE_MINIMIZED:
|
||||||
w.setStage(StagePaused)
|
w.setStage(system.StagePaused)
|
||||||
case _SIZE_MAXIMIZED, _SIZE_RESTORED:
|
case _SIZE_MAXIMIZED, _SIZE_RESTORED:
|
||||||
w.setStage(StageRunning)
|
w.setStage(system.StageRunning)
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,9 +396,9 @@ func (w *window) postRedraw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) setStage(s Stage) {
|
func (w *window) setStage(s system.Stage) {
|
||||||
w.stage = s
|
w.stage = s
|
||||||
w.w.event(StageEvent{s})
|
w.w.event(system.StageEvent{Stage: s})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) draw(sync bool) {
|
func (w *window) draw(sync bool) {
|
||||||
@@ -407,13 +408,15 @@ func (w *window) draw(sync bool) {
|
|||||||
w.height = int(r.bottom - r.top)
|
w.height = int(r.bottom - r.top)
|
||||||
cfg := configForDC(w.hdc)
|
cfg := configForDC(w.hdc)
|
||||||
cfg.now = time.Now()
|
cfg.now = time.Now()
|
||||||
w.w.event(FrameEvent{
|
w.w.event(frameEvent{
|
||||||
Size: image.Point{
|
FrameEvent: system.FrameEvent{
|
||||||
X: w.width,
|
Size: image.Point{
|
||||||
Y: w.height,
|
X: w.width,
|
||||||
|
Y: w.height,
|
||||||
|
},
|
||||||
|
Config: &cfg,
|
||||||
},
|
},
|
||||||
Config: cfg,
|
sync: sync,
|
||||||
sync: sync,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,14 +477,14 @@ func convertKeyCode(code uintptr) (rune, bool) {
|
|||||||
return r, true
|
return r, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func configForDC(hdc syscall.Handle) Config {
|
func configForDC(hdc syscall.Handle) config {
|
||||||
dpi := getDeviceCaps(hdc, _LOGPIXELSX)
|
dpi := getDeviceCaps(hdc, _LOGPIXELSX)
|
||||||
ppdp := float32(dpi) * inchPrDp * monitorScale
|
ppdp := float32(dpi) * inchPrDp * monitorScale
|
||||||
// Force a minimum density to keep text legible and to handle bogus output geometry.
|
// Force a minimum density to keep text legible and to handle bogus output geometry.
|
||||||
if ppdp < minDensity {
|
if ppdp < minDensity {
|
||||||
ppdp = minDensity
|
ppdp = minDensity
|
||||||
}
|
}
|
||||||
return Config{
|
return config{
|
||||||
pxPerDp: ppdp,
|
pxPerDp: ppdp,
|
||||||
pxPerSp: ppdp,
|
pxPerSp: ppdp,
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-12
@@ -12,6 +12,7 @@ import (
|
|||||||
"gioui.org/app/internal/input"
|
"gioui.org/app/internal/input"
|
||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/profile"
|
"gioui.org/io/profile"
|
||||||
|
"gioui.org/io/system"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
@@ -24,6 +25,12 @@ type windowOptions struct {
|
|||||||
Title string
|
Title string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type frameEvent struct {
|
||||||
|
system.FrameEvent
|
||||||
|
|
||||||
|
sync bool
|
||||||
|
}
|
||||||
|
|
||||||
// Window represents an operating system window.
|
// Window represents an operating system window.
|
||||||
type Window struct {
|
type Window struct {
|
||||||
driver *window
|
driver *window
|
||||||
@@ -37,7 +44,7 @@ type Window struct {
|
|||||||
invalidates chan struct{}
|
invalidates chan struct{}
|
||||||
frames chan *op.Ops
|
frames chan *op.Ops
|
||||||
|
|
||||||
stage Stage
|
stage system.Stage
|
||||||
animating bool
|
animating bool
|
||||||
hasNextFrame bool
|
hasNextFrame bool
|
||||||
nextFrame time.Time
|
nextFrame time.Time
|
||||||
@@ -170,7 +177,7 @@ func (w *Window) updateAnimation() {
|
|||||||
w.delayedDraw.Stop()
|
w.delayedDraw.Stop()
|
||||||
w.delayedDraw = nil
|
w.delayedDraw = nil
|
||||||
}
|
}
|
||||||
if w.stage >= StageRunning && w.hasNextFrame {
|
if w.stage >= system.StageRunning && w.hasNextFrame {
|
||||||
if dt := time.Until(w.nextFrame); dt <= 0 {
|
if dt := time.Until(w.nextFrame); dt <= 0 {
|
||||||
animate = true
|
animate = true
|
||||||
} else {
|
} else {
|
||||||
@@ -210,10 +217,10 @@ func (w *Window) waitAck() {
|
|||||||
func (w *Window) destroy(err error) {
|
func (w *Window) destroy(err error) {
|
||||||
// Ack the current event.
|
// Ack the current event.
|
||||||
w.ack <- struct{}{}
|
w.ack <- struct{}{}
|
||||||
w.out <- DestroyEvent{err}
|
w.out <- system.DestroyEvent{Err: err}
|
||||||
for e := range w.in {
|
for e := range w.in {
|
||||||
w.ack <- struct{}{}
|
w.ack <- struct{}{}
|
||||||
if _, ok := e.(DestroyEvent); ok {
|
if _, ok := e.(system.DestroyEvent); ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +230,7 @@ func (w *Window) run(opts *windowOptions) {
|
|||||||
defer close(w.in)
|
defer close(w.in)
|
||||||
defer close(w.out)
|
defer close(w.out)
|
||||||
if err := createWindow(w, opts); err != nil {
|
if err := createWindow(w, opts); err != nil {
|
||||||
w.out <- DestroyEvent{err}
|
w.out <- system.DestroyEvent{Err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
@@ -240,9 +247,9 @@ func (w *Window) run(opts *windowOptions) {
|
|||||||
w.updateAnimation()
|
w.updateAnimation()
|
||||||
case e := <-w.in:
|
case e := <-w.in:
|
||||||
switch e2 := e.(type) {
|
switch e2 := e.(type) {
|
||||||
case StageEvent:
|
case system.StageEvent:
|
||||||
if w.gpu != nil {
|
if w.gpu != nil {
|
||||||
if e2.Stage < StageRunning {
|
if e2.Stage < system.StageRunning {
|
||||||
w.gpu.Release()
|
w.gpu.Release()
|
||||||
w.gpu = nil
|
w.gpu = nil
|
||||||
} else {
|
} else {
|
||||||
@@ -253,18 +260,18 @@ func (w *Window) run(opts *windowOptions) {
|
|||||||
w.updateAnimation()
|
w.updateAnimation()
|
||||||
w.out <- e
|
w.out <- e
|
||||||
w.waitAck()
|
w.waitAck()
|
||||||
case FrameEvent:
|
case frameEvent:
|
||||||
if e2.Size == (image.Point{}) {
|
if e2.Size == (image.Point{}) {
|
||||||
panic(errors.New("internal error: zero-sized Draw"))
|
panic(errors.New("internal error: zero-sized Draw"))
|
||||||
}
|
}
|
||||||
if w.stage < StageRunning {
|
if w.stage < system.StageRunning {
|
||||||
// No drawing if not visible.
|
// No drawing if not visible.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.drawStart = time.Now()
|
w.drawStart = time.Now()
|
||||||
w.hasNextFrame = false
|
w.hasNextFrame = false
|
||||||
e2.Frame = w.update
|
e2.Frame = w.update
|
||||||
w.out <- e2
|
w.out <- e2.FrameEvent
|
||||||
var frame *op.Ops
|
var frame *op.Ops
|
||||||
// Wait for either a frame or the ack event,
|
// Wait for either a frame or the ack event,
|
||||||
// which meant that the client didn't draw.
|
// which meant that the client didn't draw.
|
||||||
@@ -303,12 +310,12 @@ func (w *Window) run(opts *windowOptions) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *CommandEvent:
|
case *system.CommandEvent:
|
||||||
w.out <- e
|
w.out <- e
|
||||||
w.waitAck()
|
w.waitAck()
|
||||||
case driverEvent:
|
case driverEvent:
|
||||||
w.driver = e2.driver
|
w.driver = e2.driver
|
||||||
case DestroyEvent:
|
case system.DestroyEvent:
|
||||||
w.out <- e2
|
w.out <- e2
|
||||||
w.ack <- struct{}{}
|
w.ack <- struct{}{}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
|
// Package system contains events usually handled at the top-level
|
||||||
|
// program level.
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gioui.org/op"
|
||||||
|
"gioui.org/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A FrameEvent asks for a new frame in the form of a list of
|
||||||
|
// operations.
|
||||||
|
type FrameEvent struct {
|
||||||
|
Config Config
|
||||||
|
// Size is the dimensions of the window.
|
||||||
|
Size image.Point
|
||||||
|
// Insets is the insets to apply.
|
||||||
|
Insets Insets
|
||||||
|
// Frame replaces the window's frame with the new
|
||||||
|
// frame.
|
||||||
|
Frame func(frame *op.Ops)
|
||||||
|
// Whether this draw is system generated and needs a complete
|
||||||
|
// frame before proceeding.
|
||||||
|
sync bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config define the essential properties of
|
||||||
|
// the environment.
|
||||||
|
type Config interface {
|
||||||
|
// Now returns the current animation time.
|
||||||
|
Now() time.Time
|
||||||
|
|
||||||
|
unit.Converter
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestroyEvent is the last event sent through
|
||||||
|
// a window event channel.
|
||||||
|
type DestroyEvent struct {
|
||||||
|
// Err is nil for normal window closures. If a
|
||||||
|
// window is prematurely closed, Err is the cause.
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insets is the space taken up by
|
||||||
|
// system decoration such as translucent
|
||||||
|
// system bars and software keyboards.
|
||||||
|
type Insets struct {
|
||||||
|
Top, Bottom, Left, Right unit.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// A StageEvent is generated whenever the stage of a
|
||||||
|
// Window changes.
|
||||||
|
type StageEvent struct {
|
||||||
|
Stage Stage
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandEvent is a system event.
|
||||||
|
type CommandEvent struct {
|
||||||
|
Type CommandType
|
||||||
|
// Suppress the default action of the command.
|
||||||
|
Cancel bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage of a Window.
|
||||||
|
type Stage uint8
|
||||||
|
|
||||||
|
// CommandType is the type of a CommandEvent.
|
||||||
|
type CommandType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StagePaused is the Stage for inactive Windows.
|
||||||
|
// Inactive Windows don't receive FrameEvents.
|
||||||
|
StagePaused Stage = iota
|
||||||
|
// StateRunning is for active Windows.
|
||||||
|
StageRunning
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CommandBack is the command for a back action
|
||||||
|
// such as the Android back button.
|
||||||
|
CommandBack CommandType = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Stage) String() string {
|
||||||
|
switch l {
|
||||||
|
case StagePaused:
|
||||||
|
return "StagePaused"
|
||||||
|
case StageRunning:
|
||||||
|
return "StageRunning"
|
||||||
|
default:
|
||||||
|
panic("unexpected Stage value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FrameEvent) ImplementsEvent() {}
|
||||||
|
func (_ StageEvent) ImplementsEvent() {}
|
||||||
|
func (_ *CommandEvent) ImplementsEvent() {}
|
||||||
|
func (_ DestroyEvent) ImplementsEvent() {}
|
||||||
+3
-12
@@ -4,9 +4,9 @@ package layout
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"time"
|
|
||||||
|
|
||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
|
"gioui.org/io/system"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
@@ -53,20 +53,11 @@ type Context struct {
|
|||||||
// operation.
|
// operation.
|
||||||
Dimensions Dimensions
|
Dimensions Dimensions
|
||||||
|
|
||||||
Config
|
system.Config
|
||||||
event.Queue
|
event.Queue
|
||||||
*op.Ops
|
*op.Ops
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config define the essential properties of
|
|
||||||
// the environment.
|
|
||||||
type Config interface {
|
|
||||||
// Now returns the current animation time.
|
|
||||||
Now() time.Time
|
|
||||||
|
|
||||||
unit.Converter
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Start Alignment = iota
|
Start Alignment = iota
|
||||||
End
|
End
|
||||||
@@ -104,7 +95,7 @@ func (s *Context) Layout(cs Constraints, w Widget) Dimensions {
|
|||||||
|
|
||||||
// Reset the context. The constraints' minimum and maximum values are
|
// Reset the context. The constraints' minimum and maximum values are
|
||||||
// set to the size.
|
// set to the size.
|
||||||
func (c *Context) Reset(cfg Config, size image.Point) {
|
func (c *Context) Reset(cfg system.Config, size image.Point) {
|
||||||
c.Constraints = RigidConstraints(size)
|
c.Constraints = RigidConstraints(size)
|
||||||
c.Dimensions = Dimensions{}
|
c.Dimensions = Dimensions{}
|
||||||
c.Config = cfg
|
c.Config = cfg
|
||||||
|
|||||||
Reference in New Issue
Block a user