From f8e2dc1eca7c2c3e77710ae2148fd185dcedc8b1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 17 May 2024 17:35:28 +0530 Subject: [PATCH] More work on face fine tune UI --- kittens/choose_fonts/face.go | 37 +++++++++++-- kittens/choose_fonts/styles.go | 94 ++++++++++++++++++++-------------- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/kittens/choose_fonts/face.go b/kittens/choose_fonts/face.go index a7db6deec..be878528f 100644 --- a/kittens/choose_fonts/face.go +++ b/kittens/choose_fonts/face.go @@ -17,22 +17,45 @@ type face_panel struct { family, which string settings faces_settings + current_preview *RenderedSampleTransmit 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 + s := styles_for_variable_data(preview.Variable_data) + lines := []string{} + for _, sg := range s.style_groups { + if len(sg.styles) < 2 { + continue + } + formatted := make([]string, len(sg.styles)) + for i, style_name := range sg.styles { + if style_name == preview.Variable_named_style.Name { + formatted[i] = self.handler.lp.SprintStyled("fg=cyan bold", style_name) + } else { + formatted[i] = tui.InternalHyperlink(style_name, "variable_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_family_style_select(sz loop.ScreenSize, start_y int) (y int, err error) { +func (self *face_panel) draw_family_style_select(sz loop.ScreenSize, start_y int, preview RenderedSampleTransmit) (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) + if style_name == preview.Style { + formatted[i] = self.handler.lp.SprintStyled("fg=cyan bold", style_name) + } else { + formatted[i] = tui.InternalHyperlink(style_name, "style:"+style_name) + } } line := sg.name + ": " + strings.Join(formatted, ", ") lines = append(lines, line) @@ -94,10 +117,11 @@ func (self *face_panel) draw_screen() (err error) { return } preview := previews[self.which] + self.current_preview = &preview 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) + y, err = self.draw_family_style_select(sz, y, preview) } if err != nil { return err @@ -150,6 +174,9 @@ func (self *face_panel) on_click(id string) (err error) { switch scheme { case "style": self.set(fmt.Sprintf(`family="%s" style="%s"`, self.family, val)) + case "variable_style": + self.set(fmt.Sprintf(`family="%s" variable_name="%s" style="%s"`, self.family, + self.current_preview.Variable_data.Variations_postscript_name_prefix, val)) } return self.handler.draw_screen() } diff --git a/kittens/choose_fonts/styles.go b/kittens/choose_fonts/styles.go index 0358aa2f6..da0edc009 100644 --- a/kittens/choose_fonts/styles.go +++ b/kittens/choose_fonts/styles.go @@ -20,11 +20,63 @@ type family_style_data struct { has_style_attribute_data bool } +func styles_with_attribute_data(ans *family_style_data, items ...VariableData) { + groups := make(map[string]*style_group) + seen_map := make(map[string]*utils.Set[string]) + get := func(key string, ordering int) (*style_group, *utils.Set[string]) { + sg := groups[key] + seen := seen_map[key] + if sg == nil { + ans.style_groups = append(ans.style_groups, style_group{name: key, ordering: ordering, styles: make([]string, 0)}) + sg = &ans.style_groups[len(ans.style_groups)-1] + groups[key] = sg + seen = utils.NewSet[string]() + seen_map[key] = seen + } + return sg, seen + } + for _, vd := range items { + for _, ax := range vd.Design_axes { + if ax.Name == "" { + continue + } + sg, seen := get(ax.Name, ax.Ordering) + for _, v := range ax.Values { + if v.Name != "" && !seen.Has(v.Name) { + seen.Add(v.Name) + sg.styles = append(sg.styles, v.Name) + } + } + } + for _, ma := range vd.Multi_axis_styles { + sg, seen := get("Styles", 0) + if ma.Name != "" && !seen.Has(ma.Name) { + seen.Add(ma.Name) + sg.styles = append(sg.styles, ma.Name) + } + } + } + utils.StableSortWithKey(ans.style_groups, func(sg style_group) int { return sg.ordering }) + +} + +func styles_for_variable_data(vd VariableData) (ans *family_style_data) { + ans = &family_style_data{style_groups: make([]style_group, 0)} + styles_with_attribute_data(ans, vd) + for _, sg := range ans.style_groups { + slices.Sort(sg.styles) + } + return +} + func styles_in_family(family string, fonts []ListedFont) (ans *family_style_data) { _ = family ans = &family_style_data{style_groups: make([]style_group, 0)} - for _, f := range fonts { - vd := variable_data_for(f) + vds := make([]VariableData, len(fonts)) + for i, f := range fonts { + vds[i] = variable_data_for(f) + } + for _, vd := range vds { if len(vd.Design_axes) > 0 { ans.has_style_attribute_data = true } @@ -33,43 +85,7 @@ func styles_in_family(family string, fonts []ListedFont) (ans *family_style_data } } if ans.has_style_attribute_data { - groups := make(map[string]*style_group) - seen_map := make(map[string]*utils.Set[string]) - get := func(key string, ordering int) (*style_group, *utils.Set[string]) { - sg := groups[key] - seen := seen_map[key] - if sg == nil { - ans.style_groups = append(ans.style_groups, style_group{name: key, ordering: ordering, styles: make([]string, 0)}) - sg = &ans.style_groups[len(ans.style_groups)-1] - groups[key] = sg - seen = utils.NewSet[string]() - seen_map[key] = seen - } - return sg, seen - } - for _, f := range fonts { - vd := variable_data_for(f) - for _, ax := range vd.Design_axes { - if ax.Name == "" { - continue - } - sg, seen := get(ax.Name, ax.Ordering) - for _, v := range ax.Values { - if v.Name != "" && !seen.Has(v.Name) { - seen.Add(v.Name) - sg.styles = append(sg.styles, v.Name) - } - } - } - for _, ma := range vd.Multi_axis_styles { - sg, seen := get("Styles", 0) - if ma.Name != "" && !seen.Has(ma.Name) { - seen.Add(ma.Name) - sg.styles = append(sg.styles, ma.Name) - } - } - } - utils.StableSortWithKey(ans.style_groups, func(sg style_group) int { return sg.ordering }) + styles_with_attribute_data(ans, vds...) } else { ans.style_groups = append(ans.style_groups, style_group{name: "Styles", styles: make([]string, 0)}) sg := &ans.style_groups[0]