This repository has been archived on 2023-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
tomo-old/elements/core/selectable.go

112 lines
3.6 KiB
Go

package core
import "git.tebibyte.media/sashakoshka/tomo"
// SelectableCore is a struct that can be embedded into objects to make them
// selectable, giving them the default selectability behavior.
type SelectableCore struct {
selected bool
enabled bool
drawSelectionChange func ()
onSelectionRequest func () (granted bool)
onSelectionMotionRequest func(tomo.SelectionDirection) (granted bool)
}
// NewSelectableCore creates a new selectability core and its corresponding
// control. If your element needs to visually update itself when it's selection
// state changes (which it should), a callback to draw and push the update can
// be specified.
func NewSelectableCore (
drawSelectionChange func (),
) (
core *SelectableCore,
control SelectableCoreControl,
) {
core = &SelectableCore {
drawSelectionChange: drawSelectionChange,
enabled: true,
}
control = SelectableCoreControl { core: core }
return
}
// Selected returns whether or not this element is currently selected.
func (core *SelectableCore) Selected () (selected bool) {
return core.selected
}
// Select selects this element, if its parent element grants the request.
func (core *SelectableCore) Select () {
if !core.enabled { return }
if core.onSelectionRequest != nil {
core.onSelectionRequest()
}
}
// HandleSelection causes this element to mark itself as selected, if it can
// currently be. Otherwise, it will return false and do nothing.
func (core *SelectableCore) HandleSelection (
direction tomo.SelectionDirection,
) (
accepted bool,
) {
direction = direction.Canon()
if !core.enabled { return false }
if core.selected && direction != tomo.SelectionDirectionNeutral {
return false
}
core.selected = true
if core.drawSelectionChange != nil { core.drawSelectionChange() }
return true
}
// HandleDeselection causes this element to mark itself as deselected.
func (core *SelectableCore) HandleDeselection () {
core.selected = false
if core.drawSelectionChange != nil { core.drawSelectionChange() }
}
// OnSelectionRequest sets a function to be called when this element
// wants its parent element to select it. Parent elements should return
// true if the request was granted, and false if it was not.
func (core *SelectableCore) OnSelectionRequest (callback func () (granted bool)) {
core.onSelectionRequest = callback
}
// OnSelectionMotionRequest sets a function to be called when this
// element wants its parent element to select the element behind or in
// front of it, depending on the specified direction. Parent elements
// should return true if the request was granted, and false if it was
// not.
func (core *SelectableCore) OnSelectionMotionRequest (
callback func (direction tomo.SelectionDirection) (granted bool),
) {
core.onSelectionMotionRequest = callback
}
// Enabled returns whether or not the element is enabled.
func (core *SelectableCore) Enabled () (enabled bool) {
return core.enabled
}
// SelectableCoreControl is a struct that can be used to exert control over a
// selectability core. It must not be directly embedded into an element, but
// instead kept as a private member. When a SelectableCore struct is created, a
// corresponding SelectableCoreControl struct is linked to it and returned
// alongside it.
type SelectableCoreControl struct {
core *SelectableCore
}
// SetEnabled sets whether the selectability core is enabled. If the state
// changes, this will call drawSelectionChange.
func (control SelectableCoreControl) SetEnabled (enabled bool) {
if control.core.enabled == enabled { return }
control.core.enabled = enabled
if !enabled { control.core.selected = false }
if control.core.drawSelectionChange != nil {
control.core.drawSelectionChange()
}
}