Go Gio 實戰:煮蛋計時器的實現 02— 如何控制窗口

大家好,我是程序員幽鬼。

上篇文章介紹了空窗口的實現。今天看看如何控制窗口,比如標題、大小等。

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 等開發的應該很熟悉)

XAFm1P

一般來說,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 小結

本節介紹瞭如何控制窗口相關屬性。大家可以各個屬性都試試,看看效果。


歡迎關注「幽鬼」,像她一樣做團隊的核心。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/_WSjprf4P443AyT5tqZAZQ