mirror of
https://github.com/br0xen/termbox-util.git
synced 2024-11-22 13:33:15 +00:00
Updated a few things
Add a few handy things to asciiart and menu
This commit is contained in:
parent
da19f61603
commit
02537f2b96
@ -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 }
|
||||||
|
|
||||||
|
248
termbox_menu.go
248
termbox_menu.go
@ -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 }
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user