forked from issadarkthing/gomu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gomu.go
155 lines (123 loc) · 3.09 KB
/
gomu.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
package main
import (
"sync"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
"github.com/spf13/viper"
"github.com/ztrue/tracerr"
)
const VERSION = "v1.4.1"
var gomu *Gomu
type Gomu struct {
app *tview.Application
playingBar *PlayingBar
queue *Queue
playlist *Playlist
player *Player
pages *tview.Pages
popups Stack
prevPanel Panel
popupBg tcell.Color
textColor tcell.Color
accentColor tcell.Color
panels []Panel
isSuspend bool
mu sync.Mutex
}
// Creates new instance of gomu with default values
func newGomu() *Gomu {
gomu := &Gomu{
popupBg: tcell.GetColor(viper.GetString("color.popup")),
textColor: tcell.GetColor(viper.GetString("color.foreground")),
accentColor: tcell.GetColor(viper.GetString("color.accent")),
}
return gomu
}
// Initialize childrens/panels this is seperated from
// constructor function `NewGomu` so that we can
// test independently
func (g *Gomu) initPanels(app *tview.Application, args Args) {
g.app = app
g.playingBar = newPlayingBar()
g.queue = newQueue()
g.playlist = newPlaylist(args)
g.player = newPlayer()
g.pages = tview.NewPages()
g.panels = []Panel{g.playlist, g.queue, g.playingBar}
}
// Cycle between panels
func (g *Gomu) cyclePanels() Panel {
var anyChildHasFocus bool
for i, child := range g.panels {
if child.HasFocus() {
anyChildHasFocus = true
var nextChild Panel
// if its the last element set the child back to one
if i == len(g.panels)-1 {
nextChild = g.panels[0]
} else {
nextChild = g.panels[i+1]
}
g.setFocusPanel(nextChild)
g.prevPanel = nextChild
return nextChild
}
}
first := g.panels[0]
if !anyChildHasFocus {
g.setFocusPanel(first)
}
g.prevPanel = first
return first
}
// Changes title and border color when focusing panel
// and changes color of the previous panel as well
func (g *Gomu) setFocusPanel(panel Panel) {
g.app.SetFocus(panel.(tview.Primitive))
panel.SetBorderColor(g.accentColor)
panel.SetTitleColor(g.accentColor)
if g.prevPanel == nil {
return
}
g.setUnfocusPanel(g.prevPanel)
}
// Safely write the IsSuspend state, IsSuspend is used to indicate if we
// are going to suspend the app. This should be used to widgets or
// texts that keeps rendering continuosly or possible to render when the app
// is going to suspend.
// Returns true if app is not in suspend
func (g *Gomu) suspend() bool {
g.mu.Lock()
defer g.mu.Unlock()
if g.isSuspend {
return false
}
g.isSuspend = true
return true
}
// The opposite of Suspend. Returns true if app is in suspend
func (g *Gomu) unsuspend() bool {
g.mu.Lock()
defer g.mu.Unlock()
if !g.isSuspend {
return false
}
g.isSuspend = false
return true
}
// Removes the color of the given panel
func (g *Gomu) setUnfocusPanel(panel Panel) {
g.prevPanel.SetBorderColor(g.textColor)
g.prevPanel.SetTitleColor((g.textColor))
}
// Quit the application and do the neccessary clean up
func (g *Gomu) quit(args Args) error {
if !*args.empty {
err := gomu.queue.saveQueue()
if err != nil {
return tracerr.Wrap(err)
}
}
gomu.app.Stop()
return nil
}