clui/button.go

113 lines
2.5 KiB
Go
Raw Normal View History

2015-09-21 20:54:39 -07:00
package clui
import (
2015-10-20 09:43:56 -07:00
xs "github.com/huandu/xstrings"
2015-10-16 10:27:43 -07:00
term "github.com/nsf/termbox-go"
2015-09-21 20:54:39 -07:00
"time"
)
2015-10-27 14:39:16 -07:00
/*
Button is a simpe push button control. Every time a user clicks a Button, it
emits OnClick event. Event has only one valid field Sender.
Button can be clicked with mouse or using space on keyboard while the Button is active.
2015-09-21 20:54:39 -07:00
*/
type Button struct {
2015-10-16 10:27:43 -07:00
ControlBase
pressed bool
shadowColor term.Attribute
2015-09-21 20:54:39 -07:00
onClick func(Event)
}
2015-10-16 10:27:43 -07:00
func NewButton(view View, parent Control, width, height int, title string, scale int) *Button {
2015-09-21 20:54:39 -07:00
b := new(Button)
2015-10-16 10:27:43 -07:00
b.view = view
b.parent = parent
b.align = AlignCenter
2015-10-20 09:43:56 -07:00
if height == AutoSize {
height = 4
}
if width == AutoSize {
2015-10-21 17:04:57 -07:00
width = xs.Len(title) + 2 + 1
2015-10-20 09:43:56 -07:00
}
if height < 4 {
height = 4
}
if width < 6 {
width = 6
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
b.SetTitle(title)
b.SetSize(width, height)
b.SetConstraints(width, height)
2015-09-21 20:54:39 -07:00
2015-10-16 10:27:43 -07:00
if parent != nil {
parent.AddChild(b, scale)
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
return b
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
func (b *Button) Repaint() {
x, y := b.Pos()
w, h := b.Size()
canvas := b.view.Canvas()
tm := b.view.Screen().Theme()
2015-09-21 20:54:39 -07:00
2015-10-16 10:27:43 -07:00
fg, bg := b.fg, b.bg
shadow := RealColor(tm, b.shadowColor, ColorControlShadow)
if !b.Enabled() {
fg, bg = RealColor(tm, fg, ColorControlDisabledText), RealColor(tm, bg, ColorControlDisabledBack)
} else if b.Active() {
2015-10-19 12:05:43 -07:00
fg, bg = RealColor(tm, b.fgActive, ColorControlActiveText), RealColor(tm, b.bgActive, ColorControlActiveBack)
2015-10-16 10:27:43 -07:00
} else {
fg, bg = RealColor(tm, fg, ColorControlText), RealColor(tm, bg, ColorControlBack)
2015-09-21 20:54:39 -07:00
}
dy := int((h - 1) / 2)
2015-10-16 10:27:43 -07:00
shift, text := AlignText(b.title, w-1, b.align)
2015-09-21 20:54:39 -07:00
if !b.pressed {
2015-10-16 10:27:43 -07:00
canvas.FillRect(x+1, y+1, w-1, h-1, term.Cell{Ch: ' ', Bg: shadow})
canvas.FillRect(x, y, w-1, h-1, term.Cell{Ch: ' ', Bg: bg})
canvas.PutText(x+shift, y+dy, text, fg, bg)
2015-09-21 20:54:39 -07:00
} else {
2015-10-16 10:27:43 -07:00
canvas.FillRect(x+1, y+1, w-1, h-1, term.Cell{Ch: ' ', Bg: bg})
canvas.PutText(x+1+shift, y+1+dy, b.title, fg, bg)
2015-09-21 20:54:39 -07:00
}
}
func (b *Button) ProcessEvent(event Event) bool {
2015-10-16 10:27:43 -07:00
if (!b.active && event.Type == EventKey) || !b.Enabled() || b.pressed {
2015-09-21 20:54:39 -07:00
return false
}
2015-10-16 10:27:43 -07:00
if (event.Type == EventKey && event.Key == term.KeySpace) || event.Type == EventMouse {
2015-09-21 20:54:39 -07:00
b.pressed = true
timer := time.NewTimer(time.Millisecond * 150)
go func() {
<-timer.C
b.pressed = false
// generate ButtonClickEvent
if b.parent != nil {
if b.onClick != nil {
2015-10-16 10:27:43 -07:00
ev := Event{Sender: b}
2015-09-21 20:54:39 -07:00
b.onClick(ev)
}
2015-10-16 10:27:43 -07:00
ev := Event{Type: EventRedraw, Sender: b}
b.view.Screen().PutEvent(ev)
2015-09-21 20:54:39 -07:00
}
}()
return true
}
return false
}
func (b *Button) OnClick(fn func(Event)) {
b.onClick = fn
}