turbo-editors/turbo-corepublic Fork 0
v1.0.1
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

menu_draw.go · 110 lines · 2.9 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 18h ago1package ui
2
3// Where the menu bar puts its panels, and how it paints them.
4
5import (
📦 Turbo Core f3ade8d k33g 11h ago6 "rickub.com/turbo-editors/turbo-core/theme"
🛟 Updated. 28d5985 k33g 18h ago7)
8
9// menuX returns the column the title of menu i starts at.
10func (b *MenuBar) menuX(i int) int {
11 x := b.Bounds().X + 1
12 for _, m := range b.menus[:i] {
13 x += LabelWidth(m.Label) + 2
14 }
15 return x
16}
17
18// dropdownBounds returns the rectangle the open drop-down occupies.
19func (b *MenuBar) dropdownBounds() Rect {
20 menu := b.menus[b.openMenu]
21
22 width := 0
23 for _, item := range menu.Items {
24 width = max(width, item.width())
25 }
26 width += 4 // one cell of frame and one of padding on each side
27
28 return Rect{
29 X: b.menuX(b.openMenu) - 1,
30 Y: b.Bounds().Y + 1,
31 W: width,
32 H: len(menu.Items) + 2,
33 }
34}
35
36// Draw paints the bar and, if one is open, the drop-down under it.
37func (b *MenuBar) Draw(p *Painter, th *theme.Theme) {
38 bar := p.Sub(b.Bounds())
39 bar.Clear(th.Style(theme.KeyMenuBar))
40
41 for i, menu := range b.menus {
42 normal, hot := th.Style(theme.KeyMenuItem), th.Style(theme.KeyMenuShortcut)
43 if i == b.openMenu {
44 normal = th.Style(theme.KeyMenuSelected)
45 hot = normal
46 }
47
48 x := b.menuX(i) - b.Bounds().X
49 bar.SetCell(x-1, 0, ' ', normal)
50 end := DrawLabel(bar, x, 0, menu.Label, normal, hot)
51 bar.SetCell(end, 0, ' ', normal)
52 }
53
54 if b.Open() {
55 b.drawDropdown(p, th)
56 }
57 if b.submenuOpen() {
58 b.drawSubmenu(p, th)
59 }
60}
61
62// drawDropdown paints the open menu's frame and items.
63func (b *MenuBar) drawDropdown(p *Painter, th *theme.Theme) {
64 bounds := b.dropdownBounds()
65 DrawShadow(p, bounds, th.Style(theme.KeyShadow))
66
67 panel := p.Sub(bounds)
68 panel.Clear(th.Style(theme.KeyMenuItem))
69 DrawFrame(panel, panel.Size(), FrameSingle, th.Style(theme.KeyMenuItem))
70
71 for i, item := range b.menus[b.openMenu].Items {
72 // The item whose submenu is showing stays highlighted, so the eye can
73 // see which branch the second panel came from.
74 b.drawLine(panel, th, i, item, i == b.highlight || i == b.openItem)
75 }
76}
77
78// drawLine paints one line of a drop-down.
79func (b *MenuBar) drawLine(p *Painter, th *theme.Theme, i int, item *MenuItem, highlighted bool) {
80 y := i + 1
81 width := p.Size().W
82
83 if item.Separator {
84 // The rule joins the frame on both sides, as Turbo Vision drew it.
85 style := th.Style(theme.KeyMenuItem)
86 p.SetCell(0, y, '├', style)
87 p.HLine(1, y, width-2, '─', style)
88 p.SetCell(width-1, y, '┤', style)
89 return
90 }
91
92 normal, hot := th.Style(theme.KeyMenuItem), th.Style(theme.KeyMenuShortcut)
93 switch {
94 case !item.enabled():
95 normal, hot = th.Style(theme.KeyMenuDisabled), th.Style(theme.KeyMenuDisabled)
96 case highlighted:
97 normal = th.Style(theme.KeyMenuSelected)
98 hot = normal
99 }
100
101 p.HLine(1, y, width-2, ' ', normal)
102 DrawLabel(p, 2, y, item.Label, normal, hot)
103
104 switch {
105 case item.Shortcut != "":
106 p.Text(width-2-len([]rune(item.Shortcut)), y, item.Shortcut, normal)
107 case item.hasSubmenu():
108 p.Text(width-2-len([]rune(submenuMarker)), y, submenuMarker, normal)
109 }
110}