Reimplement cursor as a query operation
This commit is contained in:
@@ -35,7 +35,7 @@ func main() {
|
|||||||
log.Fatalf("Couldn't load menu %s: %v", *menuName, err)
|
log.Fatalf("Couldn't load menu %s: %v", *menuName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
driver, err := ui.NewDriver(menu)
|
driver, err := ui.NewDriver(assets, menu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Couldn't initialize interface: %v", err)
|
log.Fatalf("Couldn't initialize interface: %v", err)
|
||||||
}
|
}
|
||||||
@@ -45,13 +45,6 @@ func main() {
|
|||||||
log.Fatal("Couldn't create window: %v", err)
|
log.Fatal("Couldn't create window: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this into driver. It will need to be able to change cursor.
|
|
||||||
cursor, err := assets.Cursor(assetstore.UltPointer)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Couldn't load cursor: %v", err)
|
|
||||||
}
|
|
||||||
win.SetCursor(cursor.Image)
|
|
||||||
|
|
||||||
if err := win.Run(); err != nil {
|
if err := win.Run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@@ -114,7 +114,7 @@ func buildDriver(assets *assetstore.AssetStore, name driverName) (*ui.Driver, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
driver, err := ui.NewDriver(menu)
|
driver, err := ui.NewDriver(assets, menu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -138,6 +138,10 @@ func (f *Flow) Draw(screen *ebiten.Image) error {
|
|||||||
return f.current.Draw(screen)
|
return f.current.Draw(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Flow) Cursor() (*ebiten.Image, *ebiten.DrawImageOptions, error) {
|
||||||
|
return f.current.Cursor()
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Flow) linkDrivers() {
|
func (f *Flow) linkDrivers() {
|
||||||
// linkMain
|
// linkMain
|
||||||
f.onClick(main, "2.1", f.setDriver(newGame)) // New game
|
f.onClick(main, "2.1", f.setDriver(newGame)) // New game
|
||||||
|
@@ -93,13 +93,6 @@ func Run(configFile string, overrideX, overrideY int) error {
|
|||||||
return fmt.Errorf("Failed to create window: %v", err)
|
return fmt.Errorf("Failed to create window: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this into driver. It will need to be able to change cursor.
|
|
||||||
cursor, err := assets.Cursor(assetstore.UltPointer)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Couldn't load cursor: %v", err)
|
|
||||||
}
|
|
||||||
win.SetCursor(cursor.Image)
|
|
||||||
|
|
||||||
ordoor.win = win
|
ordoor.win = win
|
||||||
|
|
||||||
if err := ordoor.setupFlow(); err != nil {
|
if err := ordoor.setupFlow(); err != nil {
|
||||||
@@ -212,3 +205,11 @@ func (o *Ordoor) Draw(screen *ebiten.Image) error {
|
|||||||
return fmt.Errorf("Unknown state: %v", o.state)
|
return fmt.Errorf("Unknown state: %v", o.state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Ordoor) Cursor() (*ebiten.Image, *ebiten.DrawImageOptions, error) {
|
||||||
|
if o.state == StateInterface {
|
||||||
|
return o.flow.Cursor()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
@@ -90,6 +90,7 @@ func registerBuilder(t menus.MenuType, f builderFunc) {
|
|||||||
type Driver struct {
|
type Driver struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
assets *assetstore.AssetStore
|
||||||
menu *assetstore.Menu
|
menu *assetstore.Menu
|
||||||
|
|
||||||
// UI elements we need to drive
|
// UI elements we need to drive
|
||||||
@@ -100,6 +101,8 @@ type Driver struct {
|
|||||||
paintables []paintable
|
paintables []paintable
|
||||||
valueables []valueable
|
valueables []valueable
|
||||||
|
|
||||||
|
cursor assetstore.CursorName
|
||||||
|
|
||||||
// The cursor in two different coordinate spaces: original, and screen-scaled
|
// The cursor in two different coordinate spaces: original, and screen-scaled
|
||||||
cursorOrig image.Point
|
cursorOrig image.Point
|
||||||
cursorScaled image.Point
|
cursorScaled image.Point
|
||||||
@@ -112,9 +115,11 @@ type Driver struct {
|
|||||||
tooltip string
|
tooltip string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDriver(menu *assetstore.Menu) (*Driver, error) {
|
func NewDriver(assets *assetstore.AssetStore, menu *assetstore.Menu) (*Driver, error) {
|
||||||
driver := &Driver{
|
driver := &Driver{
|
||||||
Name: menu.Name,
|
Name: menu.Name,
|
||||||
|
|
||||||
|
assets: assets,
|
||||||
menu: menu,
|
menu: menu,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +312,20 @@ func (d *Driver) Draw(screen *ebiten.Image) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Driver) Cursor() (*ebiten.Image, *ebiten.DrawImageOptions, error) {
|
||||||
|
cursor, err := d.assets.Cursor(d.cursor)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Translate(float64(d.cursorOrig.X), float64(d.cursorOrig.Y))
|
||||||
|
op.GeoM.Concat(d.orig2native)
|
||||||
|
op.GeoM.Translate(float64(-cursor.Hotspot.X), float64(-cursor.Hotspot.Y))
|
||||||
|
|
||||||
|
return cursor.Image, op, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Driver) addRecord(record *menus.Record) error {
|
func (d *Driver) addRecord(record *menus.Record) error {
|
||||||
//log.Printf("Adding record: %#+v", record)
|
//log.Printf("Adding record: %#+v", record)
|
||||||
children := record.Children
|
children := record.Children
|
||||||
|
@@ -3,7 +3,6 @@ package ui
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
@@ -19,6 +18,11 @@ type Game interface {
|
|||||||
Draw(*ebiten.Image) error
|
Draw(*ebiten.Image) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CustomCursor interface {
|
||||||
|
// The cursor draw operation
|
||||||
|
Cursor() (*ebiten.Image, *ebiten.DrawImageOptions, error)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
screenScale = flag.Float64("screen-scale", 1.0, "Scale the window by this factor")
|
screenScale = flag.Float64("screen-scale", 1.0, "Scale the window by this factor")
|
||||||
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
||||||
@@ -32,8 +36,6 @@ type Window struct {
|
|||||||
KeyUpHandlers map[ebiten.Key]func()
|
KeyUpHandlers map[ebiten.Key]func()
|
||||||
MouseWheelHandler func(float64, float64)
|
MouseWheelHandler func(float64, float64)
|
||||||
|
|
||||||
cursor *ebiten.Image
|
|
||||||
|
|
||||||
// Allow the "game" to be switched out at any time
|
// Allow the "game" to be switched out at any time
|
||||||
game Game
|
game Game
|
||||||
|
|
||||||
@@ -74,15 +76,26 @@ func (w *Window) Layout(_, _ int) (int, int) {
|
|||||||
return w.xRes, w.yRes
|
return w.xRes, w.yRes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) SetCursor(cursor *ebiten.Image) {
|
func (w *Window) drawCursor(screen *ebiten.Image) error {
|
||||||
w.cursor = cursor
|
cIface, ok := w.game.(CustomCursor)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor, op, err := cIface.Cursor()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Hide the system cursor if we have a custom one
|
// Hide the system cursor if we have a custom one
|
||||||
if cursor == nil {
|
if cursor == nil {
|
||||||
ebiten.SetCursorMode(ebiten.CursorModeVisible)
|
ebiten.SetCursorMode(ebiten.CursorModeVisible)
|
||||||
} else {
|
return nil
|
||||||
ebiten.SetCursorMode(ebiten.CursorModeHidden)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ebiten.SetCursorMode(ebiten.CursorModeHidden)
|
||||||
|
|
||||||
|
return screen.DrawImage(cursor, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) Update(screen *ebiten.Image) (outErr error) {
|
func (w *Window) Update(screen *ebiten.Image) (outErr error) {
|
||||||
@@ -125,23 +138,14 @@ func (w *Window) Update(screen *ebiten.Image) (outErr error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.cursor != nil {
|
|
||||||
// TODO: account for scaling, including the hotspot.
|
|
||||||
pos := image.Pt(ebiten.CursorPosition())
|
|
||||||
op := ebiten.DrawImageOptions{}
|
|
||||||
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
|
||||||
if err := screen.DrawImage(w.cursor, &op); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if w.debug {
|
if w.debug {
|
||||||
// Draw FPS, etc, to the screen
|
// Draw FPS, etc, to the screen
|
||||||
msg := fmt.Sprintf("tps=%0.2f fps=%0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS())
|
msg := fmt.Sprintf("tps=%0.2f fps=%0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS())
|
||||||
ebitenutil.DebugPrint(screen, msg)
|
ebitenutil.DebugPrint(screen, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Draw the cursor last
|
||||||
|
return w.drawCursor(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: a stop or other cancellation mechanism
|
// TODO: a stop or other cancellation mechanism
|
||||||
|
Reference in New Issue
Block a user