Antonio Mika
·
2025-03-12
border.go
1package tui
2
3import (
4 "fmt"
5
6 "git.sr.ht/~rockorager/vaxis"
7 "git.sr.ht/~rockorager/vaxis/vxfw"
8)
9
10var (
11 horizontal = vaxis.Character{Grapheme: "─", Width: 1}
12 vertical = vaxis.Character{Grapheme: "│", Width: 1}
13 topLeft = vaxis.Character{Grapheme: "╭", Width: 1}
14 topRight = vaxis.Character{Grapheme: "╮", Width: 1}
15 bottomRight = vaxis.Character{Grapheme: "╯", Width: 1}
16 bottomLeft = vaxis.Character{Grapheme: "╰", Width: 1}
17)
18
19func border(label string, surf vxfw.Surface, style vaxis.Style) vxfw.Surface {
20 finlabel := fmt.Sprintf(" %s ", label)
21 w := surf.Size.Width
22 h := surf.Size.Height
23 surf.WriteCell(0, 0, vaxis.Cell{
24 Character: topLeft,
25 Style: style,
26 })
27 surf.WriteCell(0, h-1, vaxis.Cell{
28 Character: bottomLeft,
29 Style: style,
30 })
31 surf.WriteCell(w-1, 0, vaxis.Cell{
32 Character: topRight,
33 Style: style,
34 })
35 surf.WriteCell(w-1, h-1, vaxis.Cell{
36 Character: bottomRight,
37 Style: style,
38 })
39 idx := 0
40 for j := 1; j < (int(w) - 1); j += 1 {
41 i := uint16(j)
42 // apply label
43 char := horizontal
44 if label != "" && j >= 2 && len(finlabel)+1 >= j {
45 char = vaxis.Character{Grapheme: string(finlabel[idx]), Width: 1}
46 idx += 1
47 }
48 surf.WriteCell(i, 0, vaxis.Cell{
49 Character: char,
50 Style: style,
51 })
52 surf.WriteCell(i, h-1, vaxis.Cell{
53 Character: horizontal,
54 Style: style,
55 })
56 }
57 for j := 1; j < (int(h) - 1); j += 1 {
58 i := uint16(j)
59 surf.WriteCell(0, i, vaxis.Cell{
60 Character: vertical,
61 Style: style,
62 })
63 surf.WriteCell(w-1, i, vaxis.Cell{
64 Character: vertical,
65 Style: style,
66 })
67 }
68
69 return surf
70}
71
72type Border struct {
73 w vxfw.Widget
74 Style vaxis.Style
75 Label string
76 Width uint16
77 Height uint16
78}
79
80func NewBorder(w vxfw.Widget) *Border {
81 return &Border{
82 w: w,
83 Style: vaxis.Style{Foreground: purp},
84 Label: "",
85 }
86}
87
88func (b *Border) HandleEvent(vaxis.Event, vxfw.EventPhase) (vxfw.Command, error) {
89 return nil, nil
90}
91
92func (b *Border) Draw(ctx vxfw.DrawContext) (vxfw.Surface, error) {
93 surf, _ := b.w.Draw(vxfw.DrawContext{
94 Characters: ctx.Characters,
95 Max: vxfw.Size{
96 Width: ctx.Max.Width - 2,
97 Height: ctx.Max.Height - 3,
98 },
99 })
100
101 w := surf.Size.Width + 2
102 if b.Width > 0 {
103 w = b.Width - 2
104 }
105
106 h := surf.Size.Height + 2
107 if b.Height > 0 {
108 h = b.Height - 2
109 }
110
111 root := border(
112 b.Label,
113 vxfw.NewSurface(w, h, b),
114 b.Style,
115 )
116 root.AddChild(1, 1, surf)
117 return root, nil
118}