summaryrefslogtreecommitdiff
path: root/ui/draw_utils.go
blob: 62f2d793b6ed33b0e751b947effbb8300292630a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package ui

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/delthas/go-localeinfo"

	"github.com/gdamore/tcell/v2"
)

func printString(screen tcell.Screen, x *int, y int, s StyledString) {
	style := tcell.StyleDefault
	nextStyles := s.styles
	for i, r := range s.string {
		if 0 < len(nextStyles) && nextStyles[0].Start == i {
			style = nextStyles[0].Style
			nextStyles = nextStyles[1:]
		}
		screen.SetContent(*x, y, r, nil, style)
		*x += runeWidth(r)
	}
}

func printIdent(screen tcell.Screen, x, y, width int, s StyledString) {
	s.string = truncate(s.string, width, "\u2026")
	x += width - stringWidth(s.string)
	st := tcell.StyleDefault
	if len(s.styles) != 0 && s.styles[0].Start == 0 {
		st = s.styles[0].Style
	}
	screen.SetContent(x-1, y, ' ', nil, st)
	printString(screen, &x, y, s)
	if len(s.styles) != 0 {
		// TODO check if it's not a style that is from the truncated
		// part of s.
		st = s.styles[len(s.styles)-1].Style
	}
	screen.SetContent(x, y, ' ', nil, st)
}

func printNumber(screen tcell.Screen, x *int, y int, st tcell.Style, n int) {
	s := Styled(fmt.Sprintf("%d", n), st)
	printString(screen, x, y, s)
}

var dateConfig sync.Once
var dateMonthFirst bool

func loadDateInfo() {
	// Very overkill, but I like it :)
	// Try to extract from the user locale whether they'd rather have the date
	// printed as dd/mm or mm/dd.
	// If we're not sure, print dd/mm.
	l, err := localeinfo.NewLocale("")
	if err != nil {
		return
	}
	format := l.DateFormat()
	dayIndex := -1
	for _, s := range []string{"%d", "%e"} {
		dayIndex = strings.Index(format, s)
		if dayIndex >= 0 {
			break
		}
	}
	if dayIndex == -1 {
		return
	}
	monthIndex := -1
	for _, s := range []string{"%m", "%b", "%B"} {
		monthIndex = strings.Index(format, s)
		if monthIndex >= 0 {
			break
		}
	}
	if monthIndex == -1 {
		return
	}
	if monthIndex < dayIndex {
		dateMonthFirst = true
	}
}

func printDate(screen tcell.Screen, x int, y int, st tcell.Style, t time.Time) {
	dateConfig.Do(loadDateInfo)
	_, m, d := t.Date()
	var left, right int
	if dateMonthFirst {
		left, right = int(m), d
	} else {
		left, right = d, int(m)
	}
	l0 := rune(left/10) + '0'
	l1 := rune(left%10) + '0'
	r0 := rune(right/10) + '0'
	r1 := rune(right%10) + '0'
	screen.SetContent(x+0, y, l0, nil, st)
	screen.SetContent(x+1, y, l1, nil, st)
	screen.SetContent(x+2, y, '/', nil, st)
	screen.SetContent(x+3, y, r0, nil, st)
	screen.SetContent(x+4, y, r1, nil, st)
}

func printTime(screen tcell.Screen, x int, y int, st tcell.Style, t time.Time) {
	hr0 := rune(t.Hour()/10) + '0'
	hr1 := rune(t.Hour()%10) + '0'
	mn0 := rune(t.Minute()/10) + '0'
	mn1 := rune(t.Minute()%10) + '0'
	screen.SetContent(x+0, y, hr0, nil, st)
	screen.SetContent(x+1, y, hr1, nil, st)
	screen.SetContent(x+2, y, ':', nil, st)
	screen.SetContent(x+3, y, mn0, nil, st)
	screen.SetContent(x+4, y, mn1, nil, st)
}

func clearArea(screen tcell.Screen, x0, y0, width, height int) {
	for x := x0; x < x0+width; x++ {
		for y := y0; y < y0+height; y++ {
			screen.SetContent(x, y, ' ', nil, tcell.StyleDefault)
		}
	}
}

func drawVerticalLine(screen tcell.Screen, x, y0, height int) {
	for y := y0; y < y0+height; y++ {
		screen.SetContent(x, y, 0x2502, nil, tcell.StyleDefault)
	}
}