Add GotoLineDialog and Search->Go to line functionality
This commit is contained in:
parent
3982628653
commit
ccb096a3f6
132
gotolinedialog.go
Executable file
132
gotolinedialog.go
Executable file
@ -0,0 +1,132 @@
|
|||||||
|
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)
|
||||||
|
}
|
13
main.go
13
main.go
@ -347,8 +347,19 @@ func main() {
|
|||||||
}}, &ui.ItemSeparator{}, &ui.ItemEntry{Name: "Go to line...", Shortcut: "Ctrl+G", Callback: func() {
|
}}, &ui.ItemSeparator{}, &ui.ItemEntry{Name: "Go to line...", Shortcut: "Ctrl+G", Callback: func() {
|
||||||
te := getActiveTextEdit()
|
te := getActiveTextEdit()
|
||||||
if te != nil {
|
if te != nil {
|
||||||
line := 50
|
callback := func(line int) {
|
||||||
|
te := getActiveTextEdit()
|
||||||
te.SetLineCol(line-1, 0)
|
te.SetLineCol(line-1, 0)
|
||||||
|
// Hide dialog
|
||||||
|
dialog = nil
|
||||||
|
changeFocus(tabContainer)
|
||||||
|
}
|
||||||
|
dialog = NewGotoLineDialog(screen, &theme, callback, func() {
|
||||||
|
// Dialog canceled
|
||||||
|
dialog = nil
|
||||||
|
changeFocus(tabContainer)
|
||||||
|
})
|
||||||
|
changeFocus(dialog)
|
||||||
}
|
}
|
||||||
}}})
|
}}})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user