You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.5 KiB
119 lines
2.5 KiB
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 |
|
}
|
|
|