mirror of
https://github.com/br0xen/termbox-util.git
synced 2024-11-25 14:53:14 +00:00
Syncing Repos
This commit is contained in:
parent
c19e371390
commit
062c970c0d
1
termbox-test/.gitignore
vendored
Normal file
1
termbox-test/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
termbox-test
|
@ -1,17 +1,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/nsf/termbox-go"
|
|
||||||
"gogs.bullercodeworks.com/brian/termbox-util"
|
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"gogs.bullercodeworks.com/brian/termbox-util"
|
||||||
|
|
||||||
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var keep_running bool
|
var keepRunning bool
|
||||||
|
var initialized bool
|
||||||
|
var frame *termboxUtil.Frame
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
keep_running = true
|
keepRunning = true
|
||||||
err := termbox.Init()
|
err := termbox.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -21,82 +25,7 @@ func main() {
|
|||||||
mainLoop()
|
mainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
//var input *termbox_util.InputField
|
|
||||||
var input *termbox_util.InputModal
|
|
||||||
var new_key, new_val string
|
|
||||||
var mode string
|
|
||||||
var drawY int
|
|
||||||
var added_stuff []string
|
|
||||||
|
|
||||||
func layoutAndDrawScreen() {
|
|
||||||
termbox.Clear(0, termbox.ColorBlack)
|
|
||||||
drawScreen()
|
|
||||||
termbox.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawScreen() {
|
|
||||||
w, h := termbox.Size()
|
|
||||||
termbox_util.DrawStringAtPoint(termbox_util.AlignText("Termbox Utility Test", w, termbox_util.ALIGN_CENTER), 0, 0, termbox.ColorWhite, termbox.ColorRed)
|
|
||||||
if input == nil {
|
|
||||||
mw, mh := w/4, h/4
|
|
||||||
mx, my := (w/2)-(mw/2), (h/2)-(mh/2)
|
|
||||||
input = termbox_util.CreateInputModal("", mx, my, mw, mh, termbox.ColorWhite, termbox.ColorBlack)
|
|
||||||
input.Clear()
|
|
||||||
}
|
|
||||||
if mode == "bucket" {
|
|
||||||
if input.IsDone() {
|
|
||||||
added_stuff = append(added_stuff, fmt.Sprintf("New Bucket %s", input.GetValue()))
|
|
||||||
input.Clear()
|
|
||||||
mode = ""
|
|
||||||
} else {
|
|
||||||
input.Draw()
|
|
||||||
}
|
|
||||||
} else if mode == "pair" {
|
|
||||||
if input.IsDone() {
|
|
||||||
if new_key == "" {
|
|
||||||
new_key = input.GetValue()
|
|
||||||
input.Clear()
|
|
||||||
input.SetTitle("Pair Value")
|
|
||||||
} else {
|
|
||||||
added_stuff = append(added_stuff, fmt.Sprintf("New Pair %s => %s", new_key, input.GetValue()))
|
|
||||||
mode = ""
|
|
||||||
input.Clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mode == "pair" && !input.IsDone() {
|
|
||||||
input.Draw()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mode == "" {
|
|
||||||
for i := range added_stuff {
|
|
||||||
termbox_util.DrawStringAtPoint(added_stuff[i], 1, 3+i, termbox.ColorWhite, termbox.ColorRed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleKeyEvent(event termbox.Event) bool {
|
|
||||||
if event.Key == termbox.KeyEsc {
|
|
||||||
return false
|
|
||||||
} else if event.Key == termbox.KeyCtrlB {
|
|
||||||
mode = "bucket"
|
|
||||||
new_key = ""
|
|
||||||
new_val = ""
|
|
||||||
input.Clear()
|
|
||||||
input.SetTitle("Bucket Name")
|
|
||||||
} else if event.Key == termbox.KeyCtrlP {
|
|
||||||
mode = "pair"
|
|
||||||
new_key = ""
|
|
||||||
new_val = ""
|
|
||||||
input.Clear()
|
|
||||||
input.SetTitle("Pair Key")
|
|
||||||
} else {
|
|
||||||
input.HandleKeyPress(event)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func mainLoop() {
|
func mainLoop() {
|
||||||
added_stuff = append(added_stuff, "Ctrl+B = Add Bucket; Ctrl+P = Add Pair")
|
|
||||||
layoutAndDrawScreen()
|
layoutAndDrawScreen()
|
||||||
for {
|
for {
|
||||||
event := termbox.PollEvent()
|
event := termbox.PollEvent()
|
||||||
@ -106,9 +35,12 @@ func mainLoop() {
|
|||||||
termbox.Close()
|
termbox.Close()
|
||||||
process.Signal(syscall.SIGSTOP)
|
process.Signal(syscall.SIGSTOP)
|
||||||
termbox.Init()
|
termbox.Init()
|
||||||
|
} else if event.Key == termbox.KeyCtrlC {
|
||||||
|
termbox.Close()
|
||||||
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
keep_running = handleKeyEvent(event)
|
keepRunning = handleEvent(event)
|
||||||
if !keep_running {
|
if !keepRunning {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
layoutAndDrawScreen()
|
layoutAndDrawScreen()
|
||||||
@ -117,4 +49,70 @@ func mainLoop() {
|
|||||||
layoutAndDrawScreen()
|
layoutAndDrawScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func layoutAndDrawScreen() {
|
||||||
|
w, h := termbox.Size()
|
||||||
|
if !initialized {
|
||||||
|
fg, bg := termbox.ColorWhite, termbox.ColorBlack
|
||||||
|
frame = termboxUtil.CreateFrame(1, 1, w-3, h-3, termbox.ColorWhite, termbox.ColorBlack)
|
||||||
|
/*
|
||||||
|
frame.AddControl(termboxUtil.CreateASCIIArt([]string{
|
||||||
|
"/" + strings.Repeat("=====", 5) + "\\",
|
||||||
|
"|" + strings.Repeat(".oOo.", 5) + "|",
|
||||||
|
"\\" + strings.Repeat("=====", 5) + "/",
|
||||||
|
}, 1, frame.GetBottomY()+1, fg, bg))
|
||||||
|
frame.AddControl(termboxUtil.CreateAlertModal("AlertModal", 1, 1, w-5, 6, termbox.ColorGreen, bg))
|
||||||
|
frame.AddControl(termboxUtil.CreateConfirmModal("ConfirmModal", 1, frame.GetBottomY()+1, w-5, 7, fg, bg))
|
||||||
|
frame.AddControl(termboxUtil.CreateInputModal("InputModal", 1, frame.GetBottomY()+1, w-5, 7, fg, bg))
|
||||||
|
*/
|
||||||
|
frame.AddControl(termboxUtil.CreateDropMenu("Add Control", []string{
|
||||||
|
"AlertModal",
|
||||||
|
"ASCIIArt",
|
||||||
|
"ConfirmModal",
|
||||||
|
"DropMenu",
|
||||||
|
"Frame",
|
||||||
|
"InputField",
|
||||||
|
"InputModal",
|
||||||
|
"Label",
|
||||||
|
"Menu",
|
||||||
|
"ProgressBar",
|
||||||
|
"ScrollFrame",
|
||||||
|
},
|
||||||
|
1, frame.GetBottomY()+1, w-5, 7, fg, bg, termbox.ColorBlack, termbox.ColorGreen))
|
||||||
|
frame.GetLastControl().SetBordered(true)
|
||||||
|
frame.SetActiveFlag(true)
|
||||||
|
|
||||||
|
initialized = true
|
||||||
|
}
|
||||||
|
termbox.Clear(0, termbox.ColorBlack)
|
||||||
|
drawScreen()
|
||||||
|
termboxUtil.DrawStringAtPoint(strconv.Itoa(frame.GetBottomY()), 0, h-1, termbox.ColorWhite, termbox.ColorBlack)
|
||||||
|
termbox.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawScreen() {
|
||||||
|
frame.Draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleEvent(event termbox.Event) bool {
|
||||||
|
frame.HandleEvent(event)
|
||||||
|
for _, k := range frame.GetControls() {
|
||||||
|
switch v := k.(type) {
|
||||||
|
case *termboxUtil.DropMenu:
|
||||||
|
if v.IsDone() {
|
||||||
|
}
|
||||||
|
case *termboxUtil.AlertModal:
|
||||||
|
if v.IsDone() {
|
||||||
|
v.SetText("Finished")
|
||||||
|
}
|
||||||
|
case *termboxUtil.ConfirmModal:
|
||||||
|
if v.IsDone() {
|
||||||
|
v.SetText("Finished")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k.SetFgColor(termbox.ColorWhite)
|
||||||
|
}
|
||||||
|
frame.GetActiveControl().SetFgColor(termbox.ColorGreen)
|
||||||
|
return true
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
// AlertModal is a modal with yes/no (or similar) buttons
|
// AlertModal is a modal with yes/no (or similar) buttons
|
||||||
type AlertModal struct {
|
type AlertModal struct {
|
||||||
|
id string
|
||||||
title string
|
title string
|
||||||
text string
|
text string
|
||||||
x, y, width, height int
|
x, y, width, height int
|
||||||
@ -16,18 +17,29 @@ type AlertModal struct {
|
|||||||
accepted bool
|
accepted bool
|
||||||
value string
|
value string
|
||||||
isVisible bool
|
isVisible bool
|
||||||
|
bordered bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAlertModal Creates a confirmation modal with the specified attributes
|
// CreateAlertModal Creates a confirmation modal with the specified attributes
|
||||||
func CreateAlertModal(title string, x, y, width, height int, fg, bg termbox.Attribute) *AlertModal {
|
func CreateAlertModal(title string, x, y, width, height int, fg, bg termbox.Attribute) *AlertModal {
|
||||||
i := AlertModal{title: title, x: x, y: y, width: width, height: height, fg: fg, bg: bg}
|
i := AlertModal{title: title, x: x, y: y, width: width, height: height, fg: fg, bg: bg, bordered: true}
|
||||||
if i.title == "" && i.text == "" {
|
if i.title == "" {
|
||||||
i.title = "Alert!"
|
i.title = "Alert!"
|
||||||
}
|
}
|
||||||
i.showHelp = true
|
i.showHelp = true
|
||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *AlertModal) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *AlertModal) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetTitle returns the current title of the modal
|
// GetTitle returns the current title of the modal
|
||||||
func (i *AlertModal) GetTitle() string { return i.title }
|
func (i *AlertModal) GetTitle() string { return i.title }
|
||||||
|
|
||||||
@ -44,38 +56,74 @@ func (i *AlertModal) SetText(s string) {
|
|||||||
i.text = s
|
i.text = s
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetX returns the current x coordinate of the modal
|
// GetX returns the current x coordinate of the control
|
||||||
func (i *AlertModal) GetX() int { return i.x }
|
func (i *AlertModal) GetX() int { return i.x }
|
||||||
|
|
||||||
// SetX sets the current x coordinate of the modal to x
|
// SetX sets the current x coordinate of the control to x
|
||||||
func (i *AlertModal) SetX(x int) {
|
func (i *AlertModal) SetX(x int) {
|
||||||
i.x = x
|
i.x = x
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetY returns the current y coordinate of the modal
|
// GetY returns the current y coordinate of the control
|
||||||
func (i *AlertModal) GetY() int { return i.y }
|
func (i *AlertModal) GetY() int { return i.y }
|
||||||
|
|
||||||
// SetY sets the current y coordinate of the modal to y
|
// SetY sets the current y coordinate of the control to y
|
||||||
func (i *AlertModal) SetY(y int) {
|
func (i *AlertModal) SetY(y int) {
|
||||||
i.y = y
|
i.y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWidth returns the current width of the modal
|
// GetWidth returns the current width of the control
|
||||||
func (i *AlertModal) GetWidth() int { return i.width }
|
func (i *AlertModal) GetWidth() int { return i.width }
|
||||||
|
|
||||||
// SetWidth sets the current modal width to width
|
// SetWidth sets the current control width to width
|
||||||
func (i *AlertModal) SetWidth(width int) {
|
func (i *AlertModal) SetWidth(width int) {
|
||||||
i.width = width
|
i.width = width
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeight returns the current height of the modal
|
// GetHeight returns the current height of the control
|
||||||
func (i *AlertModal) GetHeight() int { return i.height }
|
func (i *AlertModal) GetHeight() int { return i.height }
|
||||||
|
|
||||||
// SetHeight set the height of the modal to height
|
// SetHeight set the height of the control to height
|
||||||
func (i *AlertModal) SetHeight(height int) {
|
func (i *AlertModal) SetHeight(height int) {
|
||||||
i.height = height
|
i.height = height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *AlertModal) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *AlertModal) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *AlertModal) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *AlertModal) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBordered returns whether this control is bordered or not
|
||||||
|
func (i *AlertModal) IsBordered() bool {
|
||||||
|
return i.bordered
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBordered sets whether we render a border around the frame
|
||||||
|
func (i *AlertModal) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this control has it's tabskip flag set
|
||||||
|
func (i *AlertModal) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *AlertModal) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
// HelpIsShown returns true or false if the help is displayed
|
// HelpIsShown returns true or false if the help is displayed
|
||||||
func (i *AlertModal) HelpIsShown() bool { return i.showHelp }
|
func (i *AlertModal) HelpIsShown() bool { return i.showHelp }
|
||||||
|
|
||||||
@ -129,11 +177,21 @@ func (i *AlertModal) Clear() {
|
|||||||
i.isDone = false
|
i.isDone = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress handles the termbox event and returns whether it was consumed
|
// SetActiveFlag sets this control's active flag
|
||||||
func (i *AlertModal) HandleKeyPress(event termbox.Event) bool {
|
func (i *AlertModal) SetActiveFlag(b bool) {
|
||||||
if event.Key == termbox.KeyEnter {
|
i.active = b
|
||||||
i.isDone = true
|
}
|
||||||
return true
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *AlertModal) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// HandleEvent handles the termbox event and returns whether it was consumed
|
||||||
|
func (i *AlertModal) HandleEvent(event termbox.Event) bool {
|
||||||
|
if !i.active {
|
||||||
|
if event.Key == termbox.KeyEnter {
|
||||||
|
i.isDone = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -155,7 +213,6 @@ func (i *AlertModal) Draw() {
|
|||||||
}
|
}
|
||||||
if i.text != "" {
|
if i.text != "" {
|
||||||
DrawStringAtPoint(i.text, i.x+1, nextY, i.fg, i.bg)
|
DrawStringAtPoint(i.text, i.x+1, nextY, i.fg, i.bg)
|
||||||
nextY++
|
|
||||||
}
|
}
|
||||||
nextY += 2
|
nextY += 2
|
||||||
if i.showHelp {
|
if i.showHelp {
|
||||||
|
@ -8,17 +8,37 @@ import (
|
|||||||
|
|
||||||
// ASCIIArt is a []string with more functions
|
// ASCIIArt is a []string with more functions
|
||||||
type ASCIIArt struct {
|
type ASCIIArt struct {
|
||||||
|
id string
|
||||||
contents []string
|
contents []string
|
||||||
x, y int
|
x, y int
|
||||||
bg, fg termbox.Attribute
|
bg, fg termbox.Attribute
|
||||||
|
bordered bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateASCIIArt Create an ASCII art object from a string slice
|
// CreateASCIIArt Create an ASCII art object from a string slice
|
||||||
func CreateASCIIArt(c []string, x, y int, fg, bg termbox.Attribute) *ASCIIArt {
|
func CreateASCIIArt(c []string, x, y int, fg, bg termbox.Attribute) *ASCIIArt {
|
||||||
i := ASCIIArt{contents: c, x: x, y: y, fg: fg, bg: bg}
|
i := ASCIIArt{contents: c, x: x, y: y, fg: fg, bg: bg, bordered: false, tabSkip: true}
|
||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *ASCIIArt) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *ASCIIArt) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *ASCIIArt) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *ASCIIArt) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetX Return the x position of the modal
|
// GetX Return the x position of the modal
|
||||||
func (i *ASCIIArt) GetX() int { return i.x }
|
func (i *ASCIIArt) GetX() int { return i.x }
|
||||||
|
|
||||||
@ -93,20 +113,20 @@ func (i *ASCIIArt) SetContentLine(s string, idx int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackground Return the current background color of the modal
|
// GetFgColor returns the foreground color
|
||||||
func (i *ASCIIArt) GetBackground() termbox.Attribute { return i.bg }
|
func (i *ASCIIArt) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
// SetBackground Set the current background color to bg
|
// SetFgColor sets the foreground color
|
||||||
func (i *ASCIIArt) SetBackground(bg termbox.Attribute) {
|
func (i *ASCIIArt) SetFgColor(fg termbox.Attribute) {
|
||||||
i.bg = bg
|
i.fg = fg
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetForeground Return the current foreground color
|
// GetBgColor returns the background color
|
||||||
func (i *ASCIIArt) GetForeground() termbox.Attribute { return i.fg }
|
func (i *ASCIIArt) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
// SetForeground Set the foreground color to fg
|
// SetBgColor sets the current background color
|
||||||
func (i *ASCIIArt) SetForeground(fg termbox.Attribute) {
|
func (i *ASCIIArt) SetBgColor(bg termbox.Attribute) {
|
||||||
i.fg = fg
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align Align the Ascii art over width width with alignment a
|
// Align Align the Ascii art over width width with alignment a
|
||||||
@ -125,8 +145,28 @@ func (i *ASCIIArt) Align(a TextAlignment, width int) {
|
|||||||
i.contents = newContents
|
i.contents = newContents
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress accepts the termbox event and returns whether it was consumed
|
// IsBordered returns whether this modal is bordered or not
|
||||||
func (i *ASCIIArt) HandleKeyPress(event termbox.Event) bool {
|
func (i *ASCIIArt) IsBordered() bool {
|
||||||
|
return i.bordered
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBordered sets whether we render a border around the frame
|
||||||
|
func (i *ASCIIArt) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this modal has it's tabskip flag set
|
||||||
|
func (i *ASCIIArt) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *ASCIIArt) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
|
func (i *ASCIIArt) HandleEvent(event termbox.Event) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
// ConfirmModal is a modal with yes/no (or similar) buttons
|
// ConfirmModal is a modal with yes/no (or similar) buttons
|
||||||
type ConfirmModal struct {
|
type ConfirmModal struct {
|
||||||
|
id string
|
||||||
title string
|
title string
|
||||||
text string
|
text string
|
||||||
x, y, width, height int
|
x, y, width, height int
|
||||||
@ -16,6 +17,9 @@ type ConfirmModal struct {
|
|||||||
accepted bool
|
accepted bool
|
||||||
value string
|
value string
|
||||||
isVisible bool
|
isVisible bool
|
||||||
|
bordered bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConfirmModal Creates a confirmation modal with the specified attributes
|
// CreateConfirmModal Creates a confirmation modal with the specified attributes
|
||||||
@ -28,6 +32,22 @@ func CreateConfirmModal(title string, x, y, width, height int, fg, bg termbox.At
|
|||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *ConfirmModal) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *ConfirmModal) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *ConfirmModal) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *ConfirmModal) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetTitle returns the current title of the modal
|
// GetTitle returns the current title of the modal
|
||||||
func (i *ConfirmModal) GetTitle() string { return i.title }
|
func (i *ConfirmModal) GetTitle() string { return i.title }
|
||||||
|
|
||||||
@ -84,20 +104,20 @@ func (i *ConfirmModal) ShowHelp(b bool) {
|
|||||||
i.showHelp = b
|
i.showHelp = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackground returns the current background color
|
// GetFgColor returns the foreground color
|
||||||
func (i *ConfirmModal) GetBackground() termbox.Attribute { return i.bg }
|
func (i *ConfirmModal) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
// SetBackground sets the background color to bg
|
// SetFgColor sets the foreground color
|
||||||
func (i *ConfirmModal) SetBackground(bg termbox.Attribute) {
|
func (i *ConfirmModal) SetFgColor(fg termbox.Attribute) {
|
||||||
i.bg = bg
|
i.fg = fg
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetForeground returns the current foreground color
|
// GetBgColor returns the background color
|
||||||
func (i *ConfirmModal) GetForeground() termbox.Attribute { return i.fg }
|
func (i *ConfirmModal) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
// SetForeground sets the current foreground color to fg
|
// SetBgColor sets the current background color
|
||||||
func (i *ConfirmModal) SetForeground(fg termbox.Attribute) {
|
func (i *ConfirmModal) SetBgColor(bg termbox.Attribute) {
|
||||||
i.fg = fg
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDone returns whether the user has answered the modal
|
// IsDone returns whether the user has answered the modal
|
||||||
@ -129,16 +149,38 @@ func (i *ConfirmModal) Clear() {
|
|||||||
i.isDone = false
|
i.isDone = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress handles the termbox event and returns whether it was consumed
|
// IsBordered returns whether this modal is bordered or not
|
||||||
func (i *ConfirmModal) HandleKeyPress(event termbox.Event) bool {
|
func (i *ConfirmModal) IsBordered() bool {
|
||||||
if event.Ch == 'Y' || event.Ch == 'y' {
|
return i.bordered
|
||||||
i.accepted = true
|
}
|
||||||
i.isDone = true
|
|
||||||
return true
|
// SetBordered sets whether we render a border around the frame
|
||||||
} else if event.Ch == 'N' || event.Ch == 'n' {
|
func (i *ConfirmModal) SetBordered(b bool) {
|
||||||
i.accepted = false
|
i.bordered = b
|
||||||
i.isDone = true
|
}
|
||||||
return true
|
|
||||||
|
// IsTabSkipped returns whether this modal has it's tabskip flag set
|
||||||
|
func (i *ConfirmModal) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *ConfirmModal) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEvent handles the termbox event and returns whether it was consumed
|
||||||
|
func (i *ConfirmModal) HandleEvent(event termbox.Event) bool {
|
||||||
|
if i.active {
|
||||||
|
if event.Ch == 'Y' || event.Ch == 'y' {
|
||||||
|
i.accepted = true
|
||||||
|
i.isDone = true
|
||||||
|
return true
|
||||||
|
} else if event.Ch == 'N' || event.Ch == 'n' {
|
||||||
|
i.accepted = false
|
||||||
|
i.isDone = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -160,7 +202,6 @@ func (i *ConfirmModal) Draw() {
|
|||||||
}
|
}
|
||||||
if i.text != "" {
|
if i.text != "" {
|
||||||
DrawStringAtPoint(i.text, i.x+1, nextY, i.fg, i.bg)
|
DrawStringAtPoint(i.text, i.x+1, nextY, i.fg, i.bg)
|
||||||
nextY++
|
|
||||||
}
|
}
|
||||||
nextY += 2
|
nextY += 2
|
||||||
if i.showHelp {
|
if i.showHelp {
|
||||||
|
190
termbox_dropmenu.go
Normal file
190
termbox_dropmenu.go
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
package termboxUtil
|
||||||
|
|
||||||
|
import "github.com/nsf/termbox-go"
|
||||||
|
|
||||||
|
// DropMenu is a title that, when active drops a menu down
|
||||||
|
type DropMenu struct {
|
||||||
|
id string
|
||||||
|
title string
|
||||||
|
x, y, width, height int
|
||||||
|
bg, fg termbox.Attribute
|
||||||
|
selectedBg, selectedFg termbox.Attribute
|
||||||
|
menu *Menu
|
||||||
|
menuSelected bool
|
||||||
|
showMenu bool
|
||||||
|
bordered bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDropMenu Creates a menu with the specified attributes
|
||||||
|
func CreateDropMenu(title string, options []string, x, y, width, height int, fg, bg, selectedFg, selectedBg termbox.Attribute) *DropMenu {
|
||||||
|
i := DropMenu{
|
||||||
|
title: title,
|
||||||
|
x: x, y: y, width: width, height: height,
|
||||||
|
fg: fg, bg: bg,
|
||||||
|
selectedFg: fg, selectedBg: bg,
|
||||||
|
}
|
||||||
|
i.menu = CreateMenu("", options, x, y+2, width, height, fg, bg)
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *DropMenu) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *DropMenu) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTitle returns the current title of the menu
|
||||||
|
func (i *DropMenu) GetTitle() string { return i.title }
|
||||||
|
|
||||||
|
// SetTitle sets the current title of the menu to s
|
||||||
|
func (i *DropMenu) SetTitle(s string) {
|
||||||
|
i.title = s
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMenu returns the menu for this dropmenu
|
||||||
|
func (i *DropMenu) GetMenu() *Menu {
|
||||||
|
return i.menu
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX returns the current x coordinate of the menu
|
||||||
|
func (i *DropMenu) GetX() int { return i.x }
|
||||||
|
|
||||||
|
// SetX sets the current x coordinate of the menu to x
|
||||||
|
func (i *DropMenu) SetX(x int) {
|
||||||
|
i.x = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetY returns the current y coordinate of the menu
|
||||||
|
func (i *DropMenu) GetY() int { return i.y }
|
||||||
|
|
||||||
|
// SetY sets the current y coordinate of the menu to y
|
||||||
|
func (i *DropMenu) SetY(y int) {
|
||||||
|
i.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWidth returns the current width of the menu
|
||||||
|
func (i *DropMenu) GetWidth() int { return i.width }
|
||||||
|
|
||||||
|
// SetWidth sets the current menu width to width
|
||||||
|
func (i *DropMenu) SetWidth(width int) {
|
||||||
|
i.width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHeight returns the current height of the menu
|
||||||
|
func (i *DropMenu) GetHeight() int { return i.height }
|
||||||
|
|
||||||
|
// SetHeight set the height of the menu to height
|
||||||
|
func (i *DropMenu) SetHeight(height int) {
|
||||||
|
i.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *DropMenu) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *DropMenu) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *DropMenu) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *DropMenu) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBordered returns the bordered flag
|
||||||
|
func (i *DropMenu) IsBordered() bool { return i.bordered }
|
||||||
|
|
||||||
|
// SetBordered sets the bordered flag
|
||||||
|
func (i *DropMenu) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
i.menu.SetBordered(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDone returns whether the user has answered the modal
|
||||||
|
func (i *DropMenu) IsDone() bool { return i.menu.isDone }
|
||||||
|
|
||||||
|
// SetDone sets whether the modal has completed it's purpose
|
||||||
|
func (i *DropMenu) SetDone(b bool) {
|
||||||
|
i.menu.isDone = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this modal has it's tabskip flag set
|
||||||
|
func (i *DropMenu) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *DropMenu) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets the dropmenu active flag
|
||||||
|
func (i *DropMenu) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether the DropMenu is active
|
||||||
|
func (i *DropMenu) IsActive() bool {
|
||||||
|
return i.active
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowMenu tells the menu to draw the options
|
||||||
|
func (i *DropMenu) ShowMenu() {
|
||||||
|
i.showMenu = true
|
||||||
|
i.menuSelected = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HideMenu tells the menu to hide the options
|
||||||
|
func (i *DropMenu) HideMenu() {
|
||||||
|
i.showMenu = false
|
||||||
|
i.menuSelected = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEvent handles the termbox event and returns whether it was consumed
|
||||||
|
func (i *DropMenu) HandleEvent(event termbox.Event) bool {
|
||||||
|
if i.active {
|
||||||
|
moveUp := (event.Key == termbox.KeyArrowUp || (i.menu.vimMode && event.Ch == 'k'))
|
||||||
|
moveDown := (event.Key == termbox.KeyArrowDown || (i.menu.vimMode && event.Ch == 'j'))
|
||||||
|
if i.menuSelected {
|
||||||
|
selIdx := i.menu.GetSelectedIndex()
|
||||||
|
if (moveUp && selIdx == 0) || (moveDown && selIdx == (len(i.menu.options)-1)) {
|
||||||
|
i.menuSelected = false
|
||||||
|
} else {
|
||||||
|
if i.menu.HandleEvent(event) {
|
||||||
|
if i.menu.IsDone() {
|
||||||
|
i.HideMenu()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i.ShowMenu()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw draws the menu
|
||||||
|
func (i *DropMenu) Draw() {
|
||||||
|
// The title
|
||||||
|
ttlFg, ttlBg := i.fg, i.bg
|
||||||
|
if i.active && !i.menuSelected {
|
||||||
|
ttlFg, ttlBg = i.selectedFg, i.selectedBg
|
||||||
|
}
|
||||||
|
ttlTxt := i.title
|
||||||
|
if i.showMenu {
|
||||||
|
ttlTxt = ttlTxt + "-Showing Menu"
|
||||||
|
}
|
||||||
|
DrawStringAtPoint(AlignText(i.title, i.width, AlignLeft), i.x, i.y, ttlFg, ttlBg)
|
||||||
|
if i.showMenu {
|
||||||
|
i.menu.Draw()
|
||||||
|
}
|
||||||
|
}
|
213
termbox_frame.go
Normal file
213
termbox_frame.go
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
package termboxUtil
|
||||||
|
|
||||||
|
import "github.com/nsf/termbox-go"
|
||||||
|
|
||||||
|
// Frame is a frame for holding other elements
|
||||||
|
// It manages it's own x/y, tab index
|
||||||
|
type Frame struct {
|
||||||
|
id string
|
||||||
|
x, y, width, height int
|
||||||
|
tabIdx int
|
||||||
|
fg, bg termbox.Attribute
|
||||||
|
bordered bool
|
||||||
|
controls []termboxControl
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFrame creates a Frame at x, y that is w by h
|
||||||
|
func CreateFrame(x, y, w, h int, fg, bg termbox.Attribute) *Frame {
|
||||||
|
s := Frame{x: x, y: y, width: w, height: h, fg: fg, bg: bg, bordered: true}
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *Frame) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *Frame) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *Frame) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *Frame) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX returns the x position of the frame
|
||||||
|
func (i *Frame) GetX() int { return i.x }
|
||||||
|
|
||||||
|
// SetX sets the x position of the frame
|
||||||
|
func (i *Frame) SetX(x int) {
|
||||||
|
i.x = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetY returns the y position of the frame
|
||||||
|
func (i *Frame) GetY() int { return i.y }
|
||||||
|
|
||||||
|
// SetY sets the y position of the frame
|
||||||
|
func (i *Frame) SetY(y int) {
|
||||||
|
i.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWidth returns the current width of the frame
|
||||||
|
func (i *Frame) GetWidth() int { return i.width }
|
||||||
|
|
||||||
|
// SetWidth sets the current width of the frame
|
||||||
|
func (i *Frame) SetWidth(w int) {
|
||||||
|
i.width = w
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHeight returns the current height of the frame
|
||||||
|
func (i *Frame) GetHeight() int { return i.height }
|
||||||
|
|
||||||
|
// SetHeight sets the current height of the frame
|
||||||
|
func (i *Frame) SetHeight(h int) {
|
||||||
|
i.height = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *Frame) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *Frame) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *Frame) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *Frame) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBordered returns true or false if this frame has a border
|
||||||
|
func (i *Frame) IsBordered() bool { return i.bordered }
|
||||||
|
|
||||||
|
// SetBordered sets whether we render a border around the frame
|
||||||
|
func (i *Frame) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this modal has it's tabskip flag set
|
||||||
|
func (i *Frame) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *Frame) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddControl adds a control to the frame
|
||||||
|
func (i *Frame) AddControl(t termboxControl) {
|
||||||
|
i.controls = append(i.controls, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetActiveControl returns the control at tabIdx
|
||||||
|
func (i *Frame) GetActiveControl() termboxControl {
|
||||||
|
if len(i.controls) >= i.tabIdx {
|
||||||
|
return i.controls[i.tabIdx]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetControls returns a slice of all controls
|
||||||
|
func (i *Frame) GetControls() []termboxControl {
|
||||||
|
return i.controls
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetControl returns the control at index i
|
||||||
|
func (i *Frame) GetControl(idx int) termboxControl {
|
||||||
|
if len(i.controls) >= idx {
|
||||||
|
return i.controls[idx]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetControlCount returns the number of controls contained
|
||||||
|
func (i *Frame) GetControlCount() int {
|
||||||
|
return len(i.controls)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLastControl returns the last control contained
|
||||||
|
func (i *Frame) GetLastControl() termboxControl {
|
||||||
|
return i.controls[len(i.controls)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawControl figures out the relative position of the control,
|
||||||
|
// sets it, draws it, then resets it.
|
||||||
|
func (i *Frame) DrawControl(t termboxControl) {
|
||||||
|
ctlX, ctlY := t.GetX(), t.GetY()
|
||||||
|
t.SetX((i.GetX() + ctlX))
|
||||||
|
t.SetY((i.GetY() + ctlY))
|
||||||
|
t.Draw()
|
||||||
|
t.SetX(ctlX)
|
||||||
|
t.SetY(ctlY)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBottomY returns the y of the lowest control in the frame
|
||||||
|
func (i *Frame) GetBottomY() int {
|
||||||
|
var ret int
|
||||||
|
for idx := range i.controls {
|
||||||
|
if i.controls[idx].GetY()+i.controls[idx].GetHeight() > ret {
|
||||||
|
ret = i.controls[idx].GetY() + i.controls[idx].GetHeight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
|
func (i *Frame) HandleEvent(event termbox.Event) bool {
|
||||||
|
if i.active {
|
||||||
|
if event.Key == termbox.KeyTab {
|
||||||
|
i.FindNextTabStop()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return i.controls[i.tabIdx].HandleEvent(event)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindNextTabStop finds the next control that can be tabbed to
|
||||||
|
// A return of true means it found a different one than we started on.
|
||||||
|
func (i *Frame) FindNextTabStop() bool {
|
||||||
|
startTab := i.tabIdx
|
||||||
|
i.tabIdx = (i.tabIdx + 1) % len(i.controls)
|
||||||
|
for i.controls[i.tabIdx].IsTabSkipped() {
|
||||||
|
i.tabIdx = (i.tabIdx + 1) % len(i.controls)
|
||||||
|
if i.tabIdx == startTab {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for idx := range i.controls {
|
||||||
|
i.controls[idx].SetActiveFlag(idx == i.tabIdx)
|
||||||
|
}
|
||||||
|
return i.tabIdx != startTab
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw outputs the Scoll Frame on the screen
|
||||||
|
func (i *Frame) Draw() {
|
||||||
|
maxWidth := i.width
|
||||||
|
maxHeight := i.height
|
||||||
|
x, y := i.x, i.y
|
||||||
|
startX := i.x
|
||||||
|
startY := i.y
|
||||||
|
if i.bordered {
|
||||||
|
FillWithChar(' ', i.x, i.y, i.x+i.width, i.y+i.height, i.fg, i.bg)
|
||||||
|
DrawBorder(i.x, i.y, i.x+i.width, i.y+i.height, i.fg, i.bg)
|
||||||
|
maxWidth--
|
||||||
|
maxHeight--
|
||||||
|
x++
|
||||||
|
y++
|
||||||
|
startX++
|
||||||
|
startY++
|
||||||
|
}
|
||||||
|
for idx := range i.controls {
|
||||||
|
i.DrawControl(i.controls[idx])
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import "github.com/nsf/termbox-go"
|
|||||||
|
|
||||||
// InputField is a field for inputting text
|
// InputField is a field for inputting text
|
||||||
type InputField struct {
|
type InputField struct {
|
||||||
|
id string
|
||||||
value string
|
value string
|
||||||
x, y, width, height int
|
x, y, width, height int
|
||||||
cursor int
|
cursor int
|
||||||
@ -11,14 +12,32 @@ type InputField struct {
|
|||||||
bordered bool
|
bordered bool
|
||||||
wrap bool
|
wrap bool
|
||||||
multiline bool
|
multiline bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateInputField creates an input field at x, y that is w by h
|
// CreateInputField creates an input field at x, y that is w by h
|
||||||
func CreateInputField(x, y, w, h int, fg, bg termbox.Attribute) *InputField {
|
func CreateInputField(x, y, w, h int, fg, bg termbox.Attribute) *InputField {
|
||||||
i := InputField{x: x, y: y, width: w, height: h, fg: fg, bg: bg}
|
i := InputField{x: x, y: y, width: w, height: h, fg: fg, bg: bg, active: true}
|
||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *InputField) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *InputField) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *InputField) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *InputField) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetValue gets the current text that is in the InputField
|
// GetValue gets the current text that is in the InputField
|
||||||
func (i *InputField) GetValue() string { return i.value }
|
func (i *InputField) GetValue() string { return i.value }
|
||||||
|
|
||||||
@ -59,6 +78,22 @@ func (i *InputField) SetHeight(h int) {
|
|||||||
i.height = h
|
i.height = h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *InputField) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *InputField) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *InputField) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *InputField) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
|
}
|
||||||
|
|
||||||
// IsBordered returns true or false if this input field has a border
|
// IsBordered returns true or false if this input field has a border
|
||||||
func (i *InputField) IsBordered() bool { return i.bordered }
|
func (i *InputField) IsBordered() bool { return i.bordered }
|
||||||
|
|
||||||
@ -67,6 +102,16 @@ func (i *InputField) SetBordered(b bool) {
|
|||||||
i.bordered = b
|
i.bordered = b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this modal has it's tabskip flag set
|
||||||
|
func (i *InputField) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *InputField) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
// DoesWrap returns true or false if this input field wraps text
|
// DoesWrap returns true or false if this input field wraps text
|
||||||
func (i *InputField) DoesWrap() bool { return i.wrap }
|
func (i *InputField) DoesWrap() bool { return i.wrap }
|
||||||
|
|
||||||
@ -83,55 +128,58 @@ func (i *InputField) SetMultiline(b bool) {
|
|||||||
i.multiline = b
|
i.multiline = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress accepts the termbox event and returns whether it was consumed
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
func (i *InputField) HandleKeyPress(event termbox.Event) bool {
|
func (i *InputField) HandleEvent(event termbox.Event) bool {
|
||||||
if event.Key == termbox.KeyBackspace || event.Key == termbox.KeyBackspace2 {
|
if i.active {
|
||||||
if len(i.value) > 0 {
|
if event.Key == termbox.KeyBackspace || event.Key == termbox.KeyBackspace2 {
|
||||||
i.value = i.value[:len(i.value)-1]
|
if len(i.value) > 0 {
|
||||||
}
|
i.value = i.value[:len(i.value)-1]
|
||||||
} else if event.Key == termbox.KeyArrowLeft {
|
}
|
||||||
if i.cursor+len(i.value) > 0 {
|
} else if event.Key == termbox.KeyArrowLeft {
|
||||||
i.cursor--
|
if i.cursor+len(i.value) > 0 {
|
||||||
}
|
i.cursor--
|
||||||
} else if event.Key == termbox.KeyArrowRight {
|
}
|
||||||
if i.cursor < 0 {
|
} else if event.Key == termbox.KeyArrowRight {
|
||||||
i.cursor++
|
if i.cursor < 0 {
|
||||||
}
|
i.cursor++
|
||||||
} else if event.Key == termbox.KeyCtrlU {
|
}
|
||||||
// Ctrl+U Clears the Input (before the cursor)
|
} else if event.Key == termbox.KeyCtrlU {
|
||||||
i.value = i.value[i.cursor:]
|
// Ctrl+U Clears the Input (before the cursor)
|
||||||
} else {
|
i.value = i.value[i.cursor:]
|
||||||
// Get the rune to add to our value. Space and Tab are special cases where
|
} else {
|
||||||
// we can't use the event's rune directly
|
// Get the rune to add to our value. Space and Tab are special cases where
|
||||||
var ch string
|
// we can't use the event's rune directly
|
||||||
switch event.Key {
|
var ch string
|
||||||
case termbox.KeySpace:
|
switch event.Key {
|
||||||
ch = " "
|
case termbox.KeySpace:
|
||||||
case termbox.KeyTab:
|
ch = " "
|
||||||
ch = "\t"
|
case termbox.KeyTab:
|
||||||
/* Multiline is disabled right now
|
ch = "\t"
|
||||||
case termbox.KeyEnter:
|
/* Multiline is disabled right now
|
||||||
if i.multiline {
|
case termbox.KeyEnter:
|
||||||
ch = "\n"
|
if i.multiline {
|
||||||
|
ch = "\n"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
if KeyIsAlphaNumeric(event) || KeyIsSymbol(event) {
|
||||||
|
ch = string(event.Ch)
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
default:
|
|
||||||
if KeyIsAlphaNumeric(event) || KeyIsSymbol(event) {
|
if i.cursor+len(i.value) == 0 {
|
||||||
ch = string(event.Ch)
|
i.value = string(ch) + i.value
|
||||||
|
} else if i.cursor == 0 {
|
||||||
|
i.value = i.value + string(ch)
|
||||||
|
} else {
|
||||||
|
strPt1 := i.value[:(len(i.value) + i.cursor)]
|
||||||
|
strPt2 := i.value[(len(i.value) + i.cursor):]
|
||||||
|
i.value = strPt1 + string(ch) + strPt2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
if i.cursor+len(i.value) == 0 {
|
|
||||||
i.value = string(ch) + i.value
|
|
||||||
} else if i.cursor == 0 {
|
|
||||||
i.value = i.value + string(ch)
|
|
||||||
} else {
|
|
||||||
strPt1 := i.value[:(len(i.value) + i.cursor)]
|
|
||||||
strPt2 := i.value[(len(i.value) + i.cursor):]
|
|
||||||
i.value = strPt1 + string(ch) + strPt2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw outputs the input field on the screen
|
// Draw outputs the input field on the screen
|
||||||
@ -190,7 +238,11 @@ func (i *InputField) Draw() {
|
|||||||
y++
|
y++
|
||||||
x = startX
|
x = startX
|
||||||
}
|
}
|
||||||
termbox.SetCell(x, y, cursorRune, i.bg, i.fg)
|
if i.active {
|
||||||
|
termbox.SetCell(x, y, cursorRune, i.bg, i.fg)
|
||||||
|
} else {
|
||||||
|
termbox.SetCell(x, y, cursorRune, i.fg, i.bg)
|
||||||
|
}
|
||||||
x++
|
x++
|
||||||
if len(strPt2) > 0 {
|
if len(strPt2) > 0 {
|
||||||
lenLeft := maxWidth - len(strPt1) - 1
|
lenLeft := maxWidth - len(strPt1) - 1
|
||||||
@ -219,7 +271,11 @@ func (i *InputField) Draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
x, y = DrawStringAtPoint(strPt1, i.x+1, i.y+1, i.fg, i.bg)
|
x, y = DrawStringAtPoint(strPt1, i.x+1, i.y+1, i.fg, i.bg)
|
||||||
termbox.SetCell(x, y, cursorRune, i.bg, i.fg)
|
if i.active {
|
||||||
|
termbox.SetCell(x, y, cursorRune, i.bg, i.fg)
|
||||||
|
} else {
|
||||||
|
termbox.SetCell(x, y, cursorRune, i.fg, i.bg)
|
||||||
|
}
|
||||||
DrawStringAtPoint(strPt2, x+1, y, i.fg, i.bg)
|
DrawStringAtPoint(strPt2, x+1, y, i.fg, i.bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
// InputModal A modal for text input
|
// InputModal A modal for text input
|
||||||
type InputModal struct {
|
type InputModal struct {
|
||||||
|
id string
|
||||||
title string
|
title string
|
||||||
text string
|
text string
|
||||||
input *InputField
|
input *InputField
|
||||||
@ -15,18 +16,37 @@ type InputModal struct {
|
|||||||
bg, fg termbox.Attribute
|
bg, fg termbox.Attribute
|
||||||
isDone bool
|
isDone bool
|
||||||
isVisible bool
|
isVisible bool
|
||||||
|
bordered bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateInputModal Create an input modal with the given attributes
|
// CreateInputModal Create an input modal with the given attributes
|
||||||
func CreateInputModal(title string, x, y, width, height int, fg, bg termbox.Attribute) *InputModal {
|
func CreateInputModal(title string, x, y, width, height int, fg, bg termbox.Attribute) *InputModal {
|
||||||
i := InputModal{title: title, x: x, y: y, width: width, height: height, fg: fg, bg: bg}
|
i := InputModal{title: title, x: x, y: y, width: width, height: height, fg: fg, bg: bg, bordered: true}
|
||||||
i.input = CreateInputField(i.x+1, i.y+3, i.width-2, 2, i.fg, i.bg)
|
i.input = CreateInputField(i.x+2, i.y+3, i.width-2, 2, i.fg, i.bg)
|
||||||
i.showHelp = true
|
i.showHelp = true
|
||||||
i.input.bordered = true
|
i.input.bordered = true
|
||||||
i.isVisible = true
|
i.isVisible = true
|
||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *InputModal) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *InputModal) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *InputModal) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *InputModal) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetTitle Return the title of the modal
|
// GetTitle Return the title of the modal
|
||||||
func (i *InputModal) GetTitle() string { return i.title }
|
func (i *InputModal) GetTitle() string { return i.title }
|
||||||
|
|
||||||
@ -75,6 +95,26 @@ func (i *InputModal) SetHeight(height int) {
|
|||||||
i.height = height
|
i.height = height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsBordered returns whether this control is bordered or not
|
||||||
|
func (i *InputModal) IsBordered() bool {
|
||||||
|
return i.bordered
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBordered sets whether we render a border around the frame
|
||||||
|
func (i *InputModal) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTabSkipped returns whether this control has it's tabskip flag set
|
||||||
|
func (i *InputModal) IsTabSkipped() bool {
|
||||||
|
return i.tabSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTabSkip sets the tabskip flag for this control
|
||||||
|
func (i *InputModal) SetTabSkip(b bool) {
|
||||||
|
i.tabSkip = b
|
||||||
|
}
|
||||||
|
|
||||||
// HelpIsShown Returns whether the modal is showing it's help text or not
|
// HelpIsShown Returns whether the modal is showing it's help text or not
|
||||||
func (i *InputModal) HelpIsShown() bool { return i.showHelp }
|
func (i *InputModal) HelpIsShown() bool { return i.showHelp }
|
||||||
|
|
||||||
@ -83,20 +123,20 @@ func (i *InputModal) ShowHelp(b bool) {
|
|||||||
i.showHelp = b
|
i.showHelp = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackground Return the current background color of the modal
|
// GetFgColor returns the foreground color
|
||||||
func (i *InputModal) GetBackground() termbox.Attribute { return i.bg }
|
func (i *InputModal) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
// SetBackground Set the current background color to bg
|
// SetFgColor sets the foreground color
|
||||||
func (i *InputModal) SetBackground(bg termbox.Attribute) {
|
func (i *InputModal) SetFgColor(fg termbox.Attribute) {
|
||||||
i.bg = bg
|
i.fg = fg
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetForeground Return the current foreground color
|
// GetBgColor returns the background color
|
||||||
func (i *InputModal) GetForeground() termbox.Attribute { return i.fg }
|
func (i *InputModal) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
// SetForeground Set the foreground color to fg
|
// SetBgColor sets the current background color
|
||||||
func (i *InputModal) SetForeground(fg termbox.Attribute) {
|
func (i *InputModal) SetBgColor(bg termbox.Attribute) {
|
||||||
i.fg = fg
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show Sets the visibility flag to true
|
// Show Sets the visibility flag to true
|
||||||
@ -141,14 +181,17 @@ func (i *InputModal) Clear() {
|
|||||||
i.isVisible = false
|
i.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress Handle the termbox event, return true if it was consumed
|
// HandleEvent Handle the termbox event, return true if it was consumed
|
||||||
func (i *InputModal) HandleKeyPress(event termbox.Event) bool {
|
func (i *InputModal) HandleEvent(event termbox.Event) bool {
|
||||||
if event.Key == termbox.KeyEnter {
|
if i.active {
|
||||||
// Done editing
|
if event.Key == termbox.KeyEnter {
|
||||||
i.isDone = true
|
// Done editing
|
||||||
return true
|
i.isDone = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return i.input.HandleEvent(event)
|
||||||
}
|
}
|
||||||
return i.input.HandleKeyPress(event)
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Draw the modal
|
// Draw Draw the modal
|
||||||
@ -181,7 +224,9 @@ func (i *InputModal) Draw() {
|
|||||||
helpX := (i.x + i.width - len(helpString)) - 1
|
helpX := (i.x + i.width - len(helpString)) - 1
|
||||||
DrawStringAtPoint(helpString, helpX, nextY, i.fg, i.bg)
|
DrawStringAtPoint(helpString, helpX, nextY, i.fg, i.bg)
|
||||||
}
|
}
|
||||||
// Now draw the border
|
if i.bordered {
|
||||||
DrawBorder(i.x, i.y, i.x+i.width, i.y+i.height, i.fg, i.bg)
|
// Now draw the border
|
||||||
|
DrawBorder(i.x, i.y, i.x+i.width, i.y+i.height, i.fg, i.bg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
149
termbox_label.go
Normal file
149
termbox_label.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
package termboxUtil
|
||||||
|
|
||||||
|
import "github.com/nsf/termbox-go"
|
||||||
|
|
||||||
|
// Label is a field for inputting text
|
||||||
|
type Label struct {
|
||||||
|
id string
|
||||||
|
value string
|
||||||
|
x, y, width, height int
|
||||||
|
cursor int
|
||||||
|
fg, bg termbox.Attribute
|
||||||
|
bordered bool
|
||||||
|
wrap bool
|
||||||
|
multiline bool
|
||||||
|
active bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLabel creates an input field at x, y that is w by h
|
||||||
|
func CreateLabel(lbl string, x, y, w, h int, fg, bg termbox.Attribute) *Label {
|
||||||
|
i := Label{value: lbl, x: x, y: y, width: w, height: h, fg: fg, bg: bg}
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *Label) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *Label) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *Label) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *Label) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetValue gets the current text that is in the Label
|
||||||
|
func (i *Label) GetValue() string { return i.value }
|
||||||
|
|
||||||
|
// SetValue sets the current text in the Label to s
|
||||||
|
func (i *Label) SetValue(s string) {
|
||||||
|
i.value = s
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX returns the x position of the input field
|
||||||
|
func (i *Label) GetX() int { return i.x }
|
||||||
|
|
||||||
|
// SetX sets the x position of the input field
|
||||||
|
func (i *Label) SetX(x int) {
|
||||||
|
i.x = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetY returns the y position of the input field
|
||||||
|
func (i *Label) GetY() int { return i.y }
|
||||||
|
|
||||||
|
// SetY sets the y position of the input field
|
||||||
|
func (i *Label) SetY(y int) {
|
||||||
|
i.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWidth returns the current width of the input field
|
||||||
|
func (i *Label) GetWidth() int {
|
||||||
|
if i.width == -1 {
|
||||||
|
if i.bordered {
|
||||||
|
return len(i.value) + 2
|
||||||
|
}
|
||||||
|
return len(i.value)
|
||||||
|
}
|
||||||
|
return i.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWidth sets the current width of the input field
|
||||||
|
func (i *Label) SetWidth(w int) {
|
||||||
|
i.width = w
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHeight returns the current height of the input field
|
||||||
|
func (i *Label) GetHeight() int { return i.height }
|
||||||
|
|
||||||
|
// SetHeight sets the current height of the input field
|
||||||
|
func (i *Label) SetHeight(h int) {
|
||||||
|
i.height = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *Label) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *Label) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *Label) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *Label) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBordered returns true or false if this input field has a border
|
||||||
|
func (i *Label) IsBordered() bool { return i.bordered }
|
||||||
|
|
||||||
|
// SetBordered sets whether we render a border around the input field
|
||||||
|
func (i *Label) SetBordered(b bool) {
|
||||||
|
i.bordered = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoesWrap returns true or false if this input field wraps text
|
||||||
|
func (i *Label) DoesWrap() bool { return i.wrap }
|
||||||
|
|
||||||
|
// SetWrap sets whether we wrap the text at width.
|
||||||
|
func (i *Label) SetWrap(b bool) {
|
||||||
|
i.wrap = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMultiline returns true or false if this field can have multiple lines
|
||||||
|
func (i *Label) IsMultiline() bool { return i.multiline }
|
||||||
|
|
||||||
|
// SetMultiline sets whether the field can have multiple lines
|
||||||
|
func (i *Label) SetMultiline(b bool) {
|
||||||
|
i.multiline = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
|
func (i *Label) HandleEvent(event termbox.Event) bool { return false }
|
||||||
|
|
||||||
|
// Draw outputs the input field on the screen
|
||||||
|
func (i *Label) Draw() {
|
||||||
|
maxWidth := i.width
|
||||||
|
maxHeight := i.height
|
||||||
|
x, y := i.x, i.y
|
||||||
|
startX := i.x
|
||||||
|
startY := i.y
|
||||||
|
if i.bordered {
|
||||||
|
DrawBorder(i.x, i.y, i.x+i.GetWidth(), i.y+i.height, i.fg, i.bg)
|
||||||
|
maxWidth--
|
||||||
|
maxHeight--
|
||||||
|
x++
|
||||||
|
y++
|
||||||
|
startX++
|
||||||
|
startY++
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawStringAtPoint(i.value, x, y, i.fg, i.bg)
|
||||||
|
}
|
135
termbox_menu.go
135
termbox_menu.go
@ -1,9 +1,14 @@
|
|||||||
package termboxUtil
|
package termboxUtil
|
||||||
|
|
||||||
import "github.com/nsf/termbox-go"
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"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 {
|
||||||
|
id string
|
||||||
title string
|
title string
|
||||||
options []MenuOption
|
options []MenuOption
|
||||||
// If height is -1, then it is adaptive to the menu
|
// If height is -1, then it is adaptive to the menu
|
||||||
@ -16,6 +21,8 @@ type Menu struct {
|
|||||||
isDone bool
|
isDone bool
|
||||||
bordered bool
|
bordered bool
|
||||||
vimMode bool
|
vimMode bool
|
||||||
|
tabSkip bool
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMenu Creates a menu with the specified attributes
|
// CreateMenu Creates a menu with the specified attributes
|
||||||
@ -35,6 +42,14 @@ func CreateMenu(title string, options []string, x, y, width, height int, fg, bg
|
|||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *Menu) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *Menu) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetTitle returns the current title of the menu
|
// GetTitle returns the current title of the menu
|
||||||
func (i *Menu) GetTitle() string { return i.title }
|
func (i *Menu) GetTitle() string { return i.title }
|
||||||
|
|
||||||
@ -193,20 +208,20 @@ func (i *Menu) ShowHelp(b bool) {
|
|||||||
i.showHelp = b
|
i.showHelp = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackground returns the current background color
|
// GetFgColor returns the foreground color
|
||||||
func (i *Menu) GetBackground() termbox.Attribute { return i.bg }
|
func (i *Menu) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
// SetBackground sets the background color to bg
|
// SetFgColor sets the foreground color
|
||||||
func (i *Menu) SetBackground(bg termbox.Attribute) {
|
func (i *Menu) SetFgColor(fg termbox.Attribute) {
|
||||||
i.bg = bg
|
i.fg = fg
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetForeground returns the current foreground color
|
// GetBgColor returns the background color
|
||||||
func (i *Menu) GetForeground() termbox.Attribute { return i.fg }
|
func (i *Menu) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
// SetForeground sets the current foreground color to fg
|
// SetBgColor sets the current background color
|
||||||
func (i *Menu) SetForeground(fg termbox.Attribute) {
|
func (i *Menu) SetBgColor(bg termbox.Attribute) {
|
||||||
i.fg = fg
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDone returns whether the user has answered the modal
|
// IsDone returns whether the user has answered the modal
|
||||||
@ -235,29 +250,39 @@ func (i *Menu) DisableVimMode() {
|
|||||||
i.vimMode = false
|
i.vimMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress handles the termbox event and returns whether it was consumed
|
// SetActiveFlag sets this control's active flag
|
||||||
func (i *Menu) HandleKeyPress(event termbox.Event) bool {
|
func (i *Menu) SetActiveFlag(b bool) {
|
||||||
if event.Key == termbox.KeyEnter || event.Key == termbox.KeySpace {
|
i.active = b
|
||||||
i.isDone = true
|
}
|
||||||
return true
|
|
||||||
}
|
// IsActive returns whether this control is active
|
||||||
currentIdx := i.GetSelectedIndex()
|
func (i *Menu) IsActive() bool { return i.active }
|
||||||
switch event.Key {
|
|
||||||
case termbox.KeyArrowUp:
|
// HandleEvent handles the termbox event and returns whether it was consumed
|
||||||
i.SelectPrevOption()
|
func (i *Menu) HandleEvent(event termbox.Event) bool {
|
||||||
case termbox.KeyArrowDown:
|
if i.active {
|
||||||
i.SelectNextOption()
|
if event.Key == termbox.KeyEnter || event.Key == termbox.KeySpace {
|
||||||
}
|
i.isDone = true
|
||||||
if i.vimMode {
|
return true
|
||||||
switch event.Ch {
|
}
|
||||||
case 'j':
|
currentIdx := i.GetSelectedIndex()
|
||||||
i.SelectNextOption()
|
switch event.Key {
|
||||||
case 'k':
|
case termbox.KeyArrowUp:
|
||||||
i.SelectPrevOption()
|
i.SelectPrevOption()
|
||||||
|
case termbox.KeyArrowDown:
|
||||||
|
i.SelectNextOption()
|
||||||
|
}
|
||||||
|
if i.vimMode {
|
||||||
|
switch event.Ch {
|
||||||
|
case 'j':
|
||||||
|
i.SelectNextOption()
|
||||||
|
case 'k':
|
||||||
|
i.SelectPrevOption()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i.GetSelectedIndex() != currentIdx {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if i.GetSelectedIndex() != currentIdx {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -325,16 +350,55 @@ func (i *Menu) Draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
i.DrawOptions(optionStartX, optionStartY, optionHeight, optionWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawOptions draws the menu options at x, y
|
||||||
|
func (i *Menu) DrawOptions(x, y, h, w int) {
|
||||||
|
DrawStringAtPoint(strings.Repeat("-", w), x, y, i.disabledFg, i.disabledBg)
|
||||||
|
y++
|
||||||
|
if len(i.options) > 0 {
|
||||||
|
// If the currently selected option is disabled, move to the next
|
||||||
|
if i.GetSelectedOption().IsDisabled() {
|
||||||
|
i.SelectNextOption()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the options
|
||||||
|
for idx := range i.options {
|
||||||
|
if i.GetSelectedIndex()-idx >= h-1 {
|
||||||
|
// Skip this one
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currOpt := &i.options[idx]
|
||||||
|
outTxt := currOpt.GetText()
|
||||||
|
if len(outTxt) >= i.width {
|
||||||
|
outTxt = outTxt[:i.width]
|
||||||
|
}
|
||||||
|
if currOpt.IsDisabled() {
|
||||||
|
DrawStringAtPoint(outTxt, x, y, i.disabledFg, i.disabledBg)
|
||||||
|
} else if i.GetSelectedOption() == currOpt {
|
||||||
|
DrawStringAtPoint(AlignText(outTxt, w, AlignLeft), x, y, i.selectedFg, i.selectedBg)
|
||||||
|
} else {
|
||||||
|
DrawStringAtPoint(outTxt, x, y, i.fg, i.bg)
|
||||||
|
}
|
||||||
|
y++
|
||||||
|
if y > i.y+h-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MenuOption Struct & methods */
|
/* MenuOption Struct & methods */
|
||||||
|
|
||||||
// MenuOption An option in the menu
|
// MenuOption An option in the menu
|
||||||
type MenuOption struct {
|
type MenuOption struct {
|
||||||
|
id string
|
||||||
text string
|
text string
|
||||||
selected bool
|
selected bool
|
||||||
disabled bool
|
disabled bool
|
||||||
helpText string
|
helpText string
|
||||||
|
subMenu []MenuOption
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptionFromText just returns a MenuOption object
|
// CreateOptionFromText just returns a MenuOption object
|
||||||
@ -388,3 +452,8 @@ func (i *MenuOption) SetHelpText(s string) {
|
|||||||
|
|
||||||
// GetHelpText Returns the help text for this option
|
// GetHelpText Returns the help text for this option
|
||||||
func (i *MenuOption) GetHelpText() string { return i.helpText }
|
func (i *MenuOption) GetHelpText() string { return i.helpText }
|
||||||
|
|
||||||
|
// AddToSubMenu adds a slice of MenuOptions to this option
|
||||||
|
func (i *MenuOption) AddToSubMenu(sub *MenuOption) {
|
||||||
|
i.subMenu = append(i.subMenu, *sub)
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import "github.com/nsf/termbox-go"
|
|||||||
|
|
||||||
// ProgressBar Just contains the data needed to display a progress bar
|
// ProgressBar Just contains the data needed to display a progress bar
|
||||||
type ProgressBar struct {
|
type ProgressBar struct {
|
||||||
|
id string
|
||||||
total int
|
total int
|
||||||
progress int
|
progress int
|
||||||
allowOverflow bool
|
allowOverflow bool
|
||||||
@ -17,6 +18,7 @@ type ProgressBar struct {
|
|||||||
x, y int
|
x, y int
|
||||||
width, height int
|
width, height int
|
||||||
bg, fg termbox.Attribute
|
bg, fg termbox.Attribute
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateProgressBar Create a progress bar object
|
// CreateProgressBar Create a progress bar object
|
||||||
@ -30,6 +32,22 @@ func CreateProgressBar(tot, x, y int, fg, bg termbox.Attribute) *ProgressBar {
|
|||||||
return &i
|
return &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *ProgressBar) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *ProgressBar) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *ProgressBar) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *ProgressBar) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetProgress returns the curret progress value
|
// GetProgress returns the curret progress value
|
||||||
func (i *ProgressBar) GetProgress() int {
|
func (i *ProgressBar) GetProgress() int {
|
||||||
return i.progress
|
return i.progress
|
||||||
@ -138,20 +156,20 @@ func (i *ProgressBar) SetWidth(w int) {
|
|||||||
i.width = w
|
i.width = w
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackground Return the current background color of the modal
|
// GetFgColor returns the foreground color
|
||||||
func (i *ProgressBar) GetBackground() termbox.Attribute { return i.bg }
|
func (i *ProgressBar) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
// SetBackground Set the current background color to bg
|
// SetFgColor sets the foreground color
|
||||||
func (i *ProgressBar) SetBackground(bg termbox.Attribute) {
|
func (i *ProgressBar) SetFgColor(fg termbox.Attribute) {
|
||||||
i.bg = bg
|
i.fg = fg
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetForeground Return the current foreground color
|
// GetBgColor returns the background color
|
||||||
func (i *ProgressBar) GetForeground() termbox.Attribute { return i.fg }
|
func (i *ProgressBar) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
// SetForeground Set the foreground color to fg
|
// SetBgColor sets the current background color
|
||||||
func (i *ProgressBar) SetForeground(fg termbox.Attribute) {
|
func (i *ProgressBar) SetBgColor(bg termbox.Attribute) {
|
||||||
i.fg = fg
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align Tells which direction the progress bar empties
|
// Align Tells which direction the progress bar empties
|
||||||
@ -168,8 +186,8 @@ func (i *ProgressBar) SetColorized(c bool) {
|
|||||||
i.colorized = c
|
i.colorized = c
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress accepts the termbox event and returns whether it was consumed
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
func (i *ProgressBar) HandleKeyPress(event termbox.Event) bool {
|
func (i *ProgressBar) HandleEvent(event termbox.Event) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ import "github.com/nsf/termbox-go"
|
|||||||
// ScrollFrame is a frame for holding other elements
|
// ScrollFrame is a frame for holding other elements
|
||||||
// It manages it's own x/y, tab index
|
// It manages it's own x/y, tab index
|
||||||
type ScrollFrame struct {
|
type ScrollFrame struct {
|
||||||
|
id string
|
||||||
x, y, width, height int
|
x, y, width, height int
|
||||||
scrollX, scrollY int
|
scrollX, scrollY int
|
||||||
tabIdx int
|
tabIdx int
|
||||||
fg, bg termbox.Attribute
|
fg, bg termbox.Attribute
|
||||||
bordered bool
|
bordered bool
|
||||||
controls []termboxControl
|
controls []termboxControl
|
||||||
|
active bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateScrollFrame creates Scrolling Frame at x, y that is w by h
|
// CreateScrollFrame creates Scrolling Frame at x, y that is w by h
|
||||||
@ -19,92 +21,124 @@ func CreateScrollFrame(x, y, w, h int, fg, bg termbox.Attribute) *ScrollFrame {
|
|||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetActiveFlag sets this control's active flag
|
||||||
|
func (i *ScrollFrame) SetActiveFlag(b bool) {
|
||||||
|
i.active = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns whether this control is active
|
||||||
|
func (i *ScrollFrame) IsActive() bool { return i.active }
|
||||||
|
|
||||||
|
// GetID returns this control's ID
|
||||||
|
func (i *ScrollFrame) GetID() string { return i.id }
|
||||||
|
|
||||||
|
// SetID sets this control's ID
|
||||||
|
func (i *ScrollFrame) SetID(newID string) {
|
||||||
|
i.id = newID
|
||||||
|
}
|
||||||
|
|
||||||
// GetX returns the x position of the scroll frame
|
// GetX returns the x position of the scroll frame
|
||||||
func (s *ScrollFrame) GetX() int { return s.x }
|
func (i *ScrollFrame) GetX() int { return i.x }
|
||||||
|
|
||||||
// SetX sets the x position of the scroll frame
|
// SetX sets the x position of the scroll frame
|
||||||
func (s *ScrollFrame) SetX(x int) {
|
func (i *ScrollFrame) SetX(x int) {
|
||||||
s.x = x
|
i.x = x
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetY returns the y position of the scroll frame
|
// GetY returns the y position of the scroll frame
|
||||||
func (s *ScrollFrame) GetY() int { return s.y }
|
func (i *ScrollFrame) GetY() int { return i.y }
|
||||||
|
|
||||||
// SetY sets the y position of the scroll frame
|
// SetY sets the y position of the scroll frame
|
||||||
func (s *ScrollFrame) SetY(y int) {
|
func (i *ScrollFrame) SetY(y int) {
|
||||||
s.y = y
|
i.y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWidth returns the current width of the scroll frame
|
// GetWidth returns the current width of the scroll frame
|
||||||
func (s *ScrollFrame) GetWidth() int { return s.width }
|
func (i *ScrollFrame) GetWidth() int { return i.width }
|
||||||
|
|
||||||
// SetWidth sets the current width of the scroll frame
|
// SetWidth sets the current width of the scroll frame
|
||||||
func (s *ScrollFrame) SetWidth(w int) {
|
func (i *ScrollFrame) SetWidth(w int) {
|
||||||
s.width = w
|
i.width = w
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeight returns the current height of the scroll frame
|
// GetHeight returns the current height of the scroll frame
|
||||||
func (s *ScrollFrame) GetHeight() int { return s.height }
|
func (i *ScrollFrame) GetHeight() int { return i.height }
|
||||||
|
|
||||||
// SetHeight sets the current height of the scroll frame
|
// SetHeight sets the current height of the scroll frame
|
||||||
func (s *ScrollFrame) SetHeight(h int) {
|
func (i *ScrollFrame) SetHeight(h int) {
|
||||||
s.height = h
|
i.height = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFgColor returns the foreground color
|
||||||
|
func (i *ScrollFrame) GetFgColor() termbox.Attribute { return i.fg }
|
||||||
|
|
||||||
|
// SetFgColor sets the foreground color
|
||||||
|
func (i *ScrollFrame) SetFgColor(fg termbox.Attribute) {
|
||||||
|
i.fg = fg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBgColor returns the background color
|
||||||
|
func (i *ScrollFrame) GetBgColor() termbox.Attribute { return i.bg }
|
||||||
|
|
||||||
|
// SetBgColor sets the current background color
|
||||||
|
func (i *ScrollFrame) SetBgColor(bg termbox.Attribute) {
|
||||||
|
i.bg = bg
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBordered returns true or false if this scroll frame has a border
|
// IsBordered returns true or false if this scroll frame has a border
|
||||||
func (s *ScrollFrame) IsBordered() bool { return s.bordered }
|
func (i *ScrollFrame) IsBordered() bool { return i.bordered }
|
||||||
|
|
||||||
// SetBordered sets whether we render a border around the scroll frame
|
// SetBordered sets whether we render a border around the scroll frame
|
||||||
func (s *ScrollFrame) SetBordered(b bool) {
|
func (i *ScrollFrame) SetBordered(b bool) {
|
||||||
s.bordered = b
|
i.bordered = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScrollX returns the x distance scrolled
|
// GetScrollX returns the x distance scrolled
|
||||||
func (s *ScrollFrame) GetScrollX() int {
|
func (i *ScrollFrame) GetScrollX() int {
|
||||||
return s.scrollX
|
return i.scrollX
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScrollY returns the y distance scrolled
|
// GetScrollY returns the y distance scrolled
|
||||||
func (s *ScrollFrame) GetScrollY() int {
|
func (i *ScrollFrame) GetScrollY() int {
|
||||||
return s.scrollY
|
return i.scrollY
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollDown scrolls the frame down
|
// ScrollDown scrolls the frame down
|
||||||
func (s *ScrollFrame) ScrollDown() {
|
func (i *ScrollFrame) ScrollDown() {
|
||||||
s.scrollY++
|
i.scrollY++
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollUp scrolls the frame up
|
// ScrollUp scrolls the frame up
|
||||||
func (s *ScrollFrame) ScrollUp() {
|
func (i *ScrollFrame) ScrollUp() {
|
||||||
if s.scrollY > 0 {
|
if i.scrollY > 0 {
|
||||||
s.scrollY--
|
i.scrollY--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollLeft scrolls the frame left
|
// ScrollLeft scrolls the frame left
|
||||||
func (s *ScrollFrame) ScrollLeft() {
|
func (i *ScrollFrame) ScrollLeft() {
|
||||||
if s.scrollX > 0 {
|
if i.scrollX > 0 {
|
||||||
s.scrollX--
|
i.scrollX--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollRight scrolls the frame right
|
// ScrollRight scrolls the frame right
|
||||||
func (s *ScrollFrame) ScrollRight() {
|
func (i *ScrollFrame) ScrollRight() {
|
||||||
s.scrollX++
|
i.scrollX++
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddControl adds a control to the frame
|
// AddControl adds a control to the frame
|
||||||
func (s *ScrollFrame) AddControl(t termboxControl) {
|
func (i *ScrollFrame) AddControl(t termboxControl) {
|
||||||
s.controls = append(s.controls, t)
|
i.controls = append(i.controls, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawControl figures out the relative position of the control,
|
// DrawControl figures out the relative position of the control,
|
||||||
// sets it, draws it, then resets it.
|
// sets it, draws it, then resets it.
|
||||||
func (s *ScrollFrame) DrawControl(t termboxControl) {
|
func (i *ScrollFrame) DrawControl(t termboxControl) {
|
||||||
if s.IsVisible(t) {
|
if i.IsVisible(t) {
|
||||||
ctlX, ctlY := t.GetX(), t.GetY()
|
ctlX, ctlY := t.GetX(), t.GetY()
|
||||||
t.SetX((s.GetX() + ctlX))
|
t.SetX((i.GetX() + ctlX))
|
||||||
t.SetY((s.GetY() + ctlY))
|
t.SetY((i.GetY() + ctlY))
|
||||||
t.Draw()
|
t.Draw()
|
||||||
t.SetX(ctlX)
|
t.SetX(ctlX)
|
||||||
t.SetY(ctlY)
|
t.SetY(ctlY)
|
||||||
@ -113,35 +147,35 @@ func (s *ScrollFrame) DrawControl(t termboxControl) {
|
|||||||
|
|
||||||
// IsVisible takes a Termbox Control and returns whether
|
// IsVisible takes a Termbox Control and returns whether
|
||||||
// that control would be visible in the frame
|
// that control would be visible in the frame
|
||||||
func (s *ScrollFrame) IsVisible(t termboxControl) bool {
|
func (i *ScrollFrame) IsVisible(t termboxControl) bool {
|
||||||
// Check if any part of t should be visible
|
// Check if any part of t should be visible
|
||||||
cX, cY := t.GetX(), t.GetY()
|
cX, cY := t.GetX(), t.GetY()
|
||||||
if cX+t.GetWidth() >= s.scrollX && cX <= s.scrollX+s.width {
|
if cX+t.GetWidth() >= i.scrollX && cX <= i.scrollX+i.width {
|
||||||
return cY+t.GetHeight() >= s.scrollY && cY <= s.scrollY+s.height
|
return cY+t.GetHeight() >= i.scrollY && cY <= i.scrollY+i.height
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleKeyPress accepts the termbox event and returns whether it was consumed
|
// HandleEvent accepts the termbox event and returns whether it was consumed
|
||||||
func (s *ScrollFrame) HandleKeyPress(event termbox.Event) bool {
|
func (i *ScrollFrame) HandleEvent(event termbox.Event) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawToStrings generates a slice of strings with what should
|
// DrawToStrings generates a slice of strings with what should
|
||||||
// be drawn to the screen
|
// be drawn to the screen
|
||||||
func (s *ScrollFrame) DrawToStrings() []string {
|
func (i *ScrollFrame) DrawToStrings() []string {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw outputs the Scoll Frame on the screen
|
// Draw outputs the Scoll Frame on the screen
|
||||||
func (s *ScrollFrame) Draw() {
|
func (i *ScrollFrame) Draw() {
|
||||||
maxWidth := s.width
|
maxWidth := i.width
|
||||||
maxHeight := s.height
|
maxHeight := i.height
|
||||||
x, y := s.x, s.y
|
x, y := i.x, i.y
|
||||||
startX := s.x
|
startX := i.x
|
||||||
startY := s.y
|
startY := i.y
|
||||||
if s.bordered {
|
if i.bordered {
|
||||||
DrawBorder(s.x, s.y, s.x+s.width, s.y+s.height, s.fg, s.bg)
|
DrawBorder(i.x, i.y, i.x+i.width, i.y+i.height, i.fg, i.bg)
|
||||||
maxWidth--
|
maxWidth--
|
||||||
maxHeight--
|
maxHeight--
|
||||||
x++
|
x++
|
||||||
@ -149,7 +183,7 @@ func (s *ScrollFrame) Draw() {
|
|||||||
startX++
|
startX++
|
||||||
startY++
|
startY++
|
||||||
}
|
}
|
||||||
for i := range s.controls {
|
for idx := range i.controls {
|
||||||
s.DrawControl(s.controls[i])
|
i.DrawControl(i.controls[idx])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type termboxControl interface {
|
type termboxControl interface {
|
||||||
|
GetID() string
|
||||||
GetX() int
|
GetX() int
|
||||||
SetX(int)
|
SetX(int)
|
||||||
GetY() int
|
GetY() int
|
||||||
@ -16,7 +17,17 @@ type termboxControl interface {
|
|||||||
SetWidth(int)
|
SetWidth(int)
|
||||||
GetHeight() int
|
GetHeight() int
|
||||||
SetHeight(int)
|
SetHeight(int)
|
||||||
HandleKeyPress(termbox.Event) bool
|
GetFgColor() termbox.Attribute
|
||||||
|
SetFgColor(termbox.Attribute)
|
||||||
|
GetBgColor() termbox.Attribute
|
||||||
|
SetBgColor(termbox.Attribute)
|
||||||
|
HandleEvent(termbox.Event) bool
|
||||||
|
IsBordered() bool
|
||||||
|
SetBordered(bool)
|
||||||
|
SetTabSkip(bool)
|
||||||
|
IsTabSkipped() bool
|
||||||
|
IsActive() bool
|
||||||
|
SetActiveFlag(bool)
|
||||||
Draw()
|
Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,21 +123,28 @@ func DrawBorder(x1, y1, x2, y2 int, fg termbox.Attribute, bg termbox.Attribute)
|
|||||||
|
|
||||||
// AlignText Aligns the text txt within width characters using the specified alignment
|
// AlignText Aligns the text txt within width characters using the specified alignment
|
||||||
func AlignText(txt string, width int, align TextAlignment) string {
|
func AlignText(txt string, width int, align TextAlignment) string {
|
||||||
|
return AlignTextWithFill(txt, width, align, ' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AlignTextWithFill Aligns the text txt within width characters using the specified alignment
|
||||||
|
// filling any spaces with the 'fill' character
|
||||||
|
func AlignTextWithFill(txt string, width int, align TextAlignment, fill rune) string {
|
||||||
|
fillChar := string(fill)
|
||||||
numSpaces := width - len(txt)
|
numSpaces := width - len(txt)
|
||||||
switch align {
|
switch align {
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
if numSpaces/2 > 0 {
|
if numSpaces/2 > 0 {
|
||||||
return fmt.Sprintf("%s%s%s",
|
return fmt.Sprintf("%s%s%s",
|
||||||
strings.Repeat(" ", numSpaces/2),
|
strings.Repeat(fillChar, numSpaces/2),
|
||||||
txt, strings.Repeat(" ", numSpaces/2),
|
txt, strings.Repeat(fillChar, numSpaces/2),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return txt
|
return txt
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
return fmt.Sprintf("%s%s", strings.Repeat(" ", numSpaces), txt)
|
return fmt.Sprintf("%s%s", strings.Repeat(fillChar, numSpaces), txt)
|
||||||
default:
|
default:
|
||||||
if numSpaces >= 0 {
|
if numSpaces >= 0 {
|
||||||
return fmt.Sprintf("%s%s", txt, strings.Repeat(" ", numSpaces))
|
return fmt.Sprintf("%s%s", txt, strings.Repeat(fillChar, numSpaces))
|
||||||
}
|
}
|
||||||
return txt
|
return txt
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user