-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtermfields.go
More file actions
165 lines (146 loc) · 3.98 KB
/
termfields.go
File metadata and controls
165 lines (146 loc) · 3.98 KB
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
165
// Package termfields creates updateable form fields at specified locations in the console.
package termfields
import (
"fmt"
tb "github.com/nsf/termbox-go"
)
var boxRunesMap map[boxStyle][]rune
type (
boxStyle uint16
shiftDir uint16
)
// Flags to style a box border around a field
const (
boxStyleClear boxStyle = iota
BoxStyleNone
BoxStyleASCII
BoxStyleUnicode
)
// Flags to Shift a field in a specified direction
const (
FieldShiftLeft shiftDir = iota
FieldShiftRight
FieldShiftUp
FieldShiftDown
)
// Field is the identifier for a specific form field on the screen.
type Field struct {
field
}
type field struct {
x, y int
len int
border boxStyle
text string
}
func init() {
boxRunesMap = map[boxStyle][]rune{
boxStyleClear: {' ', ' ', ' ', ' ', ' ', ' '},
BoxStyleNone: {0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
BoxStyleASCII: {'+', '+', '+', '+', '-', '|'},
BoxStyleUnicode: {0x250c, 0x2510, 0x2514, 0x2518, 0x2500, 0x2502},
}
}
// Init Initializes termfields library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
// err := termfields.Init()
// if err != nil {
// panic(err)
// }
// defer termfields.Close()
func Init() error {
return tb.Init()
}
// Close Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
tb.SetCursor(0, 0)
tb.Close()
}
// Row returns the row of a field.
func (f *field) Row() int {
return f.y
}
// Column returns the column of a field.
func (f *field) Column() int {
return f.x
}
// Loc defines a new location for a field.
func (f *field) Loc(y, x int) {
border := f.border
f.Update(fmt.Sprintf("%*s", f.len, " "))
f.DrawBox(boxStyleClear)
f.x = x
f.y = y
f.DrawBox(border)
f.Update(f.text)
}
// Shift shifts a field a direction based on the value of a moveDir
func (f *field) Shift(dir shiftDir) {
border := f.border
f.DrawBox(boxStyleClear)
switch {
case dir == FieldShiftLeft:
f.x--
case dir == FieldShiftRight:
f.x++
case dir == FieldShiftUp:
f.y--
case dir == FieldShiftDown:
f.y++
}
f.DrawBox(border)
f.Update(f.text)
}
// NewField creates a new field at location y,x of lenth len with contents text.
func NewField(y, x, len int, text string) (*Field, error) {
f := field{
x: x,
y: y,
len: len,
}
err := f.Update(text)
if err != nil {
return nil, err
}
return &Field{f}, nil
}
// DrawBox draws or clears a box around a given field.
func (f *field) DrawBox(boxType boxStyle) error {
if !tb.IsInit {
return fmt.Errorf("Term not Initialized")
}
if _, ok := boxRunesMap[boxType]; !ok {
return fmt.Errorf("Unknown Box Style")
}
// Draw Corners
tb.SetCell(f.x-1, f.y-1, boxRunesMap[boxType][0], tb.ColorDefault, tb.ColorDefault)
tb.SetCell(f.x+f.len+1, f.y-1, boxRunesMap[boxType][1], tb.ColorDefault, tb.ColorDefault)
tb.SetCell(f.x-1, f.y+1, boxRunesMap[boxType][2], tb.ColorDefault, tb.ColorDefault)
tb.SetCell(f.x+f.len+1, f.y+1, boxRunesMap[boxType][3], tb.ColorDefault, tb.ColorDefault)
// Draw Sides
tb.SetCell(f.x-1, f.y, boxRunesMap[boxType][5], tb.ColorDefault, tb.ColorDefault)
tb.SetCell(f.x+f.len+1, f.y, boxRunesMap[boxType][5], tb.ColorDefault, tb.ColorDefault)
// Draw Top
for i := 0; i < f.len+1; i++ {
tb.SetCell(f.x+i, f.y-1, boxRunesMap[boxType][4], tb.ColorDefault, tb.ColorDefault)
tb.SetCell(f.x+i, f.y+1, boxRunesMap[boxType][4], tb.ColorDefault, tb.ColorDefault)
}
tb.Flush()
f.border = boxType
return nil
}
// Update changes the text for a field
func (f *field) Update(s string) error {
if !tb.IsInit {
return fmt.Errorf("Term not Initialized")
}
for i, c := range s {
tb.SetCell(f.x+i, f.y, c, tb.ColorDefault, tb.ColorDefault)
}
tb.Flush()
f.text = s
return nil
}