//
// Copyright (c) 2016, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 17 Aug 2016 Andy Frank Creation
//
using dom
**
** ButtonGroup groups a set of toggle or radio buttons and handles
** making sure only one button in group is selected at a time.
**
** See also: [docDomkit]`docDomkit::Controls#buttonGroup`,
** `ToggleButton`, `RadioButton`
**
@Js class ButtonGroup
{
** Buttons in this group.
Elem[] buttons := [,]
{
set { &buttons=it; update }
}
** Convenience to add a button to `buttons`.
This add(Elem button)
{
if (inheritEnabled) button.enabled = this.enabled
this.buttons = buttons.add(button)
return this
}
** If 'true', child buttons will inherit the `enabled` state
** of this 'ButtonGroup'. If 'false' buttons can be enabled
** or disabled independent of group.
Bool inheritEnabled := true
** Set enabled state for this button group.
Bool enabled := true
{
set {
&enabled = it
if (inheritEnabled)
buttons.each |b| { b.enabled = &enabled }
}
}
** Index of selected button, or 'null' if none selected.
Int? selIndex := null
{
set
{
old := &selIndex
mod := cbBeforeSelect?.call(this, it) ?: true
if (mod) &selIndex = it
update
if (it != old) cbSelect?.call(this)
}
}
** Callback before a selection changes. Return 'true' to
** select the new button (default), or 'false' to keep the
** currently selected button.
Void onBeforeSelect(|ButtonGroup g, Int newIndex->Bool| f)
{
this.cbBeforeSelect = f
}
** Callback when selection in group has changed.
Void onSelect(|This| f) { this.cbSelect = f }
** Mark given button as selected.
internal Void select(Elem button)
{
this.selIndex = buttons.findIndex |b| { b === button }
}
** Update group state and make sure buttons are bound to this group.
internal Void update()
{
buttons.each |b,i|
{
if (b is ToggleButton)
{
t := (ToggleButton)b
t.group = this
t.selected = i == selIndex
return
}
if (b is RadioButton)
{
r := (RadioButton)b
r.group = this
r.checked = i == selIndex
return
}
throw ArgErr("Invalid button for group '$b.typeof'")
}
}
// TODO: not sure how this works yet
@NoDoc Event? _event
private Func? cbBeforeSelect
private Func? cbSelect
}