qedit/gotolinedialog.go

133 lines
3.1 KiB
Go
Executable File

package main
import (
"strconv"
"strings"
"github.com/gdamore/tcell/v2"
"github.com/fivemoreminix/qedit/ui"
)
type GotoLineDialog struct {
LineChosenCallback func(int)
x, y int
width, height int
focused bool
screen *tcell.Screen
theme *ui.Theme
tabOrder []ui.Component
tabOrderIdx int
inputField *ui.InputField
acceptButton *ui.Button
cancelButton *ui.Button
}
func NewGotoLineDialog(s *tcell.Screen, theme *ui.Theme, lineChosenCallback func(int), cancelCallback func()) *GotoLineDialog {
dialog := &GotoLineDialog{
LineChosenCallback: lineChosenCallback,
screen: s,
theme: theme,
}
dialog.inputField = ui.NewInputField(s, nil, theme.GetOrDefault("Window"))
dialog.acceptButton = ui.NewButton("Go", theme, dialog.onConfirm) // TODO: callback
dialog.cancelButton = ui.NewButton("Cancel", theme, cancelCallback)
dialog.tabOrder = []ui.Component{dialog.inputField, dialog.cancelButton, dialog.acceptButton}
return dialog
}
func (d *GotoLineDialog) onConfirm() {
if d.LineChosenCallback != nil {
if len(d.inputField.Buffer) > 0 {
num, err := strconv.Atoi(strings.TrimSpace(string(d.inputField.Buffer)))
if err == nil {
d.LineChosenCallback(num)
}
}
}
}
func (d *GotoLineDialog) Draw(s tcell.Screen) {
ui.DrawWindow(s, d.x, d.y, d.width, d.height, "Go to line", d.theme)
btnWidth, _ := d.acceptButton.GetSize()
d.acceptButton.SetPos(d.x+d.width-btnWidth-1, d.y+4) // Place "Ok" button on right, bottom
d.inputField.Draw(s)
d.acceptButton.Draw(s)
d.cancelButton.Draw(s)
}
func (d *GotoLineDialog) SetFocused(v bool) {
d.focused = v
d.tabOrder[d.tabOrderIdx].SetFocused(v)
}
func (d *GotoLineDialog) SetTheme(theme *ui.Theme) {
d.theme = theme
d.inputField.SetStyle(theme.GetOrDefault("Window"))
d.acceptButton.SetTheme(theme)
d.cancelButton.SetTheme(theme)
}
func (d *GotoLineDialog) GetPos() (int, int) {
return d.x, d.y
}
func (d *GotoLineDialog) SetPos(x, y int) {
d.x, d.y = x, y
d.inputField.SetPos(d.x+1, d.y+2) // Center input field
d.cancelButton.SetPos(d.x+1, d.y+4) // Place "Cancel" button on left, bottom
}
func (d *GotoLineDialog) GetMinSize() (int, int) {
return 20, 6
}
func (d *GotoLineDialog) GetSize() (int, int) {
return d.width, d.height
}
func (d *GotoLineDialog) SetSize(width, height int) {
minX, minY := d.GetMinSize()
d.width, d.height = ui.Max(width, minX), ui.Max(height, minY)
d.inputField.SetSize(d.width-2, 1)
d.cancelButton.SetSize(d.cancelButton.GetMinSize())
d.acceptButton.SetSize(d.acceptButton.GetMinSize())
}
func (d *GotoLineDialog) HandleEvent(event tcell.Event) bool {
switch ev := event.(type) {
case *tcell.EventKey:
switch ev.Key() {
case tcell.KeyTab:
d.tabOrder[d.tabOrderIdx].SetFocused(false)
d.tabOrderIdx++
if d.tabOrderIdx >= len(d.tabOrder) {
d.tabOrderIdx = 0
}
d.tabOrder[d.tabOrderIdx].SetFocused(true)
return true
case tcell.KeyEsc:
if d.cancelButton.Callback != nil {
d.cancelButton.Callback()
}
return true
case tcell.KeyEnter:
if d.tabOrder[d.tabOrderIdx] == d.inputField {
d.onConfirm()
return true
}
}
}
return d.tabOrder[d.tabOrderIdx].HandleEvent(event)
}