Add Gio app shells and platform stubs (T-003)
This commit is contained in:
@@ -1,11 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"gioui.org/app"
|
||||
"gioui.org/op"
|
||||
"gioui.org/unit"
|
||||
|
||||
"softbox.local/app-win7/platform/windows"
|
||||
softboxgio "softbox.local/app-win7/ui/gio"
|
||||
"softbox.local/core"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(core.ProductName)
|
||||
go func() {
|
||||
if err := run(); err != nil {
|
||||
log.Printf("%s Legacy stopped: %v", core.ProductName, err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
app.Main()
|
||||
}
|
||||
|
||||
func run() error {
|
||||
platform := windows.New()
|
||||
window := new(app.Window)
|
||||
window.Option(
|
||||
app.Title(core.ProductName+" Legacy"),
|
||||
app.Size(unit.Dp(1024), unit.Dp(680)),
|
||||
)
|
||||
|
||||
theme := softboxgio.NewTheme()
|
||||
shell := softboxgio.NewAppShell(string(platform.Edition()))
|
||||
var operations op.Ops
|
||||
|
||||
for {
|
||||
switch event := window.Event().(type) {
|
||||
case app.DestroyEvent:
|
||||
return event.Err
|
||||
case app.FrameEvent:
|
||||
context := app.NewContext(&operations, event)
|
||||
shell.Layout(context, theme)
|
||||
event.Frame(context.Ops)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
gioui.org v0.6.0 h1:ZSXO/AbpFZJ2L9NU69uFQfDI3BKIH+YEJElrn0B+aZI=
|
||||
gioui.org v0.6.0/go.mod h1:eUvGo6FAzA7jUqeSu5a+M1W03yc9r1nanIBS8A5+Nng=
|
||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc=
|
||||
gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA=
|
||||
github.com/go-text/typesetting v0.1.1 h1:bGAesCuo85nXnEN5LmFMVGAGpGkCPtHrZLi//qD7EJo=
|
||||
golang.org/x/exp v0.0.0-20221012211006-4de253d81b95 h1:sBdrWpxhGDdTAYNqbgBLAR+ULAPPhfgncLr1X0lyWtg=
|
||||
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91 h1:ryT6Nf0R83ZgD8WnFFdfI8wCeyqgdXWN4+CkFVNPAT0=
|
||||
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
// Package windows contains Win7-compatible Windows platform adapters.
|
||||
// Package windows provides Win7-compatible platform adapters and non-Windows
|
||||
// stubs for package-level tests.
|
||||
package windows
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package windows
|
||||
|
||||
// Edition identifies the application build channel shown by the UI.
|
||||
type Edition string
|
||||
|
||||
const EditionLegacy Edition = "Legacy"
|
||||
|
||||
// Platform is the minimal boundary for target-specific capabilities.
|
||||
type Platform interface {
|
||||
OS() string
|
||||
Edition() Edition
|
||||
}
|
||||
|
||||
// New returns the platform implementation selected by build tags.
|
||||
func New() Platform {
|
||||
return newPlatform()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//go:build !windows
|
||||
|
||||
package windows
|
||||
|
||||
import "runtime"
|
||||
|
||||
type platformStub struct{}
|
||||
|
||||
func newPlatform() Platform {
|
||||
return platformStub{}
|
||||
}
|
||||
|
||||
func (platformStub) OS() string {
|
||||
return runtime.GOOS
|
||||
}
|
||||
|
||||
func (platformStub) Edition() Edition {
|
||||
return EditionLegacy
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package windows
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPlatformStubContract(t *testing.T) {
|
||||
platform := New()
|
||||
if platform.OS() == "" {
|
||||
t.Fatal("OS() should not be empty")
|
||||
}
|
||||
if platform.Edition() != EditionLegacy {
|
||||
t.Fatalf("Edition() = %q, want %q", platform.Edition(), EditionLegacy)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//go:build windows
|
||||
|
||||
package windows
|
||||
|
||||
type platform struct{}
|
||||
|
||||
func newPlatform() Platform {
|
||||
return platform{}
|
||||
}
|
||||
|
||||
func (platform) OS() string {
|
||||
return "windows"
|
||||
}
|
||||
|
||||
func (platform) Edition() Edition {
|
||||
return EditionLegacy
|
||||
}
|
||||
@@ -1,2 +1,5 @@
|
||||
// Package gio contains the Win7-compatible Gio UI adapter.
|
||||
//
|
||||
// Layout code is rendering-only: it must not read files, access the network,
|
||||
// calculate hashes, or directly mutate background application state.
|
||||
package gio
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package gio
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget/material"
|
||||
)
|
||||
|
||||
var shellColors = struct {
|
||||
background color.NRGBA
|
||||
foreground color.NRGBA
|
||||
primary color.NRGBA
|
||||
onPrimary color.NRGBA
|
||||
secondary color.NRGBA
|
||||
}{
|
||||
background: color.NRGBA{R: 248, G: 250, B: 252, A: 255},
|
||||
foreground: color.NRGBA{R: 15, G: 23, B: 42, A: 255},
|
||||
primary: color.NRGBA{R: 13, G: 148, B: 136, A: 255},
|
||||
onPrimary: color.NRGBA{R: 255, G: 255, B: 255, A: 255},
|
||||
secondary: color.NRGBA{R: 71, G: 85, B: 105, A: 255},
|
||||
}
|
||||
|
||||
// AppShell is the Legacy window frame. Feature views are added in later tasks.
|
||||
type AppShell struct {
|
||||
edition string
|
||||
}
|
||||
|
||||
// NewAppShell creates an empty shell for the supplied build edition.
|
||||
func NewAppShell(edition string) *AppShell {
|
||||
return &AppShell{edition: edition}
|
||||
}
|
||||
|
||||
// NewTheme creates the semantic palette shared by the Legacy shell.
|
||||
func NewTheme() *material.Theme {
|
||||
theme := material.NewTheme()
|
||||
theme.Palette = material.Palette{
|
||||
Bg: shellColors.background,
|
||||
Fg: shellColors.foreground,
|
||||
ContrastBg: shellColors.primary,
|
||||
ContrastFg: shellColors.onPrimary,
|
||||
}
|
||||
theme.FingerSize = unit.Dp(44)
|
||||
return theme
|
||||
}
|
||||
|
||||
// Layout renders the shell without performing IO or submitting use cases.
|
||||
func (shell *AppShell) Layout(context layout.Context, theme *material.Theme) layout.Dimensions {
|
||||
paint.Fill(context.Ops, theme.Bg)
|
||||
|
||||
return layout.UniformInset(unit.Dp(32)).Layout(context, func(context layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(
|
||||
context,
|
||||
layout.Rigid(func(context layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Alignment: layout.Middle}.Layout(
|
||||
context,
|
||||
layout.Rigid(material.H5(theme, "SoftBox").Layout),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(16)}.Layout),
|
||||
layout.Rigid(func(context layout.Context) layout.Dimensions {
|
||||
label := material.Body2(theme, shell.edition)
|
||||
label.Color = shellColors.primary
|
||||
return label.Layout(context)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(24)}.Layout),
|
||||
layout.Flexed(1, func(context layout.Context) layout.Dimensions {
|
||||
return layout.Center.Layout(context, func(context layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical, Alignment: layout.Middle}.Layout(
|
||||
context,
|
||||
layout.Rigid(material.H6(theme, "软件目录准备中").Layout),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||
layout.Rigid(func(context layout.Context) layout.Dimensions {
|
||||
label := material.Body1(theme, "Legacy 窗口已就绪,业务功能将在后续任务接入。")
|
||||
label.Color = shellColors.secondary
|
||||
return label.Layout(context)
|
||||
}),
|
||||
)
|
||||
})
|
||||
}),
|
||||
layout.Rigid(func(context layout.Context) layout.Dimensions {
|
||||
label := material.Body2(theme, "Legacy · Windows 7 SP1 x64")
|
||||
label.Color = shellColors.secondary
|
||||
return label.Layout(context)
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package gio
|
||||
|
||||
import (
|
||||
"image"
|
||||
"testing"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/unit"
|
||||
)
|
||||
|
||||
func TestAppShellFillsWindow(t *testing.T) {
|
||||
var operations op.Ops
|
||||
size := image.Pt(1024, 680)
|
||||
context := layout.Context{
|
||||
Ops: &operations,
|
||||
Metric: unit.Metric{PxPerDp: 1, PxPerSp: 1},
|
||||
Constraints: layout.Exact(size),
|
||||
}
|
||||
|
||||
dimensions := NewAppShell("Legacy").Layout(context, NewTheme())
|
||||
if dimensions.Size != size {
|
||||
t.Fatalf("Layout() size = %v, want %v", dimensions.Size, size)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user