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