blob: 4fec256df0e885f7632bc7603acfe7f129214dfb [file] [log] [blame]
Serge Bazanski0d9e1252024-09-03 12:16:47 +02001package tconsole
2
3import (
4 "strings"
5
6 "github.com/gdamore/tcell/v2"
7 "github.com/rivo/uniseg"
8)
9
10// drawText draws a single line of text from left to right, starting at x and y.
Serge Bazanskid735a3c2024-09-05 13:51:44 +020011func (c *Console) drawText(x, y int, text string, style tcell.Style) int {
Serge Bazanski0d9e1252024-09-03 12:16:47 +020012 g := uniseg.NewGraphemes(text)
Serge Bazanskid735a3c2024-09-05 13:51:44 +020013 xi := 0
Serge Bazanski0d9e1252024-09-03 12:16:47 +020014 for g.Next() {
15 runes := g.Runes()
Serge Bazanskid735a3c2024-09-05 13:51:44 +020016 c.screen.SetContent(x+xi, y, runes[0], runes[1:], style)
17 xi += 1
Serge Bazanski0d9e1252024-09-03 12:16:47 +020018 }
Serge Bazanskid735a3c2024-09-05 13:51:44 +020019 return xi
Serge Bazanski0d9e1252024-09-03 12:16:47 +020020}
21
22// drawTextCentered draw a single line of text from left to right, starting at a
23// position so that the center of the line ends up at x and y.
24func (c *Console) drawTextCentered(x, y int, text string, style tcell.Style) {
25 g := uniseg.NewGraphemes(text)
26 var runes [][]rune
27 for g.Next() {
28 runes = append(runes, g.Runes())
29 }
30
31 x -= len(runes) / 2
32
33 for _, r := range runes {
34 c.screen.SetContent(x, y, r[0], r[1:], style)
35 x += 1
36 }
37}
38
39// fillRectangle fills a given rectangle [x0,x1) [y0,y1) with empty space of a
40// given style.
41func (c *Console) fillRectangle(x0, x1, y0, y1 int, style tcell.Style) {
42 for x := x0; x < x1; x++ {
43 for y := y0; y < y1; y++ {
44 c.screen.SetContent(x, y, ' ', nil, style)
45 }
46 }
47}
48
49const logo = `
50 _g@@@@g_ _g@@@@g_
51 _@@@@@@@@@@a g@@@@@@@@@@b
52 @@@@@@@@@@@@@@___@@@@@@@@@@@@@@
53 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
54 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
55 g@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@g
56 g@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@g
57 g@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@g
58 ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,
59 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
60 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
61 %@@@@@@@@@@P<@@@@@@@@@@@@@>%@@@@@@@@@@P
62 "+B@@B>' "@@@@@@@@B" '<B@@BP"
63 '"
64`
65
66// drawLogo draws the Monogon logo so that its top left corner is at x, y.
67func (c *Console) drawLogo(x, y int, style tcell.Style) {
68 for i, line := range strings.Split(logo, "\n") {
69 c.drawText(x, y+i, line, style)
70 }
71}
72
73// split calculates a mid-point in the [0, capacity) domain so that it splits it
74// into two parts fairly with minA and minB used as minimum size hints for each
75// section.
76func split(capacity, minA, minB int) int {
77 slack := capacity - (minA + minB)
78 propA := float64(minA) / float64(minA+minB)
79 slackA := int(propA * float64(slack))
80 return minA + slackA
81}
82
83// center calculates a point at which to start drawing a 'size'-sized element in
84// a 'capacity'-sized container so that it ends in the middle of said container.
85func center(capacity, size int) int {
86 return (capacity - size) / 2
87}