mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 02:15:34 +00:00
app: [API] make the zero-value Window useful and delete NewWindow
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+7
-6
@@ -8,16 +8,17 @@ See https://gioui.org for instructions to set up and run Gio programs.
|
|||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
|
|
||||||
Create a new [Window] by calling [NewWindow]. On mobile platforms or when Gio
|
A Window is run by calling its NextEvent method in a loop. The first time a
|
||||||
is embedded in another project, NewWindow merely connects with a previously
|
method on Window is called, a new GUI window is created and shown. On mobile
|
||||||
created window.
|
platforms or when Gio is embedded in another project, Window merely connects
|
||||||
|
with a previously created GUI window.
|
||||||
|
|
||||||
A Window is run by calling its NextEvent method in a loop. The most important event is
|
The most important event is [FrameEvent] that prompts an update of the window
|
||||||
[FrameEvent] that prompts an update of the window contents.
|
contents.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
w := app.NewWindow()
|
w := new(app.Window)
|
||||||
for {
|
for {
|
||||||
e := w.NextEvent()
|
e := w.NextEvent()
|
||||||
if e, ok := e.(app.FrameEvent); ok {
|
if e, ok := e.(app.FrameEvent); ok {
|
||||||
|
|||||||
+47
-57
@@ -36,6 +36,14 @@ import (
|
|||||||
type Option func(unit.Metric, *Config)
|
type Option func(unit.Metric, *Config)
|
||||||
|
|
||||||
// Window represents an operating system window.
|
// Window represents an operating system window.
|
||||||
|
//
|
||||||
|
// The zero-value Window is useful, and calling any method on
|
||||||
|
// it creates and shows a new GUI window. On iOS or Android,
|
||||||
|
// the first Window represents the the window previously
|
||||||
|
// created by the platform.
|
||||||
|
//
|
||||||
|
// More than one Window is not supported on iOS, Android,
|
||||||
|
// WebAssembly.
|
||||||
type Window struct {
|
type Window struct {
|
||||||
ctx context
|
ctx context
|
||||||
gpu gpu.GPU
|
gpu gpu.GPU
|
||||||
@@ -70,7 +78,6 @@ type Window struct {
|
|||||||
*material.Theme
|
*material.Theme
|
||||||
*widget.Decorations
|
*widget.Decorations
|
||||||
}
|
}
|
||||||
callbacks callbacks
|
|
||||||
nocontext bool
|
nocontext bool
|
||||||
// semantic data, lazily evaluated if requested by a backend to speed up
|
// semantic data, lazily evaluated if requested by a backend to speed up
|
||||||
// the cases where semantic data is not needed.
|
// the cases where semantic data is not needed.
|
||||||
@@ -85,9 +92,8 @@ type Window struct {
|
|||||||
imeState editorState
|
imeState editorState
|
||||||
driver driver
|
driver driver
|
||||||
// basic is the driver interface that is needed even after the window is gone.
|
// basic is the driver interface that is needed even after the window is gone.
|
||||||
basic basicDriver
|
basic basicDriver
|
||||||
once sync.Once
|
once sync.Once
|
||||||
initialOpts []Option
|
|
||||||
// coalesced tracks the most recent events waiting to be delivered
|
// coalesced tracks the most recent events waiting to be delivered
|
||||||
// to the client.
|
// to the client.
|
||||||
coalesced eventSummary
|
coalesced eventSummary
|
||||||
@@ -113,56 +119,6 @@ type callbacks struct {
|
|||||||
w *Window
|
w *Window
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWindow creates a new window for a set of window
|
|
||||||
// options. The options are hints; the platform is free to
|
|
||||||
// ignore or adjust them.
|
|
||||||
//
|
|
||||||
// If the current program is running on iOS or Android,
|
|
||||||
// NewWindow returns the window previously created by the
|
|
||||||
// platform.
|
|
||||||
//
|
|
||||||
// Calling NewWindow more than once is not supported on
|
|
||||||
// iOS, Android, WebAssembly.
|
|
||||||
func NewWindow(options ...Option) *Window {
|
|
||||||
debug.Parse()
|
|
||||||
// Measure decoration height.
|
|
||||||
deco := new(widget.Decorations)
|
|
||||||
theme := material.NewTheme()
|
|
||||||
theme.Shaper = text.NewShaper(text.NoSystemFonts(), text.WithCollection(gofont.Regular()))
|
|
||||||
decoStyle := material.Decorations(theme, deco, 0, "")
|
|
||||||
gtx := layout.Context{
|
|
||||||
Ops: new(op.Ops),
|
|
||||||
// Measure in Dp.
|
|
||||||
Metric: unit.Metric{},
|
|
||||||
}
|
|
||||||
// Allow plenty of space.
|
|
||||||
gtx.Constraints.Max.Y = 200
|
|
||||||
dims := decoStyle.Layout(gtx)
|
|
||||||
decoHeight := unit.Dp(dims.Size.Y)
|
|
||||||
defaultOptions := []Option{
|
|
||||||
Size(800, 600),
|
|
||||||
Title("Gio"),
|
|
||||||
Decorated(true),
|
|
||||||
decoHeightOpt(decoHeight),
|
|
||||||
}
|
|
||||||
options = append(defaultOptions, options...)
|
|
||||||
var cnf Config
|
|
||||||
cnf.apply(unit.Metric{}, options)
|
|
||||||
|
|
||||||
w := &Window{
|
|
||||||
nocontext: cnf.CustomRenderer,
|
|
||||||
}
|
|
||||||
w.decorations.Theme = theme
|
|
||||||
w.decorations.Decorations = deco
|
|
||||||
w.decorations.enabled = cnf.Decorated
|
|
||||||
w.decorations.height = decoHeight
|
|
||||||
w.imeState.compose = key.Range{Start: -1, End: -1}
|
|
||||||
w.semantic.ids = make(map[input.SemanticID]input.SemanticNode)
|
|
||||||
w.callbacks.w = w
|
|
||||||
w.initialOpts = options
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func decoHeightOpt(h unit.Dp) Option {
|
func decoHeightOpt(h unit.Dp) Option {
|
||||||
return func(m unit.Metric, c *Config) {
|
return func(m unit.Metric, c *Config) {
|
||||||
c.decoHeight = h
|
c.decoHeight = h
|
||||||
@@ -324,11 +280,13 @@ func (w *Window) Invalidate() {
|
|||||||
w.basic.Invalidate()
|
w.basic.Invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option applies the options to the window.
|
// Option applies the options to the window. The options are hints; the platform is
|
||||||
|
// free to ignore or adjust them.
|
||||||
func (w *Window) Option(opts ...Option) {
|
func (w *Window) Option(opts ...Option) {
|
||||||
if len(opts) == 0 {
|
if len(opts) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
w.init(opts...)
|
||||||
w.Run(func() {
|
w.Run(func() {
|
||||||
cnf := Config{Decorated: w.decorations.enabled}
|
cnf := Config{Decorated: w.decorations.enabled}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@@ -738,9 +696,41 @@ func (w *Window) NextEvent() event.Event {
|
|||||||
return w.basic.Event()
|
return w.basic.Event()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) init() {
|
func (w *Window) init(initial ...Option) {
|
||||||
w.once.Do(func() {
|
w.once.Do(func() {
|
||||||
newWindow(&w.callbacks, w.initialOpts)
|
debug.Parse()
|
||||||
|
// Measure decoration height.
|
||||||
|
deco := new(widget.Decorations)
|
||||||
|
theme := material.NewTheme()
|
||||||
|
theme.Shaper = text.NewShaper(text.NoSystemFonts(), text.WithCollection(gofont.Regular()))
|
||||||
|
decoStyle := material.Decorations(theme, deco, 0, "")
|
||||||
|
gtx := layout.Context{
|
||||||
|
Ops: new(op.Ops),
|
||||||
|
// Measure in Dp.
|
||||||
|
Metric: unit.Metric{},
|
||||||
|
}
|
||||||
|
// Allow plenty of space.
|
||||||
|
gtx.Constraints.Max.Y = 200
|
||||||
|
dims := decoStyle.Layout(gtx)
|
||||||
|
decoHeight := unit.Dp(dims.Size.Y)
|
||||||
|
defaultOptions := []Option{
|
||||||
|
Size(800, 600),
|
||||||
|
Title("Gio"),
|
||||||
|
Decorated(true),
|
||||||
|
decoHeightOpt(decoHeight),
|
||||||
|
}
|
||||||
|
options := append(defaultOptions, initial...)
|
||||||
|
var cnf Config
|
||||||
|
cnf.apply(unit.Metric{}, options)
|
||||||
|
|
||||||
|
w.nocontext = cnf.CustomRenderer
|
||||||
|
w.decorations.Theme = theme
|
||||||
|
w.decorations.Decorations = deco
|
||||||
|
w.decorations.enabled = cnf.Decorated
|
||||||
|
w.decorations.height = decoHeight
|
||||||
|
w.imeState.compose = key.Range{Start: -1, End: -1}
|
||||||
|
w.semantic.ids = make(map[input.SemanticID]input.SemanticNode)
|
||||||
|
newWindow(&callbacks{w}, options)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user