Go Gio 实战:煮蛋计时器的实现 02— 如何控制窗口

共 2818字,需浏览 6分钟

 ·

2021-10-28 19:18

上篇文章介绍了空窗口的实现。今天看看如何控制窗口,比如标题、大小等。

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 小结

本节介绍了如何控制窗口相关属性。大家可以各个属性都试试,看看效果。




往期推荐


我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。


坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎关注「polarisxu」一起成长!也欢迎加我微信好友交流:gopherstudio


浏览 46
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报