// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build example // // This build tag means that "go install golang.org/x/exp/shiny/..." doesn't // install this example program. Use "go run main.go board.go xy.go" to run it // or "go install -tags=example" to install it. // Goban is a simple example of a graphics program using shiny. // It implements a Go board that two people can use to play the game. // TODO: Improve the main function. // TODO: Provide more functionality. package main import ( "flag" "image" "log" "math/rand" "time" "golang.org/x/exp/shiny/driver" "golang.org/x/exp/shiny/screen" "golang.org/x/mobile/event/key" "golang.org/x/mobile/event/lifecycle" "golang.org/x/mobile/event/mouse" "golang.org/x/mobile/event/paint" "golang.org/x/mobile/event/size" ) var scale = flag.Int("scale", 35, "`percent` to scale images (TODO: a poor design)") func main() { flag.Parse() rand.Seed(int64(time.Now().Nanosecond())) board := NewBoard(9, *scale) driver.Main(func(s screen.Screen) { w, err := s.NewWindow(&screen.NewWindowOptions{ Title: "Goban Shiny Example", }) if err != nil { log.Fatal(err) } defer w.Release() var b screen.Buffer defer func() { if b != nil { b.Release() } }() for { switch e := w.NextEvent().(type) { case lifecycle.Event: if e.To == lifecycle.StageDead { return } case key.Event: if e.Code == key.CodeEscape { return } case mouse.Event: if e.Direction != mouse.DirRelease { break } // Re-map control-click to middle-click, etc, for computers with one-button mice. if e.Modifiers&key.ModControl != 0 { e.Button = mouse.ButtonMiddle } else if e.Modifiers&key.ModAlt != 0 { e.Button = mouse.ButtonRight } else if e.Modifiers&key.ModMeta != 0 { e.Button = mouse.ButtonMiddle } if board.click(b.RGBA(), int(e.X), int(e.Y), int(e.Button)) { w.Send(paint.Event{}) } case paint.Event: w.Upload(image.Point{}, b, b.Bounds()) w.Publish() case size.Event: // TODO: Set board size. if b != nil { b.Release() } b, err = s.NewBuffer(e.Size()) if err != nil { log.Fatal(err) } render(b.RGBA(), board) case error: log.Print(e) } } }) } func render(m *image.RGBA, board *Board) { board.Draw(m) }