forked from marcusolsson/tui-go
/
main.go
109 lines (89 loc) · 2.03 KB
/
main.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
package main
import (
"fmt"
"time"
"github.com/marcusolsson/tui-go"
)
type song struct {
artist string
album string
track string
duration time.Duration
}
var songs = []song{
{artist: "DJ Example", album: "Mixtape 3", track: "Testing stuff", duration: 110 * time.Second},
{artist: "DJ Example", album: "Mixtape 3", track: "Breaking stuff", duration: 140 * time.Second},
{artist: "DJ Example", album: "Initial commit", track: "****, not again ...", duration: 150 * time.Second},
}
func main() {
var p player
progress := tui.NewProgress(100)
library := tui.NewTable(0, 0)
library.SetColumnStretch(0, 1)
library.SetColumnStretch(1, 1)
library.SetColumnStretch(2, 4)
library.AppendRow(
tui.NewLabel("ARTIST"),
tui.NewLabel("ALBUM"),
tui.NewLabel("TRACK"),
)
for _, s := range songs {
library.AppendRow(
tui.NewLabel(s.artist),
tui.NewLabel(s.album),
tui.NewLabel(s.track),
)
}
status := tui.NewStatusBar("")
status.SetPermanentText(`VOLUME 68%`)
root := tui.NewVBox(
library,
tui.NewSpacer(),
progress,
status,
)
ui := tui.New(root)
library.OnItemActivated(func(t *tui.Table) {
p.play(songs[t.Selected()-1], func(curr, max int) {
ui.Update(func() {
progress.SetCurrent(curr)
progress.SetMax(max)
status.SetText(fmt.Sprintf("%s / %s", time.Duration(curr)*time.Second, time.Duration(max)*time.Second))
})
})
})
ui.SetKeybinding("Esc", func() { ui.Quit() })
ui.SetKeybinding("q", func() { ui.Quit() })
if err := ui.Run(); err != nil {
panic(err)
}
}
type player struct {
elapsed int
total int
quit chan struct{}
}
func (p *player) play(s song, callback func(current, max int)) {
if p.quit != nil {
p.quit <- struct{}{}
<-p.quit
}
p.quit = make(chan struct{})
p.total = int(s.duration.Seconds())
p.elapsed = 0
go func() {
for {
select {
case <-time.After(1 * time.Second):
if p.elapsed >= p.total {
p.quit <- struct{}{}
}
callback(p.elapsed, p.total)
p.elapsed++
case <-p.quit:
p.quit <- struct{}{}
return
}
}
}()
}