clui/checkbox.go

150 lines
3.8 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
)
/*
CheckBox control. It can be two-state one(on and off) - it is default mode - or tree-state.
State values are 0=off, 1=on, 2=third state
*/
2015-09-21 20:54:39 -07:00
type CheckBox struct {
2015-10-16 10:27:43 -07:00
ControlBase
2015-10-27 16:40:08 -07:00
state int
2015-10-16 10:27:43 -07:00
allow3state bool
2015-09-21 20:54:39 -07:00
}
2015-10-27 16:40:08 -07:00
/*
NewCheckBox creates a new CheckBox control.
view - is a View that manages the control.
parent - is container that keeps the control. The same View can be a view and a parent at the same time.
width and heith - are minimal size of the control.
title - button title.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size.
CheckBox state can be changed using mouse or pressing space on keyboard while the control is active
*/
2015-10-16 10:27:43 -07:00
func NewCheckBox(view View, parent Control, width int, title string, scale int) *CheckBox {
2015-09-21 20:54:39 -07:00
c := new(CheckBox)
2015-10-16 10:27:43 -07:00
c.view = view
c.parent = parent
2015-10-20 09:43:56 -07:00
if width == AutoSize {
width = xs.Len(title) + 4
}
2015-09-21 20:54:39 -07:00
c.SetSize(width, 1) // TODO: only one line checkboxes are supported at that moment
2015-10-16 10:27:43 -07:00
c.SetConstraints(width, 1)
2015-09-21 20:54:39 -07:00
c.state = 0
2015-10-16 10:27:43 -07:00
c.SetTitle(title)
c.SetTabStop(true)
2015-09-21 20:54:39 -07:00
c.allow3state = false
2015-10-16 10:27:43 -07:00
if parent != nil {
parent.AddChild(c, scale)
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
return c
2015-09-21 20:54:39 -07:00
}
2015-10-27 16:40:08 -07:00
// Repaint draws the control on its View surface
2015-10-16 10:27:43 -07:00
func (c *CheckBox) Repaint() {
x, y := c.Pos()
w, h := c.Size()
canvas := c.view.Canvas()
tm := c.view.Screen().Theme()
2015-09-21 20:54:39 -07:00
2015-10-16 10:27:43 -07:00
fg, bg := RealColor(tm, c.fg, ColorControlText), RealColor(tm, c.bg, ColorControlBack)
if !c.Enabled() {
fg, bg = RealColor(tm, c.fg, ColorControlDisabledText), RealColor(tm, c.bg, ColorControlDisabledBack)
2015-10-19 12:05:43 -07:00
} else if c.Active() {
fg, bg = RealColor(tm, c.fg, ColorControlActiveText), RealColor(tm, c.bg, ColorControlActiveBack)
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
parts := []rune(tm.SysObject(ObjCheckBox))
cOpen, cClose, cCheck, cEmpty, cUnknown := parts[0], parts[1], parts[2], parts[3], parts[4]
2015-09-21 20:54:39 -07:00
cState := []rune{cEmpty, cCheck, cUnknown}
2015-10-16 10:27:43 -07:00
canvas.FillRect(x, y, w, h, term.Cell{Ch: ' ', Bg: bg})
2015-09-21 20:54:39 -07:00
if w < 3 {
return
}
2015-10-16 10:27:43 -07:00
canvas.PutSymbol(x, y, term.Cell{Ch: cOpen, Fg: fg, Bg: bg})
canvas.PutSymbol(x+2, y, term.Cell{Ch: cClose, Fg: fg, Bg: bg})
canvas.PutSymbol(x+1, y, term.Cell{Ch: cState[c.state], Fg: fg, Bg: bg})
2015-09-21 20:54:39 -07:00
if w < 5 {
return
}
2015-10-16 10:27:43 -07:00
shift, text := AlignText(c.title, w-4, c.align)
canvas.PutText(x+4+shift, y, text, fg, bg)
2015-09-21 20:54:39 -07:00
}
2015-10-27 16:40:08 -07:00
//ProcessEvent processes all events come from the control parent. If a control
// processes an event it should return true. If the method returns false it means
// that the control do not want or cannot process the event and the caller sends
// the event to the control parent
2015-09-21 20:54:39 -07:00
func (c *CheckBox) ProcessEvent(event Event) bool {
2015-10-16 10:27:43 -07:00
if (!c.Active() && event.Type == EventKey) || !c.Enabled() {
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
if c.state == 0 {
c.state = 1
} else if c.state == 2 {
c.state = 0
} else {
if c.allow3state {
c.state = 2
} else {
c.state = 0
}
}
return true
}
return false
}
2015-10-27 16:40:08 -07:00
// SetState changes the current state of CheckBox
// Value must be 0 or 1 if Allow3State is off,
// and 0, 1, or 2 if Allow3State is on
func (c *CheckBox) SetState(val int) {
if val < 0 {
val = 0
}
if val > 1 && !c.allow3state {
val = 1
}
if val > 2 {
val = 2
}
c.state = val
}
2015-10-27 16:40:08 -07:00
// State returns current state of CheckBox
2015-10-16 10:27:43 -07:00
func (c *CheckBox) State() int {
return c.state
}
2015-10-27 16:40:08 -07:00
// SetAllow3State sets if ComboBox should use 3 states. If the current
// state is unknown and one disables Allow3State option then the current
// value resets to off
2015-10-16 10:27:43 -07:00
func (c *CheckBox) SetAllow3State(enable bool) {
if !enable && c.state == 2 {
c.state = 0
}
c.allow3state = enable
}
2015-10-27 16:40:08 -07:00
// Allow3State returns true if ComboBox uses 3 states
2015-10-16 10:27:43 -07:00
func (c *CheckBox) Allow3State() bool {
return c.allow3state
}