mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
36d1cd90f2
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>
128 lines
2.6 KiB
Go
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
|
|
}
|