generated from atomicgo/template
-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
area.go
164 lines (139 loc) · 3.48 KB
/
area.go
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package cursor
import (
"os"
"strings"
)
// Area displays content which can be updated on the fly.
// You can use this to create live output, charts, dropdowns, etc.
type Area struct {
height int
writer Writer
cursor *Cursor
cursorPosY int
}
// NewArea returns a new Area.
func NewArea() Area {
return Area{
height: 0,
writer: os.Stdout,
cursor: cursor,
cursorPosY: 0,
}
}
// WithWriter sets the custom writer.
func (area Area) WithWriter(writer Writer) Area {
area.writer = writer
area.cursor = area.cursor.WithWriter(writer)
return area
}
// Clear clears the content of the Area.
func (area *Area) Clear() {
// Initialize writer if not done yet
if area.writer == nil {
area.writer = os.Stdout
}
if area.height > 0 {
area.Bottom()
area.ClearLinesUp(area.height)
area.StartOfLine()
} else {
area.StartOfLine()
area.cursor.ClearLine()
}
}
// Update overwrites the content of the Area and adjusts its height based on content.
func (area *Area) Update(content string) {
area.Clear()
area.writeArea(content)
area.cursorPosY = 0
area.height = strings.Count(content, "\n")
}
// Up moves the cursor of the area up one line.
func (area *Area) Up(n int) {
if n > 0 {
if area.cursorPosY+n > area.height {
n = area.height - area.cursorPosY
}
area.cursor.Up(n)
area.cursorPosY += n
}
}
// Down moves the cursor of the area down one line.
func (area *Area) Down(n int) {
if n > 0 {
if area.cursorPosY-n < 0 {
n = area.height - area.cursorPosY
}
area.cursor.Down(n)
area.cursorPosY -= n
}
}
// Bottom moves the cursor to the bottom of the terminal.
// This is done by calculating how many lines were moved by Up and Down.
func (area *Area) Bottom() {
if area.cursorPosY > 0 {
area.Down(area.cursorPosY)
area.cursorPosY = 0
}
}
// Top moves the cursor to the top of the area.
// This is done by calculating how many lines were moved by Up and Down.
func (area *Area) Top() {
if area.cursorPosY < area.height {
area.Up(area.height - area.cursorPosY)
area.cursorPosY = area.height
}
}
// StartOfLine moves the cursor to the start of the current line.
func (area *Area) StartOfLine() {
area.cursor.HorizontalAbsolute(0)
}
// StartOfLineDown moves the cursor down by n lines, then moves to cursor to the start of the line.
func (area *Area) StartOfLineDown(n int) {
area.Down(n)
area.StartOfLine()
}
// StartOfLineUp moves the cursor up by n lines, then moves to cursor to the start of the line.
func (area *Area) StartOfLineUp(n int) {
area.Up(n)
area.StartOfLine()
}
// UpAndClear moves the cursor up by n lines, then clears the line.
func (area *Area) UpAndClear(n int) {
area.Up(n)
area.cursor.ClearLine()
}
// DownAndClear moves the cursor down by n lines, then clears the line.
func (area *Area) DownAndClear(n int) {
area.Down(n)
area.cursor.ClearLine()
}
// Move moves the cursor relative by x and y.
func (area *Area) Move(x, y int) {
if x > 0 {
area.cursor.Right(x)
} else if x < 0 {
area.cursor.Left(-x)
}
if y > 0 {
area.Up(y)
} else if y < 0 {
area.Down(-y)
}
}
// ClearLinesUp clears n lines upwards from the current position and moves the cursor.
func (area *Area) ClearLinesUp(n int) {
area.StartOfLine()
area.cursor.ClearLine()
for i := 0; i < n; i++ {
area.UpAndClear(1)
}
}
// ClearLinesDown clears n lines downwards from the current position and moves the cursor.
func (area *Area) ClearLinesDown(n int) {
area.StartOfLine()
area.cursor.ClearLine()
for i := 0; i < n; i++ {
area.DownAndClear(1)
}
}