Files
ordoor/internal/ui/window.go

96 lines
2.0 KiB
Go
Raw Normal View History

package ui
import (
"flag"
2019-12-29 20:34:05 +00:00
"fmt"
2019-12-29 15:38:49 +00:00
"github.com/hajimehoshi/ebiten"
2019-12-29 20:34:05 +00:00
"github.com/hajimehoshi/ebiten/ebitenutil"
2019-12-29 17:30:21 +00:00
"github.com/hajimehoshi/ebiten/inpututil"
)
var (
winX = flag.Int("win-x", 1280, "width of the view-map window")
winY = flag.Int("win-y", 1024, "height of the view-map window")
)
type Window struct {
2019-12-29 17:30:21 +00:00
Title string
KeyUpHandlers map[ebiten.Key]func()
MouseWheelHandler func(float64, float64)
2019-12-29 15:38:49 +00:00
// User-provided update actions
updateFn func() error
drawFn func(*ebiten.Image) error
2019-12-29 20:34:05 +00:00
debug bool
}
2019-12-29 15:38:49 +00:00
// 0,0 is the *top left* of the window
//
2019-12-29 15:38:49 +00:00
// ebiten assumes a single window, so only call this once...
func NewWindow(title string) (*Window, error) {
2019-12-29 19:41:20 +00:00
ebiten.SetRunnableInBackground(true)
2019-12-29 15:38:49 +00:00
return &Window{
2019-12-29 17:30:21 +00:00
Title: title,
KeyUpHandlers: make(map[ebiten.Key]func()),
2019-12-29 20:34:05 +00:00
debug: true,
2019-12-29 15:38:49 +00:00
}, nil
}
2019-12-29 17:30:21 +00:00
// TODO: multiple handlers for the same key?
2019-12-29 15:38:49 +00:00
func (w *Window) OnKeyUp(key ebiten.Key, f func()) {
2019-12-29 17:30:21 +00:00
w.KeyUpHandlers[key] = f
}
2019-12-29 15:38:49 +00:00
2019-12-29 17:30:21 +00:00
func (w *Window) OnMouseWheel(f func(x, y float64)) {
w.MouseWheelHandler = f
2019-12-29 15:38:49 +00:00
}
func (w *Window) run(screen *ebiten.Image) error {
if err := w.updateFn(); err != nil {
return err
}
2019-12-29 15:38:49 +00:00
// Process keys
2019-12-29 17:30:21 +00:00
// TODO: efficient set operations
for key, cb := range w.KeyUpHandlers {
if inpututil.IsKeyJustReleased(key) {
cb()
}
}
if w.MouseWheelHandler != nil {
x, y := ebiten.Wheel()
if x != 0 || y != 0 {
w.MouseWheelHandler(x, y)
}
}
2019-12-29 15:38:49 +00:00
if !ebiten.IsDrawingSkipped() {
if err := w.drawFn(screen); err != nil {
return err
}
2019-12-29 20:34:05 +00:00
if w.debug {
// Draw FPS, etc, to the screen
msg := fmt.Sprintf("tps=%0.2f fps=%0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS())
ebitenutil.DebugPrint(screen, msg)
}
}
2019-12-29 15:38:49 +00:00
return nil
}
// TODO: a stop or other cancellation mechanism
2019-12-29 15:38:49 +00:00
//
// Note that this must be called on the main OS thread
func (w *Window) Run(updateFn func() error, drawFn func(*ebiten.Image) error) error {
w.updateFn = updateFn
w.drawFn = drawFn
return ebiten.Run(w.run, *winX, *winY, 1, w.Title)
}