]> git.0d.be Git - barnard.git/blob - uiterm/textview.go
code formatting
[barnard.git] / uiterm / textview.go
1 package uiterm
2
3 import (
4         "strings"
5
6         "github.com/nsf/termbox-go"
7 )
8
9 type Textview struct {
10         Lines       []string
11         CurrentLine int
12         Fg, Bg      Attribute
13
14         parsedLines []string
15
16         ui             *Ui
17         x0, y0, x1, y1 int
18 }
19
20 func (t *Textview) uiInitialize(ui *Ui) {
21         t.ui = ui
22 }
23
24 func (t *Textview) uiSetActive(active bool) {
25 }
26
27 func (t *Textview) uiSetBounds(x0, y0, x1, y1 int) {
28         t.x0 = x0
29         t.y0 = y0
30         t.x1 = x1
31         t.y1 = y1
32         t.updateParsedLines()
33         t.uiDraw()
34 }
35
36 func (t *Textview) ScrollUp() {
37         if newLine := t.CurrentLine + 1; newLine < len(t.parsedLines) {
38                 t.CurrentLine = newLine
39         }
40         t.uiDraw()
41 }
42
43 func (t *Textview) ScrollDown() {
44         if newLine := t.CurrentLine - 1; newLine >= 0 {
45                 t.CurrentLine = newLine
46         }
47         t.uiDraw()
48 }
49
50 func (t *Textview) ScrollTop() {
51         if newLine := len(t.parsedLines) - 1; newLine > 0 {
52                 t.CurrentLine = newLine
53         } else {
54                 t.CurrentLine = 0
55         }
56         t.uiDraw()
57 }
58
59 func (t *Textview) ScrollBottom() {
60         t.CurrentLine = 0
61         t.uiDraw()
62 }
63
64 func (t *Textview) updateParsedLines() {
65         width := t.x1 - t.x0 - 3
66
67         if t.Lines == nil || width <= 0 {
68                 t.parsedLines = nil
69                 return
70         }
71
72         parsed := make([]string, 0, len(t.Lines))
73         for _, line := range t.Lines {
74                 current := ""
75                 chars := 0
76                 reader := strings.NewReader(line)
77                 for {
78                         if chars >= width {
79                                 parsed = append(parsed, current)
80                                 chars = 0
81                                 current = ""
82                         }
83                         if reader.Len() <= 0 {
84                                 if chars > 0 {
85                                         parsed = append(parsed, current)
86                                 }
87                                 break
88                         }
89                         if ch, _, err := reader.ReadRune(); err == nil {
90                                 current = current + string(ch)
91                                 chars++
92                         }
93                 }
94         }
95         t.parsedLines = parsed
96 }
97
98 func (t *Textview) AddLine(line string) {
99         t.Lines = append(t.Lines, line)
100         t.updateParsedLines()
101         t.uiDraw()
102 }
103
104 func (t *Textview) Clear() {
105         t.Lines = nil
106         t.CurrentLine = 0
107         t.parsedLines = nil
108         t.uiDraw()
109 }
110
111 func (t *Textview) uiDraw() {
112         t.ui.beginDraw()
113         defer t.ui.endDraw()
114
115         var reader *strings.Reader
116         line := len(t.parsedLines) - 1 - t.CurrentLine
117         if line < 0 {
118                 line = 0
119         }
120         totalLines := len(t.parsedLines)
121         if totalLines == 0 {
122                 totalLines = 1
123         }
124         currentScrollLine := t.y1 - 1 - int((float32(t.CurrentLine)/float32(totalLines))*float32(t.y1-t.y0))
125         for y := t.y1 - 1; y >= t.y0; y-- {
126                 if t.parsedLines != nil && line >= 0 {
127                         reader = strings.NewReader(t.parsedLines[line])
128                 } else {
129                         reader = nil
130                 }
131                 for x := t.x0; x < t.x1; x++ {
132                         var chr rune = ' '
133                         if x == t.x1-1 { // scrollbar
134                                 if y == currentScrollLine {
135                                         chr = '█'
136                                 } else {
137                                         chr = '░'
138                                 }
139                         } else if x < t.x1-3 {
140                                 if reader != nil {
141                                         if ch, _, err := reader.ReadRune(); err == nil {
142                                                 chr = ch
143                                         }
144                                 }
145                         }
146                         termbox.SetCell(x, y, chr, termbox.Attribute(t.Fg), termbox.Attribute(t.Bg))
147                 }
148                 line--
149         }
150 }
151
152 func (t *Textview) uiKeyEvent(mod Modifier, key Key) {
153 }
154
155 func (t *Textview) uiCharacterEvent(chr rune) {
156 }