func main() { flag.Parse() rand.Seed(int64(time.Now().Nanosecond())) board := NewBoard(9, *scale) driver.Main(func(s screen.Screen) { w, err := s.NewWindow(nil) 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 && e.Button != 0 { 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 main() { log.SetFlags(0) log.SetPrefix("preview: ") flag.Usage = func() { log.Print("Usage: preview [options] file") flag.PrintDefaults() } flag.Parse() if flag.NArg() != 1 { flag.Usage() os.Exit(1) } if *prof != "" { log.Print("profile mode: will write out CPU profile after 5 seconds") f, err := os.Create(*prof) if err != nil { log.Fatal(err) } err = pprof.StartCPUProfile(f) if err != nil { log.Fatal(err) } go func() { time.Sleep(5 * time.Second) pprof.StopCPUProfile() log.Print("done writing CPU profile") }() } f, err := os.Open(flag.Arg(0)) if err != nil { log.Fatal(err) } log.Print("parsing STL...") t := time.Now() stl, err := slice.Parse(f) if err != nil { log.Fatal(err) } f.Close() log.Printf("parsing took %v", time.Now().Sub(t)) if err := sliceSTL(stl); err != nil { log.Fatal(err) } imgs, err := drawLayers(stl) if err != nil { log.Fatal(err) } r := imgs[0].Bounds() log.Print("Launching UI...") driver.Main(func(s screen.Screen) { w, err := s.NewWindow(&screen.NewWindowOptions{ Width: r.Dx(), Height: r.Dy(), }) if err != nil { log.Fatal(err) } defer w.Release() r := image.Rect(int(stl.Min.X), int(stl.Min.Y), int(stl.Max.X)+1, int(stl.Max.Y)+1) winSize := r.Size() var b screen.Buffer defer func() { if b != nil { b.Release() } }() var sz size.Event var lastClick mouse.Event var layer int redraw := func() { draw.Draw(b.RGBA(), b.RGBA().Bounds(), imgs[layer], imgs[layer].Bounds().Min, draw.Src) drawLayerNumber(b.RGBA(), layer) w.Send(paint.Event{}) } for e := range w.Events() { switch e := e.(type) { default: case mouse.Event: if e.Button == mouse.ButtonLeft { if e.Y > lastClick.Y && layer < len(imgs)-1 { layer++ redraw() } else if e.Y < lastClick.Y && layer > 0 { layer-- redraw() } lastClick = e } case key.Event: log.Printf("key: %v", e) if e.Code == key.CodeEscape { log.Print("quitting") return } case paint.Event: w.Upload(image.Point{}, b, b.Bounds(), w) w.Publish() case screen.UploadedEvent: // No-op. case size.Event: sz = e if b != nil { b.Release() } winSize = image.Point{sz.WidthPx, sz.HeightPx} b, err = s.NewBuffer(winSize) if err != nil { log.Fatal(err) } redraw() case error: log.Printf("error: %v", e) } } }) }
func main() { flag.Parse() rand.Seed(int64(time.Now().Nanosecond())) board := NewBoard(9, *scale) driver.Main(func(s screen.Screen) { w, err := s.NewWindow(nil) if err != nil { log.Fatal(err) } defer w.Release() var b screen.Buffer defer func() { if b != nil { b.Release() } }() for e := range w.Events() { switch e := e.(type) { case mouse.Event: if e.Direction == mouse.DirRelease && e.Button != 0 { board.click(b.RGBA(), int(e.X), int(e.Y), int(e.Button)) dirty = true } case key.Event: if e.Code == key.CodeEscape { return } case paint.Event: // TODO: we shouldn't rely on the library sending us a constant // stream of paint events. If we're dirty, we should just draw // on the window and then call w.Publish. // // TODO: This check should save CPU time but causes flicker on Darwin. //if dirty && !uploading { w.Upload(image.Point{}, b, b.Bounds(), w) // TODO: On Darwin always writes to 0,0, ignoring first arg. dirty = false uploading = true //} w.Publish() case screen.UploadedEvent: // No-op. uploading = false 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) } } }) }