Go Gio 实战:煮蛋计时器的实现 02— 如何控制窗口
共 2735字,需浏览 6分钟
·
2021-11-09 18:15
上篇文章介绍了空窗口的实现。今天看看如何控制窗口,比如标题、大小等。
01 目标
本节的目标是设置窗口标题并控制窗口的大小。效果如下:
02 代码
基于上一节的代码补充,因为事件循环部分可能 panic,这里在上节最后部分提到的代码基础上补充。
package main
import (
"gioui.org/app"
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op"
)
func main() {
go func() {
w := app.NewWindow(
app.Title("Egg timer"), // 设置标题
app.Size(unit.Dp(400), unit.Dp(600)), // 控制大小
)
var ops op.Ops
for e := range w.Events() {
switch e := e.(type) {
case system.FrameEvent:
gtx := layout.NewContext(&ops, e)
e.Frame(gtx.Ops)
}
}
}()
app.Main()
}
03 代码详解
gioui.org/unit 实现了与设备无关的单位和值。文档描述了各种单位:(做过 Android 等开发的应该很熟悉)
类型 | 描述 |
---|---|
dp | 设备独立像素 - 独立于底层设备。 |
sp | 缩放像素 - 用于文本大小 |
px | 像素 - 用于实际设备的精度 |
一般来说,dp
是最常用的。它可以做到尽可能保持设备独立性。所以,以上代码,我们在控制窗口大小时,使用了这个单位。
上一节,app.NewWindows()
我们没有传递任何参数,现在传递了。这表明,该函数接收可选参数:
func NewWindow(options ...Option) *Window
这是 Go 中常用的一种模式:通过一个类型去控制另一个类型的不同表现,很多库都有类似的做法,比如 Go 的爬虫库 go-colly。
就 Gio 而言,Option 实际上是一个函数类型:
type Option func(unit.Metric, *Config)
然后,Gio 提供了各种函数,返回一个 Option 的实例,这些实例直接可以作为参数传递给 app.NewWindow
函数。
以下是返回 Option 的相关函数:
func CustomRenderer(custom bool) Option
func MaxSize(w, h unit.Value) Option
func MinSize(w, h unit.Value) Option
func NavigationColor(color color.NRGBA) Option
func Size(w, h unit.Value) Option
func StatusColor(color color.NRGBA) Option
func Title(t string) Option
从名称可以大概知晓干什么用的。
了解了上面的知识点,现在稍微解释下设置窗口标题和大小的相关代码:
1)app.Size(x, y)
设置窗口大小,其中 x、y 的类型是 unit.Value,它是一个结构体,函数 unit.Dp
返回一个 unit.Value
:
// Value is a value with a unit.
type Value struct {
V float32
U Unit
}
// Dp returns the Value for v device independent pixels.
func Dp(v float32) Value
2)用户通过鼠标可以自由调整窗口的大小。如果你喜欢,可以限制窗口的最大、最小尺寸(上面获得 Option 类型的函数有),这样用户就不能随意拖放他想的大小。
我们还可以通过 NavigationColor 和 StatusColor 控制导航和状态栏的颜色(Android 开发可能有用)。
3)其他选项
除了上面列出的 Option,还有两个实现方式不太一样的 Option:
控制屏幕方向,主要用于手机,比如横屏、竖屏:
type Orientation uint8
const (
// AnyOrientation allows the window to be freely orientated.
AnyOrientation Orientation = iota
// LandscapeOrientation constrains the window to landscape orientations.
LandscapeOrientation
// PortraitOrientation constrains the window to portrait orientations.
PortraitOrientation
)
func (o Orientation) Option() Option
使用时类似这样:
app.NewWindow(LandscapeOrientation.Option())
控制全屏显示:
type WindowMode uint8
const (
// Windowed is the normal window mode with OS specific window decorations.
Windowed WindowMode = iota
// Fullscreen is the full screen window mode.
Fullscreen
)
func (m WindowMode) Option() Option
使用时类似这样:
app.NewWindow(Fullscreen.Option())
04 小结
本节介绍了如何控制窗口相关属性。大家可以各个属性都试试,看看效果。
推荐阅读