1 package main
2
3 import (
4 "fmt"
5 "strings"
6
7 "github.com/gdamore/tcell/v2"
8 "github.com/rivo/tview"
9 )
10
11 const tableData = `OrderDate|Region|Rep|Item|Units|UnitCost|Total
12 1/6/2017|East|Jones|Pencil|95|1.99|189.05
13 1/23/2017|Central|Kivell|Binder|50|19.99|999.50
14 2/9/2017|Central|Jardine|Pencil|36|4.99|179.64
15 2/26/2017|Central|Gill|Pen|27|19.99|539.73
16 3/15/2017|West|Sorvino|Pencil|56|2.99|167.44
17 4/1/2017|East|Jones|Binder|60|4.99|299.40
18 4/18/2017|Central|Andrews|Pencil|75|1.99|149.25
19 5/5/2017|Central|Jardine|Pencil|90|4.99|449.10
20 5/22/2017|West|Thompson|Pencil|32|1.99|63.68
21 6/8/2017|East|Jones|Binder|60|8.99|539.40
22 6/25/2017|Central|Morgan|Pencil|90|4.99|449.10
23 7/12/2017|East|Howard|Binder|29|1.99|57.71
24 7/29/2017|East|Parent|Binder|81|19.99|1,619.19
25 8/15/2017|East|Jones|Pencil|35|4.99|174.65
26 9/1/2017|Central|Smith|Desk|2|125.00|250.00
27 9/18/2017|East|Jones|Pen Set|16|15.99|255.84
28 10/5/2017|Central|Morgan|Binder|28|8.99|251.72
29 10/22/2017|East|Jones|Pen|64|8.99|575.36
30 11/8/2017|East|Parent|Pen|15|19.99|299.85
31 11/25/2017|Central|Kivell|Pen Set|96|4.99|479.04
32 12/12/2017|Central|Smith|Pencil|67|1.29|86.43
33 12/29/2017|East|Parent|Pen Set|74|15.99|1,183.26
34 1/15/2018|Central|Gill|Binder|46|8.99|413.54
35 2/1/2018|Central|Smith|Binder|87|15.00|1,305.00
36 2/18/2018|East|Jones|Binder|4|4.99|19.96
37 3/7/2018|West|Sorvino|Binder|7|19.99|139.93
38 3/24/2018|Central|Jardine|Pen Set|50|4.99|249.50
39 4/10/2018|Central|Andrews|Pencil|66|1.99|131.34
40 4/27/2018|East|Howard|Pen|96|4.99|479.04
41 5/14/2018|Central|Gill|Pencil|53|1.29|68.37
42 5/31/2018|Central|Gill|Binder|80|8.99|719.20
43 6/17/2018|Central|Kivell|Desk|5|125.00|625.00
44 7/4/2018|East|Jones|Pen Set|62|4.99|309.38
45 7/21/2018|Central|Morgan|Pen Set|55|12.49|686.95
46 8/7/2018|Central|Kivell|Pen Set|42|23.95|1,005.90
47 8/24/2018|West|Sorvino|Desk|3|275.00|825.00
48 9/10/2018|Central|Gill|Pencil|7|1.29|9.03
49 9/27/2018|West|Sorvino|Pen|76|1.99|151.24
50 10/14/2018|West|Thompson|Binder|57|19.99|1,139.43
51 10/31/2018|Central|Andrews|Pencil|14|1.29|18.06
52 11/17/2018|Central|Jardine|Binder|11|4.99|54.89
53 12/4/2018|Central|Jardine|Binder|94|19.99|1,879.06
54 12/21/2018|Central|Andrews|Binder|28|4.99|139.72`
55
56 const tableBasic = `[green]func[white] [yellow]main[white]() {
57 table := tview.[yellow]NewTable[white]().
58 [yellow]SetFixed[white]([red]1[white], [red]1[white])
59 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
60 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
61 color := tcell.ColorWhite
62 [yellow]if[white] row == [red]0[white] {
63 color = tcell.ColorYellow
64 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
65 color = tcell.ColorDarkCyan
66 }
67 align := tview.AlignLeft
68 [yellow]if[white] row == [red]0[white] {
69 align = tview.AlignCenter
70 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
71 align = tview.AlignRight
72 }
73 table.[yellow]SetCell[white](row,
74 column,
75 &tview.TableCell{
76 Text: [red]"..."[white],
77 Color: color,
78 Align: align,
79 })
80 }
81 }
82 tview.[yellow]NewApplication[white]().
83 [yellow]SetRoot[white](table, true).
84 [yellow]Run[white]()
85 }`
86
87 const tableSeparator = `[green]func[white] [yellow]main[white]() {
88 table := tview.[yellow]NewTable[white]().
89 [yellow]SetFixed[white]([red]1[white], [red]1[white]).
90 [yellow]SetSeparator[white](Borders.Vertical)
91 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
92 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
93 color := tcell.ColorWhite
94 [yellow]if[white] row == [red]0[white] {
95 color = tcell.ColorYellow
96 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
97 color = tcell.ColorDarkCyan
98 }
99 align := tview.AlignLeft
100 [yellow]if[white] row == [red]0[white] {
101 align = tview.AlignCenter
102 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
103 align = tview.AlignRight
104 }
105 table.[yellow]SetCell[white](row,
106 column,
107 &tview.TableCell{
108 Text: [red]"..."[white],
109 Color: color,
110 Align: align,
111 })
112 }
113 }
114 tview.[yellow]NewApplication[white]().
115 [yellow]SetRoot[white](table, true).
116 [yellow]Run[white]()
117 }`
118
119 const tableBorders = `[green]func[white] [yellow]main[white]() {
120 table := tview.[yellow]NewTable[white]().
121 [yellow]SetFixed[white]([red]1[white], [red]1[white]).
122 [yellow]SetBorders[white](true)
123 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
124 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
125 color := tcell.ColorWhite
126 [yellow]if[white] row == [red]0[white] {
127 color = tcell.ColorYellow
128 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
129 color = tcell.ColorDarkCyan
130 }
131 align := tview.AlignLeft
132 [yellow]if[white] row == [red]0[white] {
133 align = tview.AlignCenter
134 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
135 align = tview.AlignRight
136 }
137 table.[yellow]SetCell[white](row,
138 column,
139 &tview.TableCell{
140 Text: [red]"..."[white],
141 Color: color,
142 Align: align,
143 })
144 }
145 }
146 tview.[yellow]NewApplication[white]().
147 [yellow]SetRoot[white](table, true).
148 [yellow]Run[white]()
149 }`
150
151 const tableSelectRow = `[green]func[white] [yellow]main[white]() {
152 table := tview.[yellow]NewTable[white]().
153 [yellow]SetFixed[white]([red]1[white], [red]1[white]).
154 [yellow]SetSelectable[white](true, false)
155 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
156 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
157 color := tcell.ColorWhite
158 [yellow]if[white] row == [red]0[white] {
159 color = tcell.ColorYellow
160 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
161 color = tcell.ColorDarkCyan
162 }
163 align := tview.AlignLeft
164 [yellow]if[white] row == [red]0[white] {
165 align = tview.AlignCenter
166 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
167 align = tview.AlignRight
168 }
169 table.[yellow]SetCell[white](row,
170 column,
171 &tview.TableCell{
172 Text: [red]"..."[white],
173 Color: color,
174 Align: align,
175 NotSelectable: row == [red]0[white] || column == [red]0[white],
176 })
177 }
178 }
179 tview.[yellow]NewApplication[white]().
180 [yellow]SetRoot[white](table, true).
181 [yellow]Run[white]()
182 }`
183
184 const tableSelectColumn = `[green]func[white] [yellow]main[white]() {
185 table := tview.[yellow]NewTable[white]().
186 [yellow]SetFixed[white]([red]1[white], [red]1[white]).
187 [yellow]SetSelectable[white](false, true)
188 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
189 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
190 color := tcell.ColorWhite
191 [yellow]if[white] row == [red]0[white] {
192 color = tcell.ColorYellow
193 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
194 color = tcell.ColorDarkCyan
195 }
196 align := tview.AlignLeft
197 [yellow]if[white] row == [red]0[white] {
198 align = tview.AlignCenter
199 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
200 align = tview.AlignRight
201 }
202 table.[yellow]SetCell[white](row,
203 column,
204 &tview.TableCell{
205 Text: [red]"..."[white],
206 Color: color,
207 Align: align,
208 NotSelectable: row == [red]0[white] || column == [red]0[white],
209 })
210 }
211 }
212 tview.[yellow]NewApplication[white]().
213 [yellow]SetRoot[white](table, true).
214 [yellow]Run[white]()
215 }`
216
217 const tableSelectCell = `[green]func[white] [yellow]main[white]() {
218 table := tview.[yellow]NewTable[white]().
219 [yellow]SetFixed[white]([red]1[white], [red]1[white]).
220 [yellow]SetSelectable[white](true, true)
221 [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
222 [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
223 color := tcell.ColorWhite
224 [yellow]if[white] row == [red]0[white] {
225 color = tcell.ColorYellow
226 } [yellow]else[white] [yellow]if[white] column == [red]0[white] {
227 color = tcell.ColorDarkCyan
228 }
229 align := tview.AlignLeft
230 [yellow]if[white] row == [red]0[white] {
231 align = tview.AlignCenter
232 } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
233 align = tview.AlignRight
234 }
235 table.[yellow]SetCell[white](row,
236 column,
237 &tview.TableCell{
238 Text: [red]"..."[white],
239 Color: color,
240 Align: align,
241 NotSelectable: row == [red]0[white] || column == [red]0[white],
242 })
243 }
244 }
245 tview.[yellow]NewApplication[white]().
246 [yellow]SetRoot[white](table, true).
247 [yellow]Run[white]()
248 }`
249
250
251 func Table(nextSlide func()) (title string, content tview.Primitive) {
252 table := tview.NewTable().
253 SetFixed(1, 1)
254 for row, line := range strings.Split(tableData, "\n") {
255 for column, cell := range strings.Split(line, "|") {
256 color := tcell.ColorWhite
257 if row == 0 {
258 color = tcell.ColorYellow
259 } else if column == 0 {
260 color = tcell.ColorDarkCyan
261 }
262 align := tview.AlignLeft
263 if row == 0 {
264 align = tview.AlignCenter
265 } else if column == 0 || column >= 4 {
266 align = tview.AlignRight
267 }
268 tableCell := tview.NewTableCell(cell).
269 SetTextColor(color).
270 SetAlign(align).
271 SetSelectable(row != 0 && column != 0)
272 if column >= 1 && column <= 3 {
273 tableCell.SetExpansion(1)
274 }
275 table.SetCell(row, column, tableCell)
276 }
277 }
278 table.SetBorder(true).SetTitle("Table")
279
280 code := tview.NewTextView().
281 SetWrap(false).
282 SetDynamicColors(true)
283 code.SetBorderPadding(1, 1, 2, 0)
284
285 list := tview.NewList()
286
287 basic := func() {
288 table.SetBorders(false).
289 SetSelectable(false, false).
290 SetSeparator(' ')
291 code.Clear()
292 fmt.Fprint(code, tableBasic)
293 }
294
295 separator := func() {
296 table.SetBorders(false).
297 SetSelectable(false, false).
298 SetSeparator(tview.Borders.Vertical)
299 code.Clear()
300 fmt.Fprint(code, tableSeparator)
301 }
302
303 borders := func() {
304 table.SetBorders(true).
305 SetSelectable(false, false)
306 code.Clear()
307 fmt.Fprint(code, tableBorders)
308 }
309
310 selectRow := func() {
311 table.SetBorders(false).
312 SetSelectable(true, false).
313 SetSeparator(' ')
314 code.Clear()
315 fmt.Fprint(code, tableSelectRow)
316 }
317
318 selectColumn := func() {
319 table.SetBorders(false).
320 SetSelectable(false, true).
321 SetSeparator(' ')
322 code.Clear()
323 fmt.Fprint(code, tableSelectColumn)
324 }
325
326 selectCell := func() {
327 table.SetBorders(false).
328 SetSelectable(true, true).
329 SetSeparator(' ')
330 code.Clear()
331 fmt.Fprint(code, tableSelectCell)
332 }
333
334 navigate := func() {
335 app.SetFocus(table)
336 table.SetDoneFunc(func(key tcell.Key) {
337 app.SetFocus(list)
338 }).SetSelectedFunc(func(row int, column int) {
339 app.SetFocus(list)
340 })
341 }
342
343 list.ShowSecondaryText(false).
344 AddItem("Basic table", "", 'b', basic).
345 AddItem("Table with separator", "", 's', separator).
346 AddItem("Table with borders", "", 'o', borders).
347 AddItem("Selectable rows", "", 'r', selectRow).
348 AddItem("Selectable columns", "", 'c', selectColumn).
349 AddItem("Selectable cells", "", 'l', selectCell).
350 AddItem("Navigate", "", 'n', navigate).
351 AddItem("Next slide", "", 'x', nextSlide)
352 list.SetBorderPadding(1, 1, 2, 2)
353
354 basic()
355
356 return "Table", tview.NewFlex().
357 AddItem(tview.NewFlex().
358 SetDirection(tview.FlexRow).
359 AddItem(list, 10, 1, true).
360 AddItem(table, 0, 1, false), 0, 1, true).
361 AddItem(code, codeWidth, 1, false)
362 }
363
View as plain text