// Command gio-spike validates a Gio window for the V2 UI, bypassing the Walk // TTM_ADDTOOL startup failure (Gio uses no Win32 common controls, so the // manifest/comctl issue cannot occur). It shows a synthetic RGBA frame — the // same *image.RGBA type internal/render produces — a top dual-tab bar and a // start/stop button, then closes cleanly. // // Run on Windows: go run ./cmd/gio-spike package main import ( "image" "image/color" "log" "os" "gioui.org/app" "gioui.org/font/gofont" "gioui.org/layout" "gioui.org/op" "gioui.org/op/paint" "gioui.org/text" "gioui.org/unit" "gioui.org/widget" "gioui.org/widget/material" ) func main() { go func() { w := new(app.Window) w.Option( app.Title("Silver Pose V2 · Gio Spike"), app.Size(unit.Dp(960), unit.Dp(600)), ) if err := loop(w); err != nil { log.Fatal(err) } os.Exit(0) }() app.Main() } type spikeUI struct { theme *material.Theme frame paint.ImageOp tabs []string tabButton []widget.Clickable active int startStop widget.Clickable running bool } func newSpikeUI() *spikeUI { theme := material.NewTheme() theme.Shaper = text.NewShaper(text.WithCollection(gofont.Collection())) ui := &spikeUI{ theme: theme, frame: paint.NewImageOp(syntheticFrame(640, 360)), tabs: []string{"实时监控", "设置"}, } ui.tabButton = make([]widget.Clickable, len(ui.tabs)) return ui } func loop(w *app.Window) error { ui := newSpikeUI() var ops op.Ops for { switch e := w.Event().(type) { case app.DestroyEvent: return e.Err case app.FrameEvent: gtx := app.NewContext(&ops, e) ui.layout(gtx) e.Frame(gtx.Ops) } } } func (ui *spikeUI) layout(gtx layout.Context) layout.Dimensions { paint.Fill(gtx.Ops, color.NRGBA{R: 0xEA, G: 0xF1, B: 0xF8, A: 0xFF}) return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(ui.layoutTabs), layout.Flexed(1, ui.layoutBody), layout.Rigid(ui.layoutControls), ) } func (ui *spikeUI) layoutTabs(gtx layout.Context) layout.Dimensions { for i := range ui.tabButton { if ui.tabButton[i].Clicked(gtx) { ui.active = i } } children := make([]layout.FlexChild, 0, len(ui.tabs)) for i := range ui.tabs { i := i children = append(children, layout.Rigid(func(gtx layout.Context) layout.Dimensions { button := material.Button(ui.theme, &ui.tabButton[i], ui.tabs[i]) if i != ui.active { button.Background = color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF} button.Color = color.NRGBA{R: 0x52, G: 0x65, B: 0x7C, A: 0xFF} } return layout.UniformInset(unit.Dp(6)).Layout(gtx, button.Layout) })) } return layout.Flex{}.Layout(gtx, children...) } func (ui *spikeUI) layoutBody(gtx layout.Context) layout.Dimensions { if ui.active == 0 { return layout.UniformInset(unit.Dp(8)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { return widget.Image{ Src: ui.frame, Fit: widget.Contain, Position: layout.Center, }.Layout(gtx) }) } return layout.Center.Layout(gtx, material.Body1(ui.theme, "设置页占位(spike)").Layout) } func (ui *spikeUI) layoutControls(gtx layout.Context) layout.Dimensions { if ui.startStop.Clicked(gtx) { ui.running = !ui.running } label := "开始监控" if ui.running { label = "停止监控" } return layout.UniformInset(unit.Dp(8)).Layout(gtx, material.Button(ui.theme, &ui.startStop, label).Layout) } // syntheticFrame stands in for internal/render's *image.RGBA output: a gradient // with a 6px red border, mimicking a CONFIRMED overlay, to prove image display. func syntheticFrame(width, height int) *image.RGBA { img := image.NewRGBA(image.Rect(0, 0, width, height)) for y := 0; y < height; y++ { for x := 0; x < width; x++ { img.SetRGBA(x, y, color.RGBA{ R: uint8(x * 255 / width), G: uint8(y * 255 / height), B: 90, A: 255, }) } } red := color.RGBA{R: 198, G: 40, B: 40, A: 255} for t := 0; t < 6; t++ { for x := 0; x < width; x++ { img.SetRGBA(x, t, red) img.SetRGBA(x, height-1-t, red) } for y := 0; y < height; y++ { img.SetRGBA(t, y, red) img.SetRGBA(width-1-t, y, red) } } return img }