133 lines
3.2 KiB
Go
133 lines
3.2 KiB
Go
package ui
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/fivemoreminix/qedit/pkg/ui"
|
|
"github.com/gdamore/tcell/v2"
|
|
)
|
|
|
|
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)
|
|
}
|