You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.5 KiB
Go
120 lines
2.5 KiB
Go
package etk
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"math"
|
|
|
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
)
|
|
|
|
var root Widget
|
|
|
|
var (
|
|
lastWidth, lastHeight int
|
|
|
|
lastX, lastY = -math.MaxInt, -math.MaxInt
|
|
)
|
|
|
|
func SetRoot(w Widget) {
|
|
root = w
|
|
}
|
|
|
|
func Layout(outsideWidth, outsideHeight int) {
|
|
if root == nil {
|
|
panic("no root widget specified")
|
|
}
|
|
|
|
if outsideWidth != lastWidth || outsideHeight != lastHeight {
|
|
root.SetRect(image.Rect(0, 0, outsideWidth, outsideHeight))
|
|
lastWidth, lastHeight = outsideWidth, outsideHeight
|
|
}
|
|
}
|
|
|
|
func Update() error {
|
|
if root == nil {
|
|
panic("no root widget specified")
|
|
}
|
|
|
|
x, y := ebiten.CursorPosition()
|
|
cursor := image.Point{x, y}
|
|
|
|
if lastX == -math.MaxInt && lastY == -math.MaxInt {
|
|
lastX, lastY = x, y
|
|
}
|
|
|
|
// TODO handle touch input
|
|
|
|
var pressed bool
|
|
for _, binding := range Bindings.ConfirmMouse {
|
|
pressed = ebiten.IsMouseButtonPressed(binding)
|
|
if pressed {
|
|
break
|
|
}
|
|
}
|
|
|
|
var clicked bool
|
|
for _, binding := range Bindings.ConfirmMouse {
|
|
clicked = inpututil.IsMouseButtonJustReleased(binding)
|
|
if clicked {
|
|
break
|
|
}
|
|
}
|
|
|
|
_, _, err := update(root, cursor, pressed, clicked, false, false)
|
|
return err
|
|
}
|
|
|
|
func update(w Widget, cursor image.Point, pressed bool, clicked bool, mouseHandled bool, keyboardHandled bool) (bool, bool, error) {
|
|
var err error
|
|
children := w.Children()
|
|
for _, child := range children {
|
|
mouseHandled, keyboardHandled, err = update(child, cursor, pressed, clicked, mouseHandled, keyboardHandled)
|
|
if err != nil {
|
|
return false, false, err
|
|
} else if mouseHandled && keyboardHandled {
|
|
return true, true, nil
|
|
}
|
|
}
|
|
if !mouseHandled && cursor.In(w.Rect()) {
|
|
_, err = w.HandleMouse(cursor, pressed, clicked)
|
|
if err != nil {
|
|
return false, false, fmt.Errorf("failed to handle widget mouse input: %s", err)
|
|
}
|
|
}
|
|
if !keyboardHandled {
|
|
_, err = w.HandleKeyboard()
|
|
if err != nil {
|
|
return false, false, fmt.Errorf("failed to handle widget keyboard input: %s", err)
|
|
}
|
|
}
|
|
return mouseHandled, keyboardHandled, nil
|
|
}
|
|
|
|
func Draw(screen *ebiten.Image) error {
|
|
if root == nil {
|
|
panic("no root widget specified")
|
|
}
|
|
|
|
return draw(root, screen)
|
|
}
|
|
|
|
func draw(w Widget, screen *ebiten.Image) error {
|
|
err := w.Draw(screen)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to draw widget: %s", err)
|
|
}
|
|
|
|
children := w.Children()
|
|
for _, child := range children {
|
|
err = draw(child, screen)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to draw widget: %s", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|