mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-20 07:24:41 +02:00
Start work on faces panel
This commit is contained in:
69
kittens/choose_fonts/faces.go
Normal file
69
kittens/choose_fonts/faces.go
Normal file
@@ -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()
|
||||||
|
}
|
||||||
@@ -30,11 +30,12 @@ type FontList struct {
|
|||||||
preview_cache_mutex sync.Mutex
|
preview_cache_mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FontList) initialize(h *handler) {
|
func (self *FontList) initialize(h *handler) error {
|
||||||
self.handler = h
|
self.handler = h
|
||||||
self.preview_cache = make(map[preview_cache_key]string)
|
self.preview_cache = make(map[preview_cache_key]string)
|
||||||
self.rl = readline.New(h.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "Family: "})
|
self.rl = readline.New(h.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "Family: "})
|
||||||
self.variable_data_requested_for = utils.NewSet[string](256)
|
self.variable_data_requested_for = utils.NewSet[string](256)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FontList) draw_search_bar() {
|
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
|
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) {
|
func (self *FontList) draw_family_summary(start_x int, sz loop.ScreenSize) (err error) {
|
||||||
lp := self.handler.lp
|
lp := self.handler.lp
|
||||||
family := self.family_list.CurrentFamily()
|
family := self.family_list.CurrentFamily()
|
||||||
if family == "" || int(sz.WidthCells) < start_x+2 {
|
if family == "" || int(sz.WidthCells) < start_x+2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
lines := []string{
|
lines := []string{self.handler.format_title(family, start_x), ""}
|
||||||
lp.SprintStyled("fg=green bold", center_string(family, int(sz.WidthCells)-start_x)),
|
|
||||||
"",
|
|
||||||
}
|
|
||||||
width := int(sz.WidthCells) - start_x - 1
|
width := int(sz.WidthCells) - start_x - 1
|
||||||
add_line := func(x string) {
|
add_line := func(x string) {
|
||||||
lines = append(lines, style.WrapTextAsLines(x, width, style.WrapOptions{})...)
|
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
|
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.UpdateFamilies(utils.StableSortWithKey(utils.Keys(self.fonts), strings.ToLower))
|
||||||
self.family_list.SelectFamily(self.resolved_faces_from_kitty_conf.Font_family.Family)
|
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) {
|
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) {
|
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") {
|
if event.MatchesPressOrRepeat("esc") {
|
||||||
event.Handled = true
|
event.Handled = true
|
||||||
if self.rl.AllText() != "" {
|
if self.rl.AllText() != "" {
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ type TextStyle struct {
|
|||||||
Background string `json:"background"`
|
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 {
|
type handler struct {
|
||||||
lp *loop.Loop
|
lp *loop.Loop
|
||||||
state State
|
state State
|
||||||
@@ -43,6 +52,10 @@ type handler struct {
|
|||||||
temp_dir string
|
temp_dir string
|
||||||
|
|
||||||
listing FontList
|
listing FontList
|
||||||
|
faces faces
|
||||||
|
|
||||||
|
panes []pane
|
||||||
|
current_pane pane
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) set_worker_error(err error) {
|
func (h *handler) set_worker_error(err error) {
|
||||||
@@ -62,7 +75,12 @@ func (h *handler) initialize() (err error) {
|
|||||||
h.lp.SetCursorVisible(false)
|
h.lp.SetCursorVisible(false)
|
||||||
h.lp.OnQueryResponse = h.on_query_response
|
h.lp.OnQueryResponse = h.on_query_response
|
||||||
h.lp.QueryTerminal("font_size", "dpi_x", "dpi_y", "foreground", "background")
|
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
|
// 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 {
|
if h.temp_dir, err = os.MkdirTemp(utils.CacheDir(), "kitten-choose-fonts-*"); err != nil {
|
||||||
return
|
return
|
||||||
@@ -136,11 +154,10 @@ func (h *handler) draw_screen() (err error) {
|
|||||||
h.lp.ClearScreenButNotGraphics()
|
h.lp.ClearScreenButNotGraphics()
|
||||||
h.lp.AllowLineWrapping(false)
|
h.lp.AllowLineWrapping(false)
|
||||||
h.mouse_state.ClearCellRegions()
|
h.mouse_state.ClearCellRegions()
|
||||||
switch h.state {
|
if h.current_pane == nil {
|
||||||
case SCANNING_FAMILIES:
|
|
||||||
h.lp.Println("Scanning system for fonts, please wait...")
|
h.lp.Println("Scanning system for fonts, please wait...")
|
||||||
case LISTING_FAMILIES:
|
} else {
|
||||||
return h.listing.draw_screen()
|
return h.current_pane.draw_screen()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -149,12 +166,10 @@ func (h *handler) on_wakeup() (err error) {
|
|||||||
if err = h.get_worker_error(); err != nil {
|
if err = h.get_worker_error(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch h.state {
|
if h.current_pane == nil {
|
||||||
case SCANNING_FAMILIES:
|
h.current_pane = &h.listing
|
||||||
h.state = LISTING_FAMILIES
|
|
||||||
h.listing.on_wakeup()
|
|
||||||
}
|
}
|
||||||
return h.draw_screen()
|
return h.listing.on_wakeup()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) on_mouse_event(event *loop.MouseEvent) (err error) {
|
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
|
event.Handled = true
|
||||||
return fmt.Errorf("canceled by user")
|
return fmt.Errorf("canceled by user")
|
||||||
}
|
}
|
||||||
switch h.state {
|
if h.current_pane != nil {
|
||||||
case LISTING_FAMILIES:
|
err = h.current_pane.on_key_event(event)
|
||||||
return h.listing.on_key_event(event)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) on_text(text string, from_key_event bool, in_bracketed_paste bool) (err error) {
|
func (h *handler) on_text(text string, from_key_event bool, in_bracketed_paste bool) (err error) {
|
||||||
switch h.state {
|
if h.current_pane != nil {
|
||||||
case LISTING_FAMILIES:
|
err = h.current_pane.on_text(text, from_key_event, in_bracketed_paste)
|
||||||
return h.listing.on_text(text, from_key_event, in_bracketed_paste)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,3 +167,5 @@ func RuneOffsetsToByteOffsets(text string) func(int) int {
|
|||||||
return self.byte_offset
|
return self.byte_offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Repr(x any) string { return fmt.Sprintf("%#v", x) }
|
||||||
|
|||||||
Reference in New Issue
Block a user