Files
kitty/tools/cmd/list_fonts/ui.go
2024-06-22 11:16:36 +05:30

172 lines
3.5 KiB
Go

package list_fonts
import (
"fmt"
"strings"
"kitty/tools/tui/loop"
"kitty/tools/tui/readline"
"kitty/tools/utils"
"golang.org/x/exp/maps"
)
var _ = fmt.Print
type State int
const (
LISTING_FAMILIES State = iota
CHOOSING_FACES
)
type handler struct {
lp *loop.Loop
fonts map[string][]ListedFont
state State
// Listing
rl *readline.Readline
family_list FamilyList
}
// Listing families {{{
func (h *handler) draw_search_bar() {
h.lp.SetCursorVisible(true)
h.lp.SetCursorShape(loop.BAR_CURSOR, true)
sz, err := h.lp.ScreenSize()
if err != nil {
return
}
h.lp.MoveCursorTo(1, int(sz.HeightCells))
h.lp.ClearToEndOfLine()
h.rl.RedrawNonAtomic()
}
const SEPARATOR = "║"
func (h *handler) draw_family_summary() (err error) {
// TODO: Implement me
return
}
func (h *handler) draw_listing_screen() (err error) {
sz, err := h.lp.ScreenSize()
if err != nil {
return err
}
num_rows := max(0, int(sz.HeightCells)-1)
mw := h.family_list.max_width + 1
green_fg, _, _ := strings.Cut(h.lp.SprintStyled("fg=green", "|"), "|")
for _, l := range h.family_list.Lines(num_rows) {
line := l.text
if l.is_current {
line = strings.ReplaceAll(line, MARK_AFTER, green_fg)
h.lp.PrintStyled("fg=green", ">")
h.lp.PrintStyled("fg=green bold", line)
} else {
h.lp.PrintStyled("fg=green", " ")
h.lp.QueueWriteString(line)
}
h.lp.MoveCursorHorizontally(mw - l.width)
h.lp.Println(SEPARATOR)
num_rows--
}
for ; num_rows > 0; num_rows-- {
h.lp.MoveCursorHorizontally(mw + 1)
h.lp.Println(SEPARATOR)
}
if h.family_list.Len() > 0 {
if err = h.draw_family_summary(); err != nil {
return err
}
}
h.draw_search_bar()
return
}
func (h *handler) update_family_search() {
text := h.rl.AllText()
if h.family_list.UpdateSearch(text) {
h.draw_screen()
} else {
h.draw_search_bar()
}
}
func (h *handler) handle_listing_key_event(event *loop.KeyEvent) (err error) {
if event.MatchesPressOrRepeat("ctrl+c") || event.MatchesPressOrRepeat("esc") {
h.lp.Quit(1)
event.Handled = true
return
}
if err = h.rl.OnKeyEvent(event); err != nil {
if err == readline.ErrAcceptInput {
return nil
}
return err
}
if event.Handled {
h.update_family_search()
}
h.draw_search_bar()
return
}
func (h *handler) handle_listing_text(text string, from_key_event bool, in_bracketed_paste bool) (err error) {
if err = h.rl.OnText(text, from_key_event, in_bracketed_paste); err != nil {
return err
}
h.update_family_search()
return
}
// }}}
// Events {{{
func (h *handler) initialize() {
h.lp.SetCursorVisible(false)
h.family_list.UpdateFamilies(utils.StableSortWithKey(maps.Keys(h.fonts), strings.ToLower))
h.rl = readline.New(h.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "Family: "})
h.draw_screen()
}
func (h *handler) finalize() {
h.lp.SetCursorVisible(true)
h.lp.SetCursorShape(loop.BLOCK_CURSOR, true)
}
func (h *handler) draw_screen() (err error) {
h.lp.StartAtomicUpdate()
defer h.lp.EndAtomicUpdate()
h.lp.ClearScreen()
h.lp.AllowLineWrapping(false)
switch h.state {
case LISTING_FAMILIES:
return h.draw_listing_screen()
}
return
}
func (h *handler) on_wakeup() (err error) {
return
}
func (h *handler) on_key_event(event *loop.KeyEvent) (err error) {
switch h.state {
case LISTING_FAMILIES:
return h.handle_listing_key_event(event)
}
return
}
func (h *handler) on_text(text string, from_key_event bool, in_bracketed_paste bool) (err error) {
switch h.state {
case LISTING_FAMILIES:
return h.handle_listing_text(text, from_key_event, in_bracketed_paste)
}
return
}
// }}}