Added extended selection capabilities to the API
This commit is contained in:
parent
5b850ef183
commit
c2a76fcaf6
@ -78,7 +78,7 @@ func (backend *Backend) NewWindow (
|
|||||||
func (window *Window) Adopt (child tomo.Element) {
|
func (window *Window) Adopt (child tomo.Element) {
|
||||||
if window.child != nil {
|
if window.child != nil {
|
||||||
child.SetParentHooks (tomo.ParentHooks { })
|
child.SetParentHooks (tomo.ParentHooks { })
|
||||||
if child.Selectable() { child.Handle(tomo.EventDeselect { }) }
|
if child.Selected() { child.Handle(tomo.EventDeselect { }) }
|
||||||
}
|
}
|
||||||
window.child = child
|
window.child = child
|
||||||
if child != nil {
|
if child != nil {
|
||||||
@ -87,12 +87,7 @@ func (window *Window) Adopt (child tomo.Element) {
|
|||||||
MinimumSizeChange: window.childMinimumSizeChangeCallback,
|
MinimumSizeChange: window.childMinimumSizeChangeCallback,
|
||||||
SelectionRequest: window.childSelectionRequestCallback,
|
SelectionRequest: window.childSelectionRequestCallback,
|
||||||
})
|
})
|
||||||
// TODO: it is possible for an element to start out as
|
|
||||||
// selectable, and then become unselectable. it should be
|
|
||||||
// standard behavior for containers (including windows) to, if
|
|
||||||
// no children are selected, select the first child on ctrl-tab
|
|
||||||
// press. we should therefore be able to ask any element if it
|
|
||||||
// is selected.
|
|
||||||
if child.Selectable() { child.Handle(tomo.EventSelect { }) }
|
if child.Selectable() { child.Handle(tomo.EventSelect { }) }
|
||||||
window.resizeChildToFit()
|
window.resizeChildToFit()
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ type Button struct {
|
|||||||
|
|
||||||
pressed bool
|
pressed bool
|
||||||
enabled bool
|
enabled bool
|
||||||
selected bool
|
|
||||||
onClick func ()
|
onClick func ()
|
||||||
|
|
||||||
text string
|
text string
|
||||||
@ -91,10 +90,10 @@ func (element *Button) Handle (event tomo.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case tomo.EventSelect:
|
case tomo.EventSelect:
|
||||||
element.selected = true
|
element.core.SetSelected(true)
|
||||||
|
|
||||||
case tomo.EventDeselect:
|
case tomo.EventDeselect:
|
||||||
element.selected = false
|
element.core.SetSelected(false)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -103,16 +102,6 @@ func (element *Button) OnClick (callback func ()) {
|
|||||||
element.onClick = callback
|
element.onClick = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *Button) AdvanceSelection (direction int) (ok bool) {
|
|
||||||
wasSelected := element.selected
|
|
||||||
element.selected = false
|
|
||||||
if element.core.HasImage() && wasSelected {
|
|
||||||
element.draw()
|
|
||||||
element.core.PushAll()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (element *Button) Select () {
|
func (element *Button) Select () {
|
||||||
element.core.Select()
|
element.core.Select()
|
||||||
}
|
}
|
||||||
@ -150,7 +139,7 @@ func (element *Button) draw () {
|
|||||||
theme.RaisedProfile (
|
theme.RaisedProfile (
|
||||||
element.pressed,
|
element.pressed,
|
||||||
element.enabled,
|
element.enabled,
|
||||||
element.selected),
|
element.Selected()),
|
||||||
bounds)
|
bounds)
|
||||||
|
|
||||||
innerBounds := bounds
|
innerBounds := bounds
|
||||||
|
@ -13,6 +13,7 @@ type Container struct {
|
|||||||
layout tomo.Layout
|
layout tomo.Layout
|
||||||
children []tomo.LayoutEntry
|
children []tomo.LayoutEntry
|
||||||
selectable bool
|
selectable bool
|
||||||
|
selected bool
|
||||||
|
|
||||||
drags [10]tomo.Element
|
drags [10]tomo.Element
|
||||||
}
|
}
|
||||||
@ -183,6 +184,16 @@ func (element *Container) Handle (event tomo.Event) {
|
|||||||
Y: mouseMoveEvent.Y - childPosition.Y,
|
Y: mouseMoveEvent.Y - childPosition.Y,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case tomo.EventSelect:
|
||||||
|
if !element.Selectable() { break }
|
||||||
|
element.core.SetSelected(true)
|
||||||
|
|
||||||
|
case tomo.EventDeselect:
|
||||||
|
element.core.SetSelected(false)
|
||||||
|
// TODO: propogate deselect event to all children who report
|
||||||
|
// themselves as selected.
|
||||||
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -198,6 +209,7 @@ func (element *Container) updateSelectable () {
|
|||||||
if entry.Selectable() { selectable = true }
|
if entry.Selectable() { selectable = true }
|
||||||
}
|
}
|
||||||
element.core.SetSelectable(selectable)
|
element.core.SetSelectable(selectable)
|
||||||
|
if !selectable { element.selected = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *Container) updateMinimumSize () {
|
func (element *Container) updateMinimumSize () {
|
||||||
|
@ -84,10 +84,6 @@ func (element *Label) updateMinimumSize () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *Label) AdvanceSelection (direction int) (ok bool) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (element *Label) draw () {
|
func (element *Label) draw () {
|
||||||
bounds := element.core.Bounds()
|
bounds := element.core.Bounds()
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package basic
|
|||||||
import "image"
|
import "image"
|
||||||
import "image/color"
|
import "image/color"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo"
|
import "git.tebibyte.media/sashakoshka/tomo"
|
||||||
|
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||||
|
|
||||||
@ -33,9 +34,7 @@ func (element *Test) Handle (event tomo.Event) {
|
|||||||
resizeEvent.Height)
|
resizeEvent.Height)
|
||||||
artist.Rectangle (
|
artist.Rectangle (
|
||||||
element.core,
|
element.core,
|
||||||
artist.NewUniform (color.RGBA {
|
theme.AccentImage(),
|
||||||
R: 0x40, G: 0x80, B: 0x90, A: 0xFF,
|
|
||||||
}),
|
|
||||||
artist.NewUniform(color.Black),
|
artist.NewUniform(color.Black),
|
||||||
1, element.Bounds())
|
1, element.Bounds())
|
||||||
artist.Line (
|
artist.Line (
|
||||||
@ -46,7 +45,6 @@ func (element *Test) Handle (event tomo.Event) {
|
|||||||
element.core, artist.NewUniform(color.White), 1,
|
element.core, artist.NewUniform(color.White), 1,
|
||||||
image.Pt(1, resizeEvent.Height - 2),
|
image.Pt(1, resizeEvent.Height - 2),
|
||||||
image.Pt(resizeEvent.Width - 2, 1))
|
image.Pt(resizeEvent.Width - 2, 1))
|
||||||
// println(resizeEvent.Width, resizeEvent.Height)
|
|
||||||
|
|
||||||
case tomo.EventMouseDown:
|
case tomo.EventMouseDown:
|
||||||
element.drawing = true
|
element.drawing = true
|
||||||
@ -78,7 +76,3 @@ func (element *Test) Handle (event tomo.Event) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *Test) AdvanceSelection (direction int) (ok bool) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@ -16,6 +16,7 @@ type Core struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectable bool
|
selectable bool
|
||||||
|
selected bool
|
||||||
hooks tomo.ParentHooks
|
hooks tomo.ParentHooks
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,14 +48,22 @@ func (core Core) Bounds () (bounds image.Rectangle) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (core *Core) SetParentHooks (hooks tomo.ParentHooks) {
|
|
||||||
core.hooks = hooks
|
|
||||||
}
|
|
||||||
|
|
||||||
func (core Core) Selectable () (selectable bool) {
|
func (core Core) Selectable () (selectable bool) {
|
||||||
return core.selectable
|
return core.selectable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (core Core) Selected () (selected bool) {
|
||||||
|
return core.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (core Core) AdvanceSelection (direction int) (ok bool) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (core *Core) SetParentHooks (hooks tomo.ParentHooks) {
|
||||||
|
core.hooks = hooks
|
||||||
|
}
|
||||||
|
|
||||||
func (core Core) MinimumSize () (width, height int) {
|
func (core Core) MinimumSize () (width, height int) {
|
||||||
return core.metrics.minimumWidth, core.metrics.minimumHeight
|
return core.metrics.minimumWidth, core.metrics.minimumHeight
|
||||||
}
|
}
|
||||||
@ -76,6 +85,18 @@ func (control CoreControl) Select () {
|
|||||||
control.core.hooks.RunSelectionRequest()
|
control.core.hooks.RunSelectionRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (control CoreControl) SetSelected (selected bool) {
|
||||||
|
if !control.core.selectable { return }
|
||||||
|
control.core.selected = selected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (control CoreControl) SetSelectable (selectable bool) {
|
||||||
|
if control.core.selectable == selectable { return }
|
||||||
|
control.core.selectable = selectable
|
||||||
|
if !selectable { control.core.selected = false }
|
||||||
|
control.core.hooks.RunSelectabilityChange(selectable)
|
||||||
|
}
|
||||||
|
|
||||||
func (control CoreControl) PushRegion (bounds image.Rectangle) {
|
func (control CoreControl) PushRegion (bounds image.Rectangle) {
|
||||||
control.core.hooks.RunDraw(control.SubImage(bounds).(*image.RGBA))
|
control.core.hooks.RunDraw(control.SubImage(bounds).(*image.RGBA))
|
||||||
}
|
}
|
||||||
@ -91,18 +112,12 @@ func (control *CoreControl) AllocateCanvas (width, height int) {
|
|||||||
control.RGBA = core.canvas
|
control.RGBA = core.canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (control CoreControl) SetSelectable (selectable bool) {
|
|
||||||
changed := control.core.selectable != selectable
|
|
||||||
control.core.selectable = selectable
|
|
||||||
if changed {
|
|
||||||
control.core.hooks.RunSelectabilityChange(selectable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (control CoreControl) SetMinimumSize (width, height int) {
|
func (control CoreControl) SetMinimumSize (width, height int) {
|
||||||
core := control.core
|
core := control.core
|
||||||
if width != core.metrics.minimumWidth ||
|
if width == core.metrics.minimumWidth &&
|
||||||
height != core.metrics.minimumHeight {
|
height == core.metrics.minimumHeight {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
core.metrics.minimumWidth = width
|
core.metrics.minimumWidth = width
|
||||||
core.metrics.minimumHeight = height
|
core.metrics.minimumHeight = height
|
||||||
@ -125,7 +140,6 @@ func (control CoreControl) SetMinimumSize (width, height int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (control CoreControl) ConstrainSize (
|
func (control CoreControl) ConstrainSize (
|
||||||
inWidth, inHeight int,
|
inWidth, inHeight int,
|
||||||
|
@ -12,7 +12,7 @@ import "git.tebibyte.media/sashakoshka/tomo/defaultfont"
|
|||||||
|
|
||||||
var foregroundImage = artist.NewUniform(color.Gray16 { 0x0000})
|
var foregroundImage = artist.NewUniform(color.Gray16 { 0x0000})
|
||||||
var disabledForegroundImage = artist.NewUniform(color.Gray16 { 0x5555})
|
var disabledForegroundImage = artist.NewUniform(color.Gray16 { 0x5555})
|
||||||
var accentImage = artist.NewUniform(color.RGBA { 0x3E, 0x81, 0x69, 0xFF})
|
var accentImage = artist.NewUniform(color.RGBA { 0x40, 0x80, 0x90, 0xFF})
|
||||||
var highlightImage = artist.NewUniform(color.Gray16 { 0xEEEE })
|
var highlightImage = artist.NewUniform(color.Gray16 { 0xEEEE })
|
||||||
var shadowImage = artist.NewUniform(color.Gray16 { 0x3333 })
|
var shadowImage = artist.NewUniform(color.Gray16 { 0x3333 })
|
||||||
var weakShadeImage = artist.NewUniform(color.Gray16 { 0x7777 })
|
var weakShadeImage = artist.NewUniform(color.Gray16 { 0x7777 })
|
||||||
@ -24,7 +24,7 @@ var backgroundImage = artist.NewUniform(color.Gray16 { 0xAAAA})
|
|||||||
var backgroundProfile = artist.ShadingProfile {
|
var backgroundProfile = artist.ShadingProfile {
|
||||||
Highlight: highlightImage,
|
Highlight: highlightImage,
|
||||||
Shadow: shadowImage,
|
Shadow: shadowImage,
|
||||||
Stroke: artist.NewUniform(color.Gray16 { 0x0000 }),
|
Stroke: strokeImage,
|
||||||
Fill: backgroundImage,
|
Fill: backgroundImage,
|
||||||
StrokeWeight: 1,
|
StrokeWeight: 1,
|
||||||
ShadingWeight: 1,
|
ShadingWeight: 1,
|
||||||
|
6
tomo.go
6
tomo.go
@ -90,7 +90,11 @@ type Element interface {
|
|||||||
|
|
||||||
// Selectable returns whether this element can be selected. If this
|
// Selectable returns whether this element can be selected. If this
|
||||||
// element contains other selectable elements, it must return true.
|
// element contains other selectable elements, it must return true.
|
||||||
Selectable () (bool)
|
Selectable () (selectable bool)
|
||||||
|
|
||||||
|
// Selected returns wehther this element is currently selected. This
|
||||||
|
// will always return false if it is not selectable.
|
||||||
|
Selected () (selected bool)
|
||||||
|
|
||||||
// If this element contains other elements, and one is selected, this
|
// If this element contains other elements, and one is selected, this
|
||||||
// method will advance the selection in the specified direction. If no
|
// method will advance the selection in the specified direction. If no
|
||||||
|
Reference in New Issue
Block a user