diff --git a/kittens/choose_fonts/face.go b/kittens/choose_fonts/face.go index fb67e5360..a7db6deec 100644 --- a/kittens/choose_fonts/face.go +++ b/kittens/choose_fonts/face.go @@ -2,9 +2,12 @@ package choose_fonts import ( "fmt" - "kitty/tools/tui/loop" "math" + "strings" "sync" + + "kitty/tools/tui" + "kitty/tools/tui/loop" ) var _ = fmt.Print @@ -14,11 +17,31 @@ type face_panel struct { family, which string settings faces_settings - setting string preview_cache map[faces_preview_key]map[string]RenderedSampleTransmit preview_cache_mutex sync.Mutex } +func (self *face_panel) draw_variable_fine_tune(sz loop.ScreenSize, start_y int, preview RenderedSampleTransmit) (y int, err error) { + y = start_y + return +} + +func (self *face_panel) draw_family_style_select(sz loop.ScreenSize, start_y int) (y int, err error) { + s := styles_in_family(self.family, self.handler.listing.fonts[self.family]) + lines := []string{} + for _, sg := range s.style_groups { + formatted := make([]string, len(sg.styles)) + for i, style_name := range sg.styles { + formatted[i] = tui.InternalHyperlink(style_name, "style:"+style_name) + } + line := sg.name + ": " + strings.Join(formatted, ", ") + lines = append(lines, line) + } + _, y, str := self.handler.render_lines.InRectangle(lines, 0, start_y, int(sz.WidthCells), int(sz.HeightCells)-start_y, &self.handler.mouse_state, self.on_click) + self.handler.lp.QueueWriteString(str) + return y, nil +} + func (self *face_panel) draw_screen() (err error) { lp := self.handler.lp lp.SetCursorVisible(false) @@ -34,12 +57,15 @@ func (self *face_panel) draw_screen() (err error) { wt = "Bold-Italic font" } + lp.QueueWriteString(self.handler.format_title(fmt.Sprintf("%s: %s face", self.family, wt), 0)) + lines := []string{ - self.handler.format_title(self.family+": "+wt, 0), "", - fmt.Sprintf("Press %s to select this face or %s to cancel. Click on a style name below to switch to it.", styled("fg=green", "Enter"), styled("fg=red", "Esc")), "", + fmt.Sprintf("Press %s to accept any changes or %s to cancel. Click on a style name below to switch to it.", styled("fg=green", "Enter"), styled("fg=red", "Esc")), "", + fmt.Sprintf("Current setting: %s", self.get()), "", } - _, y, str := self.handler.render_lines.InRectangle(lines, 0, 0, int(sz.WidthCells), int(sz.HeightCells), &self.handler.mouse_state, self.on_click) + _, y, str := self.handler.render_lines.InRectangle(lines, 0, 2, int(sz.WidthCells), int(sz.HeightCells)-2, &self.handler.mouse_state, self.on_click) lp.QueueWriteString(str) + num_lines_per_font := (int(sz.HeightCells) - y - 1) - 2 num_lines_needed := int(math.Ceil(100. / float64(sz.WidthCells))) num_lines := max(1, min(num_lines_per_font, num_lines_needed)) @@ -67,7 +93,18 @@ func (self *face_panel) draw_screen() (err error) { if len(previews) < 4 { return } + preview := previews[self.which] + if len(preview.Variable_data.Axes) > 0 { + y, err = self.draw_variable_fine_tune(sz, y, preview) + } else { + y, err = self.draw_family_style_select(sz, y) + } + if err != nil { + return err + } + lp.MoveCursorTo(1, y+2) + self.handler.graphics_manager.display_image(0, preview.Path, key.width, key.height) return } @@ -81,8 +118,40 @@ func (self *face_panel) on_wakeup() error { return self.handler.draw_screen() } +func (self *face_panel) get() string { + switch self.which { + case "font_family": + return self.settings.font_family + case "bold_font": + return self.settings.bold_font + case "italic_font": + return self.settings.italic_font + case "bold_italic_font": + return self.settings.bold_italic_font + } + panic(fmt.Sprintf("Unknown self.which value: %s", self.which)) +} + +func (self *face_panel) set(setting string) { + switch self.which { + case "font_family": + self.settings.font_family = setting + case "bold_font": + self.settings.bold_font = setting + case "italic_font": + self.settings.italic_font = setting + case "bold_italic_font": + self.settings.bold_italic_font = setting + } +} + func (self *face_panel) on_click(id string) (err error) { - return + scheme, val, _ := strings.Cut(id, ":") + switch scheme { + case "style": + self.set(fmt.Sprintf(`family="%s" style="%s"`, self.family, val)) + } + return self.handler.draw_screen() } func (self *face_panel) on_key_event(event *loop.KeyEvent) (err error) { @@ -90,6 +159,11 @@ func (self *face_panel) on_key_event(event *loop.KeyEvent) (err error) { event.Handled = true self.handler.current_pane = &self.handler.faces return self.handler.draw_screen() + } else if event.MatchesPressOrRepeat("enter") { + event.Handled = true + self.handler.current_pane = &self.handler.faces + self.handler.faces.settings = self.settings + return self.handler.draw_screen() } return } diff --git a/kittens/choose_fonts/faces.go b/kittens/choose_fonts/faces.go index 9cbcd0642..3a34c8bdf 100644 --- a/kittens/choose_fonts/faces.go +++ b/kittens/choose_fonts/faces.go @@ -34,11 +34,11 @@ func (self *faces) draw_screen() (err error) { lp.SetCursorVisible(false) sz, _ := lp.ScreenSize() styled := lp.SprintStyled + lp.QueueWriteString(self.handler.format_title(self.family, 0)) lines := []string{ - self.handler.format_title(self.family, 0), "", fmt.Sprintf("Press %s to select this font, %s to go back to the font list or any of the %s keys below to fine-tune the appearance of the individual font styles.", styled("fg=green", "Enter"), styled("fg=red", "Esc"), styled("fg=magenta bold", "highlighted")), "", } - _, y, str := self.handler.render_lines.InRectangle(lines, 0, 0, int(sz.WidthCells), int(sz.HeightCells), &self.handler.mouse_state, self.on_click) + _, y, str := self.handler.render_lines.InRectangle(lines, 0, 2, int(sz.WidthCells), int(sz.HeightCells), &self.handler.mouse_state, self.on_click) lp.QueueWriteString(str) diff --git a/kittens/choose_fonts/styles.go b/kittens/choose_fonts/styles.go index a8706ee3d..0358aa2f6 100644 --- a/kittens/choose_fonts/styles.go +++ b/kittens/choose_fonts/styles.go @@ -3,6 +3,7 @@ package choose_fonts import ( "fmt" "kitty/tools/utils" + "slices" ) var _ = fmt.Print @@ -80,5 +81,8 @@ func styles_in_family(family string, fonts []ListedFont) (ans *family_style_data } } } + for _, sg := range ans.style_groups { + slices.Sort(sg.styles) + } return } diff --git a/tools/tui/render_lines.go b/tools/tui/render_lines.go index ea9f4e6d0..b5d462dcb 100644 --- a/tools/tui/render_lines.go +++ b/tools/tui/render_lines.go @@ -20,7 +20,6 @@ func InternalHyperlink(text, id string) string { } type RenderLines struct { - WrapOptions style.WrapOptions } var hyperlink_pat = sync.OnceValue(func() *regexp.Regexp { @@ -102,10 +101,11 @@ func (r RenderLines) InRectangle( } all_rendered = true + wo := style.WrapOptions{Trim_whitespace: true} for _, line := range lines { wrapped_lines := []string{line} if width > 0 { - wrapped_lines = style.WrapTextAsLines(line, width, r.WrapOptions) + wrapped_lines = style.WrapTextAsLines(line, width, wo) } for _, line := range wrapped_lines { move_cursor(start_x, y)