music_player_page.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. package MusicPlayer
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "log"
  6. "strconv"
  7. "strings"
  8. "github.com/cuu/gogame/event"
  9. "github.com/cuu/gogame/rect"
  10. "github.com/cuu/gogame/surface"
  11. // "github.com/cuu/gogame/time"
  12. gotime "time"
  13. //"github.com/veandco/go-sdl2/sdl"
  14. "github.com/veandco/go-sdl2/ttf"
  15. "github.com/cuu/gogame/color"
  16. "github.com/clockworkpi/LauncherGoDev/sysgo"
  17. "github.com/clockworkpi/LauncherGoDev/sysgo/UI"
  18. "github.com/fhs/gompd/v2/mpd"
  19. )
  20. type MusicPlayerPage struct {
  21. UI.Page
  22. ListFontObj *ttf.Font
  23. URLColor *color.Color
  24. TextColor *color.Color
  25. Labels map[string]UI.LabelInterface
  26. Icons map[string]UI.IconItemInterface
  27. IP string
  28. MyMusicLibListPage *MusicLibListPage //also use the MpdClient *mpd.Client
  29. //MyList []UI.ListItemInterface
  30. MyStack *UI.FolderStack
  31. BGwidth int
  32. BGheight int //70
  33. Scroller *UI.ListScroller
  34. Scrolled int
  35. MpdClient *mpd.Client
  36. CurSongTime string
  37. CurSongName string
  38. playing_ch chan bool
  39. PlayerOn bool
  40. }
  41. func NewMusicPlayerPage() *MusicPlayerPage {
  42. p := &MusicPlayerPage{}
  43. p.PageIconMargin = 20
  44. p.SelectedIconTopOffset = 20
  45. p.EasingDur = 10
  46. p.Align = UI.ALIGN["SLeft"]
  47. p.FootMsg = [5]string{"Nav","Remove","","Back","Play/Pause"}
  48. p.URLColor = UI.MySkinManager.GiveColor("URL")
  49. p.TextColor = UI.MySkinManager.GiveColor("Text")
  50. p.ListFontObj = UI.MyLangManager.TrFont("notosanscjk14")
  51. p.Labels = make(map[string]UI.LabelInterface)
  52. p.Icons = make(map[string]UI.IconItemInterface)
  53. p.BGwidth = 56
  54. p.BGheight = 70
  55. p.CurSongTime = "0:0"
  56. p.playing_ch = make(chan bool,1)
  57. p.PlayerOn = false
  58. return p
  59. }
  60. func (self *MusicPlayerPage) OnLoadCb() {
  61. self.PosY = 0
  62. self.PlayerOn = true
  63. if self.MpdClient == nil {
  64. conn, err := mpd.Dial("unix", sysgo.MPD_socket)
  65. if err != nil {
  66. log.Fatalln(err)
  67. }
  68. self.MpdClient = conn
  69. fmt.Println("Start mpd client")
  70. }
  71. self.SyncList()
  72. self.SetPlaying(true)
  73. go self.UpdatePlayingStatus(250)
  74. }
  75. func (self *MusicPlayerPage) OnPopUpCb() {
  76. if self.MpdClient != nil {
  77. self.MpdClient.Close()
  78. self.MpdClient = nil
  79. fmt.Println("Close mpd client")
  80. }
  81. }
  82. func (self *MusicPlayerPage) OnReturnBackCb() {
  83. self.SyncList()
  84. }
  85. func (self *MusicPlayerPage) SyncList() {
  86. conn := self.MpdClient
  87. start_x := 0
  88. start_y := 0
  89. if conn == nil {
  90. return
  91. }
  92. self.MyList = nil
  93. play_list,_ := conn.PlaylistInfo(-1,-1)
  94. for i,v := range play_list {
  95. li := NewMusicPlayPageListItem()
  96. li.Parent = self
  97. li.PosX = start_x
  98. li.PosY = start_y + UI.DefaultInfoPageListItemHeight * i
  99. li.Width = UI.Width
  100. li.Fonts["normal"] = self.ListFontObj
  101. if val,ok:=v["Title"]; ok {
  102. li.Init(val)
  103. if val2,ok2 := v["file"]; ok2 {
  104. li.Path = val2
  105. }
  106. }else {
  107. if val2,ok2 := v["file"]; ok2 {
  108. li.Init(filepath.Base(val2))
  109. li.Path = val2
  110. }else{
  111. li.Init("NoName")
  112. }
  113. }
  114. x,_ := li.Labels["Text"].Coord()
  115. li.Labels["Text"].NewCoord(x,7)
  116. self.MyList = append(self.MyList, li)
  117. }
  118. self.SyncPlaying()
  119. }
  120. func (self *MusicPlayerPage) UpdatePlayingStatus(ms int) {
  121. RefreshTicker := gotime.NewTicker(gotime.Duration(ms)*gotime.Millisecond)
  122. defer RefreshTicker.Stop()
  123. L:
  124. for {
  125. select {
  126. case <- RefreshTicker.C:
  127. cur_pos_id := self.SyncPlaying()
  128. if self.Screen.CurPage() == self && cur_pos_id >= 0 {
  129. self.Screen.Refresh()
  130. }
  131. case v:= <- self.playing_ch:
  132. if v== false {
  133. break L
  134. }
  135. }
  136. }
  137. fmt.Println("Quiting UpdatePlayingStatus")
  138. }
  139. func (self *MusicPlayerPage) SyncPlaying() int {
  140. conn := self.MpdClient
  141. cur_pos_id := -1
  142. if self.PlayerOn == false {
  143. return cur_pos_id
  144. }
  145. for i,_ := range self.MyList {
  146. self.MyList[i].(*MusicPlayPageListItem).Active = false
  147. self.MyList[i].(*MusicPlayPageListItem).PlayingProcess = 0
  148. self.MyList[i].(*MusicPlayPageListItem).State = ""
  149. }
  150. current_song,_ := conn.Status()
  151. if len(current_song) > 0 {
  152. if val,ok := current_song["song"]; ok{
  153. posid, _ := strconv.Atoi(val)
  154. if posid < len(self.MyList) {
  155. cur_pos_id = posid
  156. if state,ok2 := current_song["state"]; ok2 {
  157. if state == "play" {
  158. self.MyList[posid].(*MusicPlayPageListItem).Active = true
  159. }else{
  160. self.MyList[posid].(*MusicPlayPageListItem).Active = false
  161. }
  162. self.MyList[posid].(*MusicPlayPageListItem).State = state
  163. }
  164. if song_time,ok3 := current_song["time"]; ok3 {
  165. self.CurSongTime = song_time
  166. times := strings.Split(self.CurSongTime,":")
  167. if len(times) > 1{
  168. cur,_ := strconv.ParseFloat(times[0],64)
  169. end,_ := strconv.ParseFloat(times[1],64)
  170. pos := int( (cur/end)*100.0 )
  171. self.MyList[posid].(*MusicPlayPageListItem).PlayingProcess = pos
  172. }
  173. }
  174. }
  175. }
  176. }
  177. return cur_pos_id
  178. }
  179. func (self *MusicPlayerPage) InPlayList(path string) bool {
  180. if self.MyList == nil || len(self.MyList) == 0 {
  181. return false
  182. }
  183. for _,v := range self.MyList {
  184. ///fmt.Println(v.(*MusicPlayPageListItem).Path, path)
  185. if v.(*MusicPlayPageListItem).Path == path {
  186. return true
  187. }
  188. }
  189. return false
  190. }
  191. func (self *MusicPlayerPage) SetPlaying( v bool) {
  192. for len(self.playing_ch) > 0 {
  193. <- self.playing_ch
  194. }
  195. self.playing_ch <- v
  196. }
  197. func (self *MusicPlayerPage) StopPlayer() {
  198. self.SetPlaying(false)
  199. conn := self.MpdClient
  200. conn.Stop()
  201. self.CurSongName = ""
  202. self.CurSongTime = "0:0"
  203. }
  204. func (self *MusicPlayerPage) PlayOrPause() {
  205. self.RefreshPsIndex()
  206. if self.MyList == nil || len(self.MyList) == 0 {
  207. return
  208. }
  209. conn := self.MpdClient
  210. cur_song_posid := self.SyncPlaying()
  211. if cur_song_posid == self.PsIndex {
  212. cur_li := self.MyList[self.PsIndex].(*MusicPlayPageListItem)
  213. //fmt.Println(cur_li.State)
  214. if cur_li.State == "pause" {
  215. conn.Pause(false)
  216. }else if cur_li.State == "play" {
  217. conn.Pause(true)
  218. }else {
  219. conn.Play(self.PsIndex)
  220. }
  221. }else{
  222. conn.Play(self.PsIndex)
  223. }
  224. self.SyncPlaying()
  225. self.Screen.Refresh()
  226. }
  227. func (self *MusicPlayerPage) Init() {
  228. if self.Screen == nil {
  229. panic("No Screen")
  230. }
  231. if self.Screen.CanvasHWND != nil && self.CanvasHWND == nil {
  232. self.HWND = self.Screen.CanvasHWND
  233. self.CanvasHWND = surface.Surface(self.Screen.Width, self.Screen.Height)
  234. }
  235. self.PosX = self.Index * self.Screen.Width
  236. self.Width = self.Screen.Width
  237. self.Height = self.Screen.Height
  238. //ps := UI.NewInfoPageSelector()
  239. ps := NewListPageSelector()
  240. //ps.Width = UI.Width - 12
  241. ps.Parent = self
  242. self.Ps = ps
  243. self.PsIndex = 0
  244. bgpng := UI.NewIconItem()
  245. bgpng.ImgSurf = UI.MyIconPool.GetImgSurf("empty")
  246. bgpng.MyType = UI.ICON_TYPES["STAT"]
  247. bgpng.Parent = self
  248. bgpng.AddLabel("Please upload data over Wi-Fi", UI.Fonts["varela22"])
  249. bgpng.SetLabelColor(&color.Color{204, 204, 204, 255})
  250. bgpng.Adjust(0, 0, self.BGwidth, self.BGheight, 0)
  251. self.Icons["bg"] = bgpng
  252. icon_for_list := UI.NewMultiIconItem()
  253. icon_for_list.ImgSurf = UI.MyIconPool.GetImgSurf("sys")
  254. icon_for_list.MyType = UI.ICON_TYPES["STAT"]
  255. icon_for_list.Parent = self
  256. icon_for_list.Adjust(0, 0, 18, 18, 0)
  257. self.Icons["sys"] = icon_for_list
  258. self.Scroller = UI.NewListScroller()
  259. self.Scroller.Parent = self
  260. self.Scroller.PosX = self.Width - 10
  261. self.Scroller.PosY = 2
  262. self.Scroller.Init()
  263. self.MyMusicLibListPage = NewMusicLibListPage()
  264. self.MyMusicLibListPage.Screen = self.Screen
  265. self.MyMusicLibListPage.Name = "Music library"
  266. self.MyMusicLibListPage.Parent = self
  267. self.MyMusicLibListPage.Init()
  268. self.MyStack = UI.NewFolderStack()
  269. self.MyStack.SetRootPath("/")
  270. }
  271. func (self *MusicPlayerPage) KeyDown(ev *event.Event) {
  272. if ev.Data["Key"] == UI.CurKeys["Right"] {
  273. self.Screen.PushPage(self.MyMusicLibListPage)
  274. self.Screen.Refresh()
  275. }
  276. if ev.Data["Key"] == UI.CurKeys["A"] || ev.Data["Key"] == UI.CurKeys["Menu"] {
  277. self.PlayerOn = false
  278. self.StopPlayer()
  279. self.ReturnToUpLevelPage()
  280. self.Screen.Refresh()
  281. }
  282. if ev.Data["Key"] == UI.CurKeys["Up"] {
  283. self.ScrollUp()
  284. self.Screen.Refresh()
  285. }
  286. if ev.Data["Key"] == UI.CurKeys["Down"] {
  287. self.ScrollDown()
  288. self.Screen.Refresh()
  289. }
  290. if ev.Data["Key"] == UI.CurKeys["X"] {
  291. self.MpdClient.Delete(self.PsIndex,-1)
  292. self.SyncList()
  293. self.Screen.Refresh()
  294. }
  295. if ev.Data["Key"] == UI.CurKeys["B"] {
  296. self.PlayOrPause()
  297. }
  298. return
  299. }
  300. func (self *MusicPlayerPage) Draw() {
  301. self.ClearCanvas()
  302. if len(self.MyList) == 0 {
  303. self.Icons["bg"].NewCoord(self.Width/2, self.Height/2)
  304. self.Icons["bg"].Draw()
  305. }else {
  306. if len(self.MyList)*UI.DefaultInfoPageListItemHeight > self.Height {
  307. self.Ps.(*ListPageSelector).Width = self.Width - 11
  308. self.Ps.Draw()
  309. for _, v := range self.MyList {
  310. if v.(*MusicPlayPageListItem).PosY > self.Height+self.Height/2 {
  311. break
  312. }
  313. if v.(*MusicPlayPageListItem).PosY < 0 {
  314. continue
  315. }
  316. v.Draw()
  317. }
  318. self.Scroller.UpdateSize( len(self.MyList)*UI.DefaultInfoPageListItemHeight, self.PsIndex*UI.DefaultInfoPageListItemHeight)
  319. self.Scroller.Draw()
  320. } else{
  321. self.Ps.(*ListPageSelector).Width = self.Width
  322. self.Ps.Draw()
  323. for _, v := range self.MyList {
  324. if v.(*MusicPlayPageListItem).PosY > self.Height+self.Height/2 {
  325. break
  326. }
  327. if v.(*MusicPlayPageListItem).PosY < 0 {
  328. continue
  329. }
  330. v.Draw()
  331. }
  332. }
  333. }
  334. if self.HWND != nil {
  335. surface.Fill(self.HWND, UI.MySkinManager.GiveColor("White"))
  336. rect_ := rect.Rect(self.PosX, self.PosY, self.Width, self.Height)
  337. surface.Blit(self.HWND, self.CanvasHWND, &rect_, nil)
  338. }
  339. }