//
// Copyright (c) 2011, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 12 Jul 2011 Andy Frank Creation
//
using gfx
using fwt
**
** StyledButton is a customizable button that wraps a content widget.
**
@Js
class StyledButton : ContentPane
{
** It-block constructor.
new make(|This|? f := null)
{
if (f != null) f(this)
}
** Construct HUD style button.
new makeHud(|This|? f := null)
{
border = Border("#131313 4")
bg = Gradient("0% 0%, 0% 100%, #5b5b5b, #393939")
bgPressed = Gradient("0% 0%, 0% 100%, #333, #484848")
dropShadow = Shadow("#555 0 1")
innerShadow = Shadow("#555 0 1")
innerShadowPressed = Shadow("#222 0 1")
if (f != null) f(this)
}
** Border of button, or null for none. This field cannot be
** changed after widget peer has been created.
Border? border := Border("#9a9a9a 4")
** Insets betwee content and button border.
const Insets insets := Insets(1,10)
** Inner shadow color, of null for none.
const Shadow? innerShadow := Shadow("#fff 0 1")
** Inner shadow color when button is pressed, of null for none.
const Shadow? innerShadowPressed := Shadow("#ccc 0 1")
** Drop shadow color, or null for none.
const Shadow? dropShadow := Shadow("#dfdfdf 0 1")
** Background brush for button, or null for none.
const Brush? bg := Gradient("0% 0%, 0% 100%, #fefefe, #cfcfcf")
** Background brush when button is pressed, or null for none.
const Brush? bgPressed := Gradient("0% 0%, 0% 100%, #cecece, #d9d9d9")
** Tooltip to display on mouse hover, or null for none.
const Str? toolTip := null
** ButtonMode - only push and toggle are supported.
const ButtonMode mode := ButtonMode.push
** The button's selected state (if toggle).
Bool selected := false
{
set { &selected=it; updateState }
}
** Command associated with this button. Setting the
** command automatically maps the enable state and
** eventing to the command.
Command? command
{
set
{
newVal := it
this.&command?.unregister(this)
this.&command = newVal
if (newVal != null)
{
enabled = newVal.enabled
onAction.add |e| { newVal.invoke(e) }
newVal.register(this)
}
}
}
** EventListener invoked when button is pressed.
once EventListeners onAction() { EventListeners() }
** EventListener invoked when button is moved to pressed state.
** Use `onAction` to properly register button action events.
once EventListeners onPressed() { EventListeners() }
** EventListener invoked when button is moved to released state.
** Use `onAction` to properly register button action events.
once EventListeners onReleased() { EventListeners() }
** Group a list of StyledButtons into a single widget.
static Widget group(StyledButton[] buttons)
{
if (buttons.size == 1) return buttons.first
flow := FlowPane { hgap = -1 }
color := buttons.first.border.colorTop
radius := buttons.first.border.radiusTopLeft
buttons.each |b,i|
{
first := i == 0
last := i == buttons.size-1
left := first ? radius : 0
right := last ? radius : 0
b.border = Border("$color $left,$right,$right,$left")
flow.add(b)
}
return flow
}
** Fire 'onAction' event.
private Void fireAction()
{
onAction.fire(Event { id=EventId.action; widget=this })
}
override Size prefSize(Hints hints := Hints.defVal)
{
if (content == null) return Size(100,40)
p := content.prefSize
w := p.w + insets.left + insets.right
h := p.h + insets.top + insets.bottom
if (border != null)
{
w += border.widthLeft + border.widthRight
h += border.widthTop + border.widthBottom
}
if (dropShadow != null)
h += dropShadow.offset.y + dropShadow.blur + dropShadow.spread
return Size(w,h)
}
override Void onLayout()
{
c := content
if (c == null) return
p := content.prefSize
w := size.w - (insets.left + insets.right)
h := size.h - (insets.top + insets.bottom)
if (border != null)
{
w -= border.widthLeft + border.widthRight
h -= border.widthTop + border.widthBottom
}
if (dropShadow != null)
h -= dropShadow.offset.y + dropShadow.blur + dropShadow.spread
cw := w.min(p.w)
ch := h.min(p.h)
cx := insets.left + ((w-cw) / 2)
cy := insets.top + ((h-ch) / 2)
c.bounds = Rect(cx, cy, cw, ch)
}
private native Void updateState()
}