Updated a few things

Add a few handy things to asciiart and menu
This commit is contained in:
Brian Buller 2015-10-26 17:38:49 -05:00
parent da19f61603
commit 02537f2b96
3 changed files with 221 additions and 56 deletions

View File

@ -35,6 +35,30 @@ func (i *ASCIIArt) SetY(y int) *ASCIIArt {
return i return i
} }
// GetHeight Returns the number of strings in the contents slice
func (i *ASCIIArt) GetHeight() int {
return len(i.contents)
}
// SetContents Sets the contents of i to c
func (i *ASCIIArt) SetContents(c []string) *ASCIIArt {
i.contents = c
return i
}
// GetContents returns the ascii art
func (i *ASCIIArt) GetContents() []string {
return i.contents
}
// SetContentLine Sets a specific line of the contents to s
func (i *ASCIIArt) SetContentLine(s string, idx int) *ASCIIArt {
if idx >= 0 && idx < len(i.contents) {
i.contents[idx] = s
}
return i
}
// GetBackground Return the current background color of the modal // GetBackground Return the current background color of the modal
func (i *ASCIIArt) GetBackground() termbox.Attribute { return i.bg } func (i *ASCIIArt) GetBackground() termbox.Attribute { return i.bg }

View File

@ -1,38 +1,36 @@
package termboxUtil package termboxUtil
import ( import "github.com/nsf/termbox-go"
"github.com/nsf/termbox-go"
)
// Menu is a menu with a list of options // Menu is a menu with a list of options
type Menu struct { type Menu struct {
title string title string
options []string options []MenuOption
// If height is -1, then it is adaptive to the menu // If height is -1, then it is adaptive to the menu
x, y, width, height int x, y, width, height int
optionsDisabled []bool
optionsHelp []string
showHelp bool showHelp bool
cursor int cursor int
bg, fg termbox.Attribute bg, fg termbox.Attribute
selectedBg, selectedFg termbox.Attribute selectedBg, selectedFg termbox.Attribute
disabledBg, disabledFg termbox.Attribute disabledBg, disabledFg termbox.Attribute
isDone bool isDone bool
selectedOption int
bordered bool bordered bool
hasFocus bool
} }
// CreateMenu Creates a menu with the specified attributes // CreateMenu Creates a menu with the specified attributes
func CreateMenu(title string, options []string, x, y, width, height int, fg, bg termbox.Attribute) *Menu { func CreateMenu(title string, options []string, x, y, width, height int, fg, bg termbox.Attribute) *Menu {
i := Menu{title: title, options: options, x: x, y: y, width: width, height: height, fg: fg, bg: bg} i := Menu{
for len(i.optionsDisabled) < len(i.options) { title: title,
i.optionsDisabled = append(i.optionsDisabled, false) x: x, y: y, width: width, height: height,
fg: fg, bg: bg, selectedFg: bg, selectedBg: fg,
disabledFg: bg, disabledBg: bg,
}
for _, line := range options {
i.options = append(i.options, MenuOption{text: line})
}
if len(i.options) > 0 {
i.SetSelectedOption(&i.options[0])
} }
i.selectedFg = i.bg
i.selectedBg = i.fg
i.disabledFg = i.bg
i.disabledBg = i.bg
return &i return &i
} }
@ -46,30 +44,23 @@ func (i *Menu) SetTitle(s string) *Menu {
} }
// GetOptions returns the current options of the menu // GetOptions returns the current options of the menu
func (i *Menu) GetOptions() []string { func (i *Menu) GetOptions() []MenuOption {
return i.options return i.options
} }
// SetOptions set the menu's options to opts // SetOptions set the menu's options to opts
func (i *Menu) SetOptions(opts []string) *Menu { func (i *Menu) SetOptions(opts []MenuOption) *Menu {
i.options = opts i.options = opts
return i return i
} }
// SetOptionDisabled sets an option in the menu to disabled // SetOptionsFromStrings sets the options of this menu from a slice of strings
func (i *Menu) SetOptionDisabled(idx int) *Menu { func (i *Menu) SetOptionsFromStrings(opts []string) *Menu {
if idx > 0 && idx < len(i.options) { var newOpts []MenuOption
i.optionsDisabled[idx] = true for _, v := range opts {
newOpts = append(newOpts, *CreateOptionFromText(v))
} }
return i return i.SetOptions(newOpts)
}
// SetOptionEnabled sets an option to enabled
func (i *Menu) SetOptionEnabled(idx int) *Menu {
if idx >= 0 && idx < len(i.options) {
i.optionsDisabled[idx] = false
}
return i
} }
// GetX returns the current x coordinate of the menu // GetX returns the current x coordinate of the menu
@ -108,6 +99,85 @@ func (i *Menu) SetHeight(height int) *Menu {
return i return i
} }
// GetSelectedOption returns the current selected option
func (i *Menu) GetSelectedOption() *MenuOption {
idx := i.GetSelectedIndex()
if idx != -1 {
return &i.options[idx]
}
return nil
}
// GetOptionFromIndex Returns the
func (i *Menu) GetOptionFromIndex(idx int) *MenuOption {
if idx >= 0 && idx < len(i.options) {
return &i.options[idx]
}
return nil
}
// GetOptionFromText Returns the first option with the text v
func (i *Menu) GetOptionFromText(v string) *MenuOption {
for idx := range i.options {
testOption := &i.options[idx]
if testOption.GetText() == v {
return testOption
}
}
return nil
}
// GetSelectedIndex returns the index of the selected option
// Returns -1 if nothing is selected
func (i *Menu) GetSelectedIndex() int {
for idx := range i.options {
if i.options[idx].IsSelected() {
return idx
}
}
return -1
}
// SetSelectedOption sets the current selected option to v (if it's valid)
func (i *Menu) SetSelectedOption(v *MenuOption) *Menu {
for idx := range i.options {
if &i.options[idx] == v {
i.options[idx].Select()
} else {
i.options[idx].Unselect()
}
}
return i
}
// SelectPrevOption Decrements the selected option (if it can)
func (i *Menu) SelectPrevOption() *Menu {
idx := i.GetSelectedIndex()
for idx >= 0 {
idx--
testOption := i.GetOptionFromIndex(idx)
if testOption != nil && !testOption.IsDisabled() {
i.SetSelectedOption(testOption)
return i
}
}
return i
}
// SelectNextOption Increments the selected option (if it can)
func (i *Menu) SelectNextOption() *Menu {
idx := i.GetSelectedIndex()
for idx < len(i.options) {
idx++
testOption := i.GetOptionFromIndex(idx)
if testOption != nil && !testOption.IsDisabled() {
i.SetSelectedOption(testOption)
return i
}
}
return i
}
// HelpIsShown returns true or false if the help is displayed // HelpIsShown returns true or false if the help is displayed
func (i *Menu) HelpIsShown() bool { return i.showHelp } func (i *Menu) HelpIsShown() bool { return i.showHelp }
@ -155,23 +225,19 @@ func (i *Menu) SetBordered(b bool) *Menu {
// HandleKeyPress handles the termbox event and returns whether it was consumed // HandleKeyPress handles the termbox event and returns whether it was consumed
func (i *Menu) HandleKeyPress(event termbox.Event) bool { func (i *Menu) HandleKeyPress(event termbox.Event) bool {
if i.hasFocus { if event.Key == termbox.KeyEnter {
if event.Key == termbox.KeyEnter { i.isDone = true
i.isDone = true return true
return true }
} currentIdx := i.GetSelectedIndex()
switch event.Key { switch event.Key {
case termbox.KeyArrowUp: case termbox.KeyArrowUp:
if i.selectedOption > 0 { i.SelectPrevOption()
i.selectedOption-- case termbox.KeyArrowDown:
return true i.SelectNextOption()
} }
case termbox.KeyArrowDown: if i.GetSelectedIndex() != currentIdx {
if i.selectedOption < len(i.options) { return true
i.selectedOption++
return true
}
}
} }
return false return false
} }
@ -196,7 +262,7 @@ func (i *Menu) Draw() {
} }
optionStartX = i.x + 1 optionStartX = i.x + 1
optionStartY = i.y + 1 optionStartY = i.y + 1
optionWidth = i.width - 2 optionWidth = i.width - 1
} }
// The title // The title
@ -210,13 +276,85 @@ func (i *Menu) Draw() {
} }
// Print the options // Print the options
for idx, opt := range i.options { if len(i.options) > 0 {
if i.optionsDisabled[idx] { for idx := range i.options {
DrawStringAtPoint(opt, optionStartX, optionStartY, i.disabledFg, i.disabledBg) currOpt := &i.options[idx]
} else if i.selectedOption == idx { if currOpt.IsDisabled() {
DrawStringAtPoint(opt, optionStartX, optionStartY, i.selectedFg, i.selectedBg) DrawStringAtPoint(currOpt.GetText(), optionStartX, optionStartY, i.disabledFg, i.disabledBg)
} else { } else if i.GetSelectedOption() == currOpt {
DrawStringAtPoint(opt, optionStartX, optionStartY, i.fg, i.bg) DrawStringAtPoint(AlignText(currOpt.GetText(), optionWidth, AlignLeft), optionStartX, optionStartY, i.selectedFg, i.selectedBg)
} else {
DrawStringAtPoint(currOpt.GetText(), optionStartX, optionStartY, i.fg, i.bg)
}
optionStartY++
} }
} }
} }
/* MenuOption Struct & methods */
// MenuOption An option in the menu
type MenuOption struct {
text string
selected bool
disabled bool
helpText string
}
// CreateOptionFromText just returns a MenuOption object
// That only has it's text value set.
func CreateOptionFromText(s string) *MenuOption {
return &MenuOption{text: s}
}
// SetText Sets the text for this option
func (i *MenuOption) SetText(s string) *MenuOption {
i.text = s
return i
}
// GetText Returns the text for this option
func (i *MenuOption) GetText() string { return i.text }
// Disable Sets this option to disabled
func (i *MenuOption) Disable() *MenuOption {
i.disabled = true
return i
}
// Enable Sets this option to enabled
func (i *MenuOption) Enable() *MenuOption {
i.disabled = false
return i
}
// IsDisabled returns whether this option is enabled
func (i *MenuOption) IsDisabled() bool {
return i.disabled
}
// IsSelected Returns whether this option is selected
func (i *MenuOption) IsSelected() bool {
return i.selected
}
// Select Sets this option to selected
func (i *MenuOption) Select() *MenuOption {
i.selected = true
return i
}
// Unselect Sets this option to not selected
func (i *MenuOption) Unselect() *MenuOption {
i.selected = false
return i
}
// SetHelpText Sets this option's help text to s
func (i *MenuOption) SetHelpText(s string) *MenuOption {
i.helpText = s
return i
}
// GetHelpText Returns the help text for this option
func (i *MenuOption) GetHelpText() string { return i.helpText }

View File

@ -69,7 +69,10 @@ func AlignText(txt string, width int, align TextAlignment) string {
case AlignRight: case AlignRight:
return fmt.Sprintf("%s%s", strings.Repeat(" ", numSpaces), txt) return fmt.Sprintf("%s%s", strings.Repeat(" ", numSpaces), txt)
default: default:
return fmt.Sprintf("%s%s", txt, strings.Repeat(" ", numSpaces)) if numSpaces >= 0 {
return fmt.Sprintf("%s%s", txt, strings.Repeat(" ", numSpaces))
}
return txt
} }
} }