Files
gio/app/app.go
T
Elias Naur 36d1cd90f2 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>
2019-10-14 16:20:20 +02:00

128 lines
2.6 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
package app
import (
"errors"
"math"
"os"
"strings"
"time"
"gioui.org/unit"
)
type windowRendezvous struct {
in chan windowAndOptions
out chan windowAndOptions
errs chan error
}
type windowAndOptions struct {
window *Window
opts *windowOptions
}
const (
inchPrDp = 1.0 / 160
mmPrDp = 25.4 / 160
// monitorScale is the extra scale applied to
// monitor outputs to compensate for the extra
// viewing distance compared to phone and tables.
monitorScale = 1.20
// minDensity is the minimum pixels per dp to
// ensure font and ui legibility on low-dpi
// screens.
minDensity = 1.25
)
// extraArgs contains extra arguments to append to
// os.Args. The arguments are separated with |.
// Useful for running programs on mobiles where the
// command line is not available.
// Set with the go linker flag -X.
var extraArgs string
func init() {
if extraArgs != "" {
args := strings.Split(extraArgs, "|")
os.Args = append(os.Args, args...)
}
}
// DataDir returns a path to use for application-specific
// configuration data.
// On desktop systems, DataDir use os.UserConfigDir.
// On iOS NSDocumentDirectory is queried.
// For Android Context.getFilesDir is used.
//
// BUG: DataDir blocks on Android until init functions
// have completed.
func DataDir() (string, error) {
return dataDir()
}
// Main must be called from the a program's main function. It
// blocks until there are no more windows active.
//
// Calling Main is necessary because some operating systems
// require control of the main thread of the program for
// running windows.
func Main() {
main()
}
// config implements the system.Config interface.
type config struct {
// Device pixels per dp.
pxPerDp float32
// Device pixels per sp.
pxPerSp float32
now time.Time
}
func (c *config) Now() time.Time {
return c.now
}
func (c *config) Px(v unit.Value) int {
var r float32
switch v.U {
case unit.UnitPx:
r = v.V
case unit.UnitDp:
r = c.pxPerDp * v.V
case unit.UnitSp:
r = c.pxPerSp * v.V
default:
panic("unknown unit")
}
return int(math.Round(float64(r)))
}
func newWindowRendezvous() *windowRendezvous {
wr := &windowRendezvous{
in: make(chan windowAndOptions),
out: make(chan windowAndOptions),
errs: make(chan error),
}
go func() {
var main windowAndOptions
var out chan windowAndOptions
for {
select {
case w := <-wr.in:
var err error
if main.window != nil {
err = errors.New("multiple windows are not supported")
}
wr.errs <- err
main = w
out = wr.out
case out <- main:
}
}
}()
return wr
}