Add method for controlling focus
This commit is contained in:
parent
416660e4c9
commit
5a3db3e94e
7 changed files with 68 additions and 16 deletions
10
box.go
10
box.go
|
@ -10,6 +10,8 @@ type Box struct {
|
|||
|
||||
children []Widget
|
||||
|
||||
focus bool
|
||||
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
|
@ -31,6 +33,14 @@ func (b *Box) SetRect(r image.Rectangle) {
|
|||
b.rect = r
|
||||
}
|
||||
|
||||
func (b *Box) SetFocus(focus bool) {
|
||||
b.focus = focus
|
||||
}
|
||||
|
||||
func (b *Box) Focus() bool {
|
||||
return b.focus
|
||||
}
|
||||
|
||||
func (b *Box) Children() []Widget {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
|
|
|
@ -34,16 +34,13 @@ func main() {
|
|||
w := etk.NewWindow()
|
||||
|
||||
// Input demo.
|
||||
buffer := etk.NewText("Press enter to append input below to this buffer.")
|
||||
onselected := func(text string) (handled bool) {
|
||||
buffer.Write([]byte("\nInput: " + text))
|
||||
return true
|
||||
}
|
||||
input := etk.NewInput(">", "", onselected)
|
||||
{
|
||||
buffer := etk.NewText("Press enter to append input below to this buffer.")
|
||||
|
||||
onselected := func(text string) (handled bool) {
|
||||
buffer.Write([]byte("\nInput: " + text))
|
||||
return true
|
||||
}
|
||||
|
||||
input := etk.NewInput(">", "", onselected)
|
||||
|
||||
inputDemo := etk.NewFlex()
|
||||
inputDemo.SetVertical(true)
|
||||
|
||||
|
@ -85,6 +82,7 @@ func main() {
|
|||
}
|
||||
|
||||
etk.SetRoot(w)
|
||||
etk.SetFocus(input)
|
||||
|
||||
err := ebiten.RunGame(g)
|
||||
if err != nil {
|
||||
|
|
30
game.go
30
game.go
|
@ -17,6 +17,8 @@ var (
|
|||
lastX, lastY = -math.MaxInt, -math.MaxInt
|
||||
|
||||
touchIDs []ebiten.TouchID
|
||||
|
||||
focusedWidget Widget
|
||||
)
|
||||
|
||||
func SetRoot(w Widget) {
|
||||
|
@ -24,6 +26,17 @@ func SetRoot(w Widget) {
|
|||
if lastWidth != 0 || lastHeight != 0 {
|
||||
root.SetRect(image.Rect(0, 0, lastWidth, lastHeight))
|
||||
}
|
||||
SetFocus(root)
|
||||
}
|
||||
|
||||
func SetFocus(w Widget) {
|
||||
if focusedWidget != nil {
|
||||
focusedWidget.SetFocus(false)
|
||||
}
|
||||
focusedWidget = w
|
||||
if w != nil {
|
||||
w.SetFocus(true)
|
||||
}
|
||||
}
|
||||
|
||||
func Layout(outsideWidth, outsideHeight int) {
|
||||
|
@ -88,6 +101,21 @@ func Update() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func getWidgetAt(w Widget, cursor image.Point) Widget {
|
||||
if !cursor.In(w.Rect()) {
|
||||
return nil
|
||||
}
|
||||
for _, child := range w.Children() {
|
||||
if cursor.In(child.Rect()) {
|
||||
result := getWidgetAt(child, cursor)
|
||||
if result != nil {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func update(w Widget, cursor image.Point, pressed bool, clicked bool, mouseHandled bool, keyboardHandled bool) (bool, bool, error) {
|
||||
var err error
|
||||
children := w.Children()
|
||||
|
@ -105,7 +133,7 @@ func update(w Widget, cursor image.Point, pressed bool, clicked bool, mouseHandl
|
|||
return false, false, fmt.Errorf("failed to handle widget mouse input: %s", err)
|
||||
}
|
||||
}
|
||||
if !keyboardHandled {
|
||||
if !keyboardHandled && w == focusedWidget {
|
||||
keyboardHandled, err = w.HandleKeyboard()
|
||||
if err != nil {
|
||||
return false, false, fmt.Errorf("failed to handle widget keyboard input: %s", err)
|
||||
|
|
21
input.go
21
input.go
|
@ -3,14 +3,14 @@ package etk
|
|||
import (
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
"code.rocketnine.space/tslocum/messeji"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type Input struct {
|
||||
*Box
|
||||
Field *messeji.InputField
|
||||
Field *messeji.InputField
|
||||
Cursor string
|
||||
}
|
||||
|
||||
func NewInput(prefix string, text string, onSelected func(text string) (handled bool)) *Input {
|
||||
|
@ -30,8 +30,9 @@ func NewInput(prefix string, text string, onSelected func(text string) (handled
|
|||
})
|
||||
|
||||
return &Input{
|
||||
Box: NewBox(),
|
||||
Field: i,
|
||||
Box: NewBox(),
|
||||
Field: i,
|
||||
Cursor: "_",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +56,16 @@ func (i *Input) SetRect(r image.Rectangle) {
|
|||
i.Field.SetRect(r)
|
||||
}
|
||||
|
||||
func (i *Input) SetFocus(focus bool) {
|
||||
i.focus = focus
|
||||
|
||||
cursor := i.Cursor
|
||||
if !focus {
|
||||
cursor = ""
|
||||
}
|
||||
i.Field.SetSuffix(cursor)
|
||||
}
|
||||
|
||||
func (i *Input) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
|
|
4
text.go
4
text.go
|
@ -27,6 +27,10 @@ func NewText(text string) *Text {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *Text) SetFocus(focus bool) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (t *Text) Children() []Widget {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
type Widget interface {
|
||||
Rect() image.Rectangle
|
||||
SetRect(r image.Rectangle)
|
||||
SetFocus(focus bool)
|
||||
HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error)
|
||||
HandleKeyboard() (handled bool, err error)
|
||||
Draw(screen *ebiten.Image) error
|
||||
|
|
|
@ -66,7 +66,7 @@ func (w *Window) AddChildWithLabel(wgt Widget, label string) {
|
|||
if label != "" {
|
||||
w.hasLabel = true
|
||||
}
|
||||
|
||||
|
||||
w.childrenUpdated()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue