From 802ed976a94fc366f5dacfa2d114bbc0a2cadf02 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 May 2024 12:10:47 +0530 Subject: [PATCH] Start work on faces panel --- kittens/choose_fonts/faces.go | 69 +++++++++++++++++++++++++++++++++++ kittens/choose_fonts/list.go | 24 +++++++++--- kittens/choose_fonts/ui.go | 45 +++++++++++++++-------- tools/utils/strings.go | 2 + 4 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 kittens/choose_fonts/faces.go diff --git a/kittens/choose_fonts/faces.go b/kittens/choose_fonts/faces.go new file mode 100644 index 000000000..9181f434b --- /dev/null +++ b/kittens/choose_fonts/faces.go @@ -0,0 +1,69 @@ +package choose_fonts + +import ( + "fmt" + "kitty/tools/tui/loop" + "kitty/tools/utils" +) + +var _ = fmt.Print + +type faces struct { + handler *handler + + family string + settings struct { + font_family, bold_font, italic_font, bold_italic_font string + } +} + +func (self *faces) draw_screen() (err error) { + self.handler.lp.SetCursorVisible(false) + sz, _ := self.handler.lp.ScreenSize() + lines := []string{self.handler.format_title(self.family, 0), ""} + _, _, str := self.handler.render_lines.InRectangle(lines, 0, 0, int(sz.WidthCells), int(sz.HeightCells), &self.handler.mouse_state, self.on_click) + self.handler.lp.QueueWriteString(str) + return +} + +func (self *faces) initialize(h *handler) (err error) { + self.handler = h + return +} + +func (self *faces) on_wakeup() error { + return self.handler.draw_screen() +} + +func (self *faces) on_click(id string) (err error) { + return +} + +func (self *faces) on_key_event(event *loop.KeyEvent) (err error) { + if event.MatchesPressOrRepeat("esc") { + event.Handled = true + self.handler.current_pane = &self.handler.listing + return self.handler.draw_screen() + } + return +} + +func (self *faces) on_text(text string, from_key_event bool, in_bracketed_paste bool) (err error) { + return +} + +func (self *faces) on_enter(family string) error { + if family != "" { + self.family = family + r := self.handler.listing.resolved_faces_from_kitty_conf + d := func(conf ResolvedFace, setting *string, defval string) { + *setting = utils.IfElse(family == conf.Family, conf.Spec, defval) + } + d(r.Font_family, &self.settings.font_family, family) + d(r.Bold_font, &self.settings.bold_font, "auto") + d(r.Italic_font, &self.settings.italic_font, "auto") + d(r.Bold_italic_font, &self.settings.bold_italic_font, "auto") + } + self.handler.current_pane = self + return self.handler.draw_screen() +} diff --git a/kittens/choose_fonts/list.go b/kittens/choose_fonts/list.go index 1e109abf6..e2149c516 100644 --- a/kittens/choose_fonts/list.go +++ b/kittens/choose_fonts/list.go @@ -30,11 +30,12 @@ type FontList struct { preview_cache_mutex sync.Mutex } -func (self *FontList) initialize(h *handler) { +func (self *FontList) initialize(h *handler) error { self.handler = h self.preview_cache = make(map[preview_cache_key]string) self.rl = readline.New(h.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "Family: "}) self.variable_data_requested_for = utils.NewSet[string](256) + return nil } func (self *FontList) draw_search_bar() { @@ -58,16 +59,18 @@ func center_string(x string, width int) string { return strings.Repeat(" ", utils.Max(0, spaces)) + x } +func (self *handler) format_title(title string, start_x int) string { + sz, _ := self.lp.ScreenSize() + return self.lp.SprintStyled("fg=green bold", center_string(title, int(sz.WidthCells)-start_x)) +} + func (self *FontList) draw_family_summary(start_x int, sz loop.ScreenSize) (err error) { lp := self.handler.lp family := self.family_list.CurrentFamily() if family == "" || int(sz.WidthCells) < start_x+2 { return nil } - lines := []string{ - lp.SprintStyled("fg=green bold", center_string(family, int(sz.WidthCells)-start_x)), - "", - } + lines := []string{self.handler.format_title(family, start_x), ""} width := int(sz.WidthCells) - start_x - 1 add_line := func(x string) { lines = append(lines, style.WrapTextAsLines(x, width, style.WrapOptions{})...) @@ -157,9 +160,10 @@ func (self *FontList) draw_preview(x, y int, sz loop.ScreenSize) (err error) { return } -func (self *FontList) on_wakeup() { +func (self *FontList) on_wakeup() error { self.family_list.UpdateFamilies(utils.StableSortWithKey(utils.Keys(self.fonts), strings.ToLower)) self.family_list.SelectFamily(self.resolved_faces_from_kitty_conf.Font_family.Family) + return self.handler.draw_screen() } func (self *FontList) draw_screen() (err error) { @@ -235,6 +239,14 @@ func (self *FontList) next(delta int, allow_wrapping bool) { } func (self *FontList) on_key_event(event *loop.KeyEvent) (err error) { + if event.MatchesPressOrRepeat("enter") { + event.Handled = true + if family := self.family_list.CurrentFamily(); family != "" { + return self.handler.faces.on_enter(family) + } + self.handler.lp.Beep() + return + } if event.MatchesPressOrRepeat("esc") { event.Handled = true if self.rl.AllText() != "" { diff --git a/kittens/choose_fonts/ui.go b/kittens/choose_fonts/ui.go index 74b510153..ba86fa8b0 100644 --- a/kittens/choose_fonts/ui.go +++ b/kittens/choose_fonts/ui.go @@ -30,6 +30,15 @@ type TextStyle struct { Background string `json:"background"` } +type pane interface { + initialize(*handler) error + draw_screen() error + on_wakeup() error + on_key_event(event *loop.KeyEvent) error + on_text(text string, from_key_event bool, in_bracketed_paste bool) error + on_click(id string) error +} + type handler struct { lp *loop.Loop state State @@ -43,6 +52,10 @@ type handler struct { temp_dir string listing FontList + faces faces + + panes []pane + current_pane pane } func (h *handler) set_worker_error(err error) { @@ -62,7 +75,12 @@ func (h *handler) initialize() (err error) { h.lp.SetCursorVisible(false) h.lp.OnQueryResponse = h.on_query_response h.lp.QueryTerminal("font_size", "dpi_x", "dpi_y", "foreground", "background") - h.listing.initialize(h) + h.panes = []pane{&h.listing, &h.faces} + for _, pane := range h.panes { + if err = pane.initialize(h); err != nil { + return err + } + } // dont use /tmp as it may be mounted in RAM, Le Sigh if h.temp_dir, err = os.MkdirTemp(utils.CacheDir(), "kitten-choose-fonts-*"); err != nil { return @@ -136,11 +154,10 @@ func (h *handler) draw_screen() (err error) { h.lp.ClearScreenButNotGraphics() h.lp.AllowLineWrapping(false) h.mouse_state.ClearCellRegions() - switch h.state { - case SCANNING_FAMILIES: + if h.current_pane == nil { h.lp.Println("Scanning system for fonts, please wait...") - case LISTING_FAMILIES: - return h.listing.draw_screen() + } else { + return h.current_pane.draw_screen() } return } @@ -149,12 +166,10 @@ func (h *handler) on_wakeup() (err error) { if err = h.get_worker_error(); err != nil { return } - switch h.state { - case SCANNING_FAMILIES: - h.state = LISTING_FAMILIES - h.listing.on_wakeup() + if h.current_pane == nil { + h.current_pane = &h.listing } - return h.draw_screen() + return h.listing.on_wakeup() } func (h *handler) on_mouse_event(event *loop.MouseEvent) (err error) { @@ -179,17 +194,15 @@ func (h *handler) on_key_event(event *loop.KeyEvent) (err error) { event.Handled = true return fmt.Errorf("canceled by user") } - switch h.state { - case LISTING_FAMILIES: - return h.listing.on_key_event(event) + if h.current_pane != nil { + err = h.current_pane.on_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.listing.on_text(text, from_key_event, in_bracketed_paste) + if h.current_pane != nil { + err = h.current_pane.on_text(text, from_key_event, in_bracketed_paste) } return } diff --git a/tools/utils/strings.go b/tools/utils/strings.go index 1373b4b6f..37bfbdad2 100644 --- a/tools/utils/strings.go +++ b/tools/utils/strings.go @@ -167,3 +167,5 @@ func RuneOffsetsToByteOffsets(text string) func(int) int { return self.byte_offset } } + +func Repr(x any) string { return fmt.Sprintf("%#v", x) }