The system can now focus previous, next

This commit is contained in:
Sasha Koshka 2023-04-15 21:49:40 -04:00
parent 0a21f605fb
commit e16195d274
3 changed files with 58 additions and 13 deletions

View File

@ -30,8 +30,10 @@ func (backend *Backend) NewEntity (owner tomo.Element) tomo.Entity {
func (ent *entity) unlink () { func (ent *entity) unlink () {
ent.propagate (func (child *entity) bool { ent.propagate (func (child *entity) bool {
child.window = nil if child.window != nil {
delete(ent.window.system.drawingInvalid, child) delete(ent.window.system.drawingInvalid, child)
}
child.window = nil
return true return true
}) })
@ -61,17 +63,19 @@ func (ent *entity) setWindow (window *window) {
}) })
} }
func (entity *entity) propagate (callback func (*entity) bool) { func (entity *entity) propagate (callback func (*entity) bool) bool {
for _, child := range entity.children { for _, child := range entity.children {
if !callback(child) { break } if !child.propagate(callback) {
child.propagate(callback) return false
} }
} }
return callback(entity)
}
func (entity *entity) childAt (point image.Point) *entity { func (entity *entity) childAt (point image.Point) *entity {
for _, child := range entity.children { for _, child := range entity.children {
if point.In(child.bounds) { if point.In(child.bounds) {
return child return child.childAt(point)
} }
} }
return entity return entity
@ -190,12 +194,7 @@ func (entity *entity) Focused () bool {
func (entity *entity) Focus () { func (entity *entity) Focus () {
if entity.window == nil { return } if entity.window == nil { return }
previous := entity.window.focused entity.window.system.focus(entity)
entity.window.focused = entity
if previous != nil {
previous.element.(tomo.Focusable).HandleFocusChange()
}
entity.element.(tomo.Focusable).HandleFocusChange()
} }
func (entity *entity) FocusNext () { func (entity *entity) FocusNext () {

View File

@ -62,12 +62,55 @@ func (system *system) SetConfig (config tomo.Config) {
}) })
} }
func (system *system) focus (entity *entity) {
previous := system.focused
system.focused = entity
if previous != nil {
previous.element.(tomo.Focusable).HandleFocusChange()
}
if entity != nil {
entity.element.(tomo.Focusable).HandleFocusChange()
}
}
func (system *system) focusNext () { func (system *system) focusNext () {
// TODO found := system.focused == nil
focused := false
system.propagate (func (entity *entity) bool {
if found {
// looking for the next element to select
child, ok := entity.element.(tomo.Focusable)
if ok && child.Enabled() {
// found it
entity.Focus()
focused = true
return false
}
} else {
// looking for the current focused element
if entity == system.focused {
// found it
found = true
}
}
return true
})
if !focused { system.focus(nil) }
} }
func (system *system) focusPrevious () { func (system *system) focusPrevious () {
// TODO var behind *entity
system.propagate (func (entity *entity) bool {
if entity == system.focused {
return false
}
child, ok := entity.element.(tomo.Focusable)
if ok && child.Enabled() { behind = entity }
return true
})
system.focus(behind)
} }
func (system *system) propagate (callback func (*entity) bool) { func (system *system) propagate (callback func (*entity) bool) {

View File

@ -37,6 +37,9 @@ type Container interface {
type Focusable interface { type Focusable interface {
Element Element
// Enabled returns whether or not the element can currently accept focus.
Enabled () bool
// HandleFocusChange is called when the element is focused or unfocused. // HandleFocusChange is called when the element is focused or unfocused.
HandleFocusChange () HandleFocusChange ()
} }