ui,ui/app: convert Config to an interface

To keep the interface slim, remove the helper methods and shorten
the essential method, Pixels, to Px.

Add and use unexported Config implementation in the app package.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-07-10 16:40:53 +02:00
parent 624ef78e1c
commit 32aae18293
14 changed files with 104 additions and 104 deletions
+34 -1
View File
@@ -4,8 +4,10 @@ package app
import (
"image"
"math"
"os"
"strings"
"time"
"gioui.org/ui"
)
@@ -15,7 +17,7 @@ type Event interface {
}
type DrawEvent struct {
Config ui.Config
Config Config
Size image.Point
// Insets is the window space taken up by
// system decoration such as translucent
@@ -131,3 +133,34 @@ func init() {
func DataDir() (string, error) {
return dataDir()
}
// Config implements the ui.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 ui.Value) int {
var r float32
switch v.U {
case ui.UnitPx:
r = v.V
case ui.UnitDp:
r = c.pxPerDp * v.V
case ui.UnitSp:
r = c.pxPerSp * v.V
default:
panic("unknown unit")
}
if math.IsInf(float64(r), +1) {
return ui.Inf
}
return int(math.Round(float64(r)))
}
+4 -5
View File
@@ -24,7 +24,6 @@ import (
"time"
"unsafe"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -289,10 +288,10 @@ func (w *window) draw(sync bool) {
Y: int(height),
},
Insets: w.insets,
Config: ui.Config{
PxPerDp: ppdp,
PxPerSp: w.fontScale * ppdp,
Now: time.Now(),
Config: Config{
pxPerDp: ppdp,
pxPerSp: w.fontScale * ppdp,
now: time.Now(),
},
sync: sync,
})
+4 -5
View File
@@ -22,7 +22,6 @@ import (
"sync/atomic"
"time"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -87,10 +86,10 @@ func onDraw(view C.CFTypeRef, dpi, sdpi, width, height C.CGFloat, sync C.int, to
Min: image.Point{X: int(left + .5), Y: int(top + .5)},
Max: image.Point{X: int(right + .5), Y: int(bottom + .5)},
},
Config: ui.Config{
PxPerDp: float32(dpi) * inchPrDp,
PxPerSp: float32(sdpi) * inchPrDp,
Now: time.Now(),
Config: Config{
pxPerDp: float32(dpi) * inchPrDp,
pxPerSp: float32(sdpi) * inchPrDp,
now: time.Now(),
},
sync: isSync,
})
+6 -7
View File
@@ -7,7 +7,6 @@ import (
"syscall/js"
"time"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -329,13 +328,13 @@ func (w *window) setTextInput(s key.TextInputState) {
func (w *window) draw(sync bool) {
width, height, scale, cfg := w.config()
if cfg == (ui.Config{}) {
if cfg == (Config{}) {
return
}
w.mu.Lock()
w.scale = float32(scale)
w.mu.Unlock()
cfg.Now = time.Now()
cfg.now = time.Now()
w.w.event(DrawEvent{
Size: image.Point{
X: width,
@@ -346,7 +345,7 @@ func (w *window) draw(sync bool) {
})
}
func (w *window) config() (int, int, float32, ui.Config) {
func (w *window) config() (int, int, float32, Config) {
rect := w.cnv.Call("getBoundingClientRect")
width, height := rect.Get("width").Float(), rect.Get("height").Float()
scale := w.window.Get("devicePixelRatio").Float()
@@ -359,9 +358,9 @@ func (w *window) config() (int, int, float32, ui.Config) {
w.cnv.Set("height", ih)
}
const ppdp = 96 * inchPrDp * monitorScale
return iw, ih, float32(scale), ui.Config{
PxPerDp: ppdp * float32(scale),
PxPerSp: ppdp * float32(scale),
return iw, ih, float32(scale), Config{
pxPerDp: ppdp * float32(scale),
pxPerSp: ppdp * float32(scale),
}
}
+7 -8
View File
@@ -19,7 +19,6 @@ import (
"time"
"unsafe"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -142,7 +141,7 @@ func (w *window) draw(sync bool) {
return
}
cfg := getConfig()
cfg.Now = time.Now()
cfg.now = time.Now()
w.setStage(StageRunning)
w.w.event(DrawEvent{
Size: image.Point{
@@ -154,15 +153,15 @@ func (w *window) draw(sync bool) {
})
}
func getConfig() ui.Config {
func getConfig() Config {
ppdp := float32(C.gio_getPixelsPerDP())
ppdp *= monitorScale
if ppdp < minDensity {
ppdp = minDensity
}
return ui.Config{
PxPerDp: ppdp,
PxPerSp: ppdp,
return Config{
pxPerDp: ppdp,
pxPerSp: ppdp,
}
}
@@ -216,8 +215,8 @@ func Main() {
}
cfg := getConfig()
opts := singleWindow.opts
w := cfg.Pixels(opts.Width)
h := cfg.Pixels(opts.Height)
w := cfg.Px(opts.Width)
h := cfg.Px(opts.Height)
title := C.CString(opts.Title)
defer C.free(unsafe.Pointer(title))
C.gio_main(view, title, C.CGFloat(w), C.CGFloat(h))
+8 -9
View File
@@ -19,7 +19,6 @@ import (
"unicode/utf8"
"unsafe"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -237,8 +236,8 @@ func createNativeWindow(opts *WindowOptions) (*window, error) {
C.free(unsafe.Pointer(title))
_, _, cfg := w.config()
w.width = cfg.Pixels(opts.Width)
w.height = cfg.Pixels(opts.Height)
w.width = cfg.Px(opts.Width)
w.height = cfg.Px(opts.Height)
if conn.decor != nil {
// Request server side decorations.
w.decor = C.zxdg_decoration_manager_v1_get_toplevel_decoration(conn.decor, w.topLvl)
@@ -1020,11 +1019,11 @@ func (w *window) updateOutputs() {
}
}
func (w *window) config() (int, int, ui.Config) {
func (w *window) config() (int, int, Config) {
width, height := w.width*w.scale, w.height*w.scale
return width, height, ui.Config{
PxPerDp: w.ppdp * float32(w.scale),
PxPerSp: w.ppsp * float32(w.scale),
return width, height, Config{
pxPerDp: w.ppdp * float32(w.scale),
pxPerSp: w.ppsp * float32(w.scale),
}
}
@@ -1036,7 +1035,7 @@ func (w *window) draw(sync bool) {
return
}
width, height, cfg := w.config()
if cfg == (ui.Config{}) {
if cfg == (Config{}) {
return
}
if animating && w.lastFrameCallback == nil {
@@ -1044,7 +1043,7 @@ func (w *window) draw(sync bool) {
// Use the surface as listener data for gio_onFrameDone.
C.gio_wl_callback_add_listener(w.lastFrameCallback, unsafe.Pointer(w.surf))
}
cfg.Now = time.Now()
cfg.now = time.Now()
w.w.event(DrawEvent{
Size: image.Point{
X: width,
+7 -8
View File
@@ -13,7 +13,6 @@ import (
syscall "golang.org/x/sys/windows"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -220,8 +219,8 @@ func createNativeWindow(opts *WindowOptions) (*window, error) {
}
defer unregisterClass(cls, hInst)
wr := rect{
right: int32(cfg.Pixels(opts.Width)),
bottom: int32(cfg.Pixels(opts.Height)),
right: int32(cfg.Px(opts.Width)),
bottom: int32(cfg.Px(opts.Height)),
}
dwStyle := uint32(_WS_OVERLAPPEDWINDOW)
dwExStyle := uint32(_WS_EX_APPWINDOW | _WS_EX_WINDOWEDGE)
@@ -419,7 +418,7 @@ func (w *window) draw(sync bool) {
w.width = int(r.right - r.left)
w.height = int(r.bottom - r.top)
cfg := configForDC(w.hdc)
cfg.Now = time.Now()
cfg.now = time.Now()
w.w.event(DrawEvent{
Size: image.Point{
X: w.width,
@@ -487,16 +486,16 @@ func convertKeyCode(code uintptr) (rune, bool) {
return r, true
}
func configForDC(hdc syscall.Handle) ui.Config {
func configForDC(hdc syscall.Handle) Config {
dpi := getDeviceCaps(hdc, _LOGPIXELSX)
ppdp := float32(dpi) * inchPrDp * monitorScale
// Force a minimum density to keep text legible and to handle bogus output geometry.
if ppdp < minDensity {
ppdp = minDensity
}
return ui.Config{
PxPerDp: ppdp,
PxPerSp: ppdp,
return Config{
pxPerDp: ppdp,
pxPerSp: ppdp,
}
}