...

Source file src/code.rocketnine.space/tslocum/etk/game.go

Documentation: code.rocketnine.space/tslocum/etk

     1  package etk
     2  
     3  import (
     4  	"fmt"
     5  	"image"
     6  	"math"
     7  
     8  	"github.com/hajimehoshi/ebiten/v2/inpututil"
     9  
    10  	"github.com/hajimehoshi/ebiten/v2"
    11  )
    12  
    13  var root Widget
    14  
    15  var (
    16  	lastWidth, lastHeight int
    17  
    18  	lastX, lastY = -math.MaxInt, -math.MaxInt
    19  )
    20  
    21  func SetRoot(w Widget) {
    22  	root = w
    23  }
    24  
    25  func Layout(outsideWidth, outsideHeight int) {
    26  	if root == nil {
    27  		panic("no root widget specified")
    28  	}
    29  
    30  	if outsideWidth != lastWidth || outsideHeight != lastHeight {
    31  		root.SetRect(image.Rect(0, 0, outsideWidth, outsideHeight))
    32  		lastWidth, lastHeight = outsideWidth, outsideHeight
    33  	}
    34  }
    35  
    36  func Update() error {
    37  	if root == nil {
    38  		panic("no root widget specified")
    39  	}
    40  
    41  	x, y := ebiten.CursorPosition()
    42  	cursor := image.Point{x, y}
    43  
    44  	if lastX == -math.MaxInt && lastY == -math.MaxInt {
    45  		lastX, lastY = x, y
    46  	}
    47  
    48  	// TODO handle touch input
    49  
    50  	var pressed bool
    51  	for _, binding := range Bindings.ConfirmMouse {
    52  		pressed = ebiten.IsMouseButtonPressed(binding)
    53  		if pressed {
    54  			break
    55  		}
    56  	}
    57  
    58  	var clicked bool
    59  	for _, binding := range Bindings.ConfirmMouse {
    60  		clicked = inpututil.IsMouseButtonJustReleased(binding)
    61  		if clicked {
    62  			break
    63  		}
    64  	}
    65  
    66  	_, _, err := update(root, cursor, pressed, clicked, false, false)
    67  	return err
    68  }
    69  
    70  func update(w Widget, cursor image.Point, pressed bool, clicked bool, mouseHandled bool, keyboardHandled bool) (bool, bool, error) {
    71  	var err error
    72  	children := w.Children()
    73  	for _, child := range children {
    74  		mouseHandled, keyboardHandled, err = update(child, cursor, pressed, clicked, mouseHandled, keyboardHandled)
    75  		if err != nil {
    76  			return false, false, err
    77  		} else if mouseHandled && keyboardHandled {
    78  			return true, true, nil
    79  		}
    80  	}
    81  	if !mouseHandled && cursor.In(w.Rect()) {
    82  		_, err = w.HandleMouse(cursor, pressed, clicked)
    83  		if err != nil {
    84  			return false, false, fmt.Errorf("failed to handle widget mouse input: %s", err)
    85  		}
    86  	}
    87  	if !keyboardHandled {
    88  		_, err = w.HandleKeyboard()
    89  		if err != nil {
    90  			return false, false, fmt.Errorf("failed to handle widget keyboard input: %s", err)
    91  		}
    92  	}
    93  	return mouseHandled, keyboardHandled, nil
    94  }
    95  
    96  func Draw(screen *ebiten.Image) error {
    97  	if root == nil {
    98  		panic("no root widget specified")
    99  	}
   100  
   101  	return draw(root, screen)
   102  }
   103  
   104  func draw(w Widget, screen *ebiten.Image) error {
   105  	err := w.Draw(screen)
   106  	if err != nil {
   107  		return fmt.Errorf("failed to draw widget: %s", err)
   108  	}
   109  
   110  	children := w.Children()
   111  	for _, child := range children {
   112  		err = draw(child, screen)
   113  		if err != nil {
   114  			return fmt.Errorf("failed to draw widget: %s", err)
   115  		}
   116  	}
   117  
   118  	return nil
   119  }
   120  

View as plain text