mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-06 18:32:50 +08:00
Initial commit
This commit is contained in:
48
gui/gui.go
Normal file
48
gui/gui.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/logger"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
)
|
||||
|
||||
const MODULE_GUI = "GUI"
|
||||
|
||||
var App fyne.App
|
||||
var MainWindow fyne.Window
|
||||
|
||||
func l() *logrus.Entry {
|
||||
return logger.Logger.WithField("Module", MODULE_GUI)
|
||||
}
|
||||
|
||||
func Initialize() {
|
||||
os.Setenv("FYNE_FONT", config.GetAssetPath("msyh.ttc"))
|
||||
App = app.New()
|
||||
MainWindow = App.NewWindow("AynaLivePlayer")
|
||||
|
||||
tabs := container.NewAppTabs(
|
||||
container.NewTabItem("Player",
|
||||
newPaddedBoarder(nil, createPlayController(), nil, nil, createPlaylist()),
|
||||
),
|
||||
container.NewTabItem("Search",
|
||||
newPaddedBoarder(createSearchBar(), nil, nil, nil, createSearchList()),
|
||||
),
|
||||
container.NewTabItem("Room",
|
||||
newPaddedBoarder(createRoomController(), nil, nil, nil, createRoomLogger()),
|
||||
),
|
||||
container.NewTabItem("Playlist",
|
||||
newPaddedBoarder(nil, nil, createPlaylists(), nil, createPlaylistMedias()),
|
||||
),
|
||||
)
|
||||
|
||||
tabs.SetTabLocation(container.TabLocationTop)
|
||||
|
||||
MainWindow.SetContent(tabs)
|
||||
//MainWindow.Resize(fyne.NewSize(1280, 720))
|
||||
MainWindow.Resize(fyne.NewSize(960, 480))
|
||||
//MainWindow.SetFixedSize(true)
|
||||
}
|
||||
33
gui/helper.go
Normal file
33
gui/helper.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
func newPaddedBoarder(top, bottom, left, right fyne.CanvasObject, objects ...fyne.CanvasObject) *fyne.Container {
|
||||
return container.NewPadded(container.NewBorder(top, bottom, left, right, objects...))
|
||||
}
|
||||
|
||||
func newLabelWithWrapping(text string, wrapping fyne.TextWrap) *widget.Label {
|
||||
w := widget.NewLabel(text)
|
||||
w.Wrapping = wrapping
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func createAsyncOnTapped(btn *widget.Button, f func()) func() {
|
||||
return func() {
|
||||
btn.Disable()
|
||||
go func() {
|
||||
f()
|
||||
btn.Enable()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func createAsyncButton(btn *widget.Button, tapped func()) *widget.Button {
|
||||
btn.OnTapped = createAsyncOnTapped(btn, tapped)
|
||||
return btn
|
||||
}
|
||||
213
gui/player_controller.go
Normal file
213
gui/player_controller.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/player"
|
||||
"AynaLivePlayer/util"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/storage"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/aynakeya/go-mpv"
|
||||
)
|
||||
|
||||
type PlayControllerContainer struct {
|
||||
Title *widget.Label
|
||||
Artist *widget.Label
|
||||
Username *widget.Label
|
||||
Cover *canvas.Image
|
||||
ButtonPrev *widget.Button
|
||||
ButtonSwitch *widget.Button
|
||||
ButtonNext *widget.Button
|
||||
Progress *widget.Slider
|
||||
Volume *widget.Slider
|
||||
ButtonLrc *widget.Button
|
||||
LrcWindowOpen bool
|
||||
CurrentTime *widget.Label
|
||||
TotalTime *widget.Label
|
||||
}
|
||||
|
||||
func (p *PlayControllerContainer) SetDefaultCover() {
|
||||
p.Cover.Resource = nil
|
||||
p.Cover.File = config.GetAssetPath("empty.png")
|
||||
p.Cover.Refresh()
|
||||
}
|
||||
|
||||
var PlayController = &PlayControllerContainer{}
|
||||
|
||||
func createPlayController() fyne.CanvasObject {
|
||||
PlayController.Cover = canvas.NewImageFromFile(config.GetAssetPath("empty.png"))
|
||||
PlayController.Cover.SetMinSize(fyne.NewSize(128, 128))
|
||||
PlayController.Cover.FillMode = canvas.ImageFillContain
|
||||
|
||||
PlayController.ButtonPrev = widget.NewButtonWithIcon("", theme.MediaSkipPreviousIcon(), func() {})
|
||||
PlayController.ButtonSwitch = widget.NewButtonWithIcon("", theme.MediaPlayIcon(), func() {})
|
||||
PlayController.ButtonNext = widget.NewButtonWithIcon("", theme.MediaSkipNextIcon(), func() {})
|
||||
|
||||
buttonsBox := container.NewCenter(
|
||||
container.NewHBox(PlayController.ButtonPrev, PlayController.ButtonSwitch, PlayController.ButtonNext))
|
||||
|
||||
PlayController.Progress = widget.NewSlider(0, 10000)
|
||||
PlayController.CurrentTime = widget.NewLabel("0:00")
|
||||
PlayController.TotalTime = widget.NewLabel("0:00")
|
||||
progressItem := container.NewBorder(nil, nil, PlayController.CurrentTime, PlayController.TotalTime, PlayController.Progress)
|
||||
|
||||
PlayController.Title = widget.NewLabel("Title")
|
||||
PlayController.Artist = widget.NewLabel("Artist")
|
||||
PlayController.Username = widget.NewLabel("Username")
|
||||
|
||||
playInfo := container.NewVBox(PlayController.Title, PlayController.Artist, PlayController.Username)
|
||||
|
||||
PlayController.Volume = widget.NewSlider(0, 100)
|
||||
volumeIcon := widget.NewIcon(theme.VolumeMuteIcon())
|
||||
PlayController.ButtonLrc = widget.NewButton("lrc", func() {})
|
||||
|
||||
volumeControl := container.NewBorder(nil, nil, container.NewHBox(widget.NewLabel(" "), volumeIcon), nil,
|
||||
container.NewGridWithColumns(3, container.NewMax(PlayController.Volume), PlayController.ButtonLrc))
|
||||
|
||||
registerPlayControllerHandler()
|
||||
|
||||
return container.NewBorder(nil, nil, container.NewHBox(PlayController.Cover, playInfo, widget.NewSeparator()), nil,
|
||||
container.NewVBox(buttonsBox, progressItem, volumeControl))
|
||||
}
|
||||
|
||||
func registerPlayControllerHandler() {
|
||||
PlayController.ButtonPrev.OnTapped = func() {
|
||||
controller.Seek(0, true)
|
||||
}
|
||||
PlayController.ButtonSwitch.OnTapped = func() {
|
||||
if controller.Toggle() {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaPlayIcon()
|
||||
} else {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaStopIcon()
|
||||
}
|
||||
}
|
||||
PlayController.ButtonNext.OnTapped = func() {
|
||||
controller.PlayNext()
|
||||
}
|
||||
|
||||
PlayController.ButtonLrc.OnTapped = func() {
|
||||
if !PlayController.LrcWindowOpen {
|
||||
PlayController.LrcWindowOpen = true
|
||||
createLyricWindow().Show()
|
||||
}
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("pause", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaPlayIcon()
|
||||
return
|
||||
}
|
||||
if property.Data.(mpv.Node).Value.(bool) {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaPlayIcon()
|
||||
} else {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaStopIcon()
|
||||
}
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for switch button with property pause")
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("percent-pos", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
PlayController.Progress.SetValue(0)
|
||||
return
|
||||
}
|
||||
PlayController.Progress.Value = property.Data.(mpv.Node).Value.(float64) * 100
|
||||
PlayController.Progress.Refresh()
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for progress bar with property percent-pos")
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("idle-active", func(property *mpv.EventProperty) {
|
||||
isIdle := property.Data.(mpv.Node).Value.(bool)
|
||||
l().Debug("receive idle active ", isIdle, " set/reset info")
|
||||
// todo: @3
|
||||
if isIdle {
|
||||
PlayController.Progress.Value = 0
|
||||
PlayController.Progress.Max = 0
|
||||
//PlayController.Title.SetText("Title")
|
||||
//PlayController.Artist.SetText("Artist")
|
||||
//PlayController.Username.SetText("Username")
|
||||
//PlayController.SetDefaultCover()
|
||||
} else {
|
||||
PlayController.Progress.Max = 10000
|
||||
}
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for progress bar with property idle-active")
|
||||
}
|
||||
|
||||
PlayController.Progress.OnChanged = func(f float64) {
|
||||
controller.Seek(f/100, false)
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("time-pos", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
PlayController.CurrentTime.SetText("0:00")
|
||||
return
|
||||
}
|
||||
PlayController.CurrentTime.SetText(util.FormatTime(int(property.Data.(mpv.Node).Value.(float64))))
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for current time with property time-pos")
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("duration", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
PlayController.TotalTime.SetText("0:00")
|
||||
return
|
||||
}
|
||||
PlayController.TotalTime.SetText(util.FormatTime(int(property.Data.(mpv.Node).Value.(float64))))
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for total time with property duration")
|
||||
}
|
||||
|
||||
if controller.MainPlayer.ObserveProperty("volume", func(property *mpv.EventProperty) {
|
||||
l().Trace("receive volume change event", *property)
|
||||
if property.Data == nil {
|
||||
PlayController.Volume.Value = 0
|
||||
} else {
|
||||
PlayController.Volume.Value = property.Data.(mpv.Node).Value.(float64)
|
||||
}
|
||||
|
||||
PlayController.Volume.Refresh()
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for progress bar with property percent-pos")
|
||||
}
|
||||
|
||||
PlayController.Volume.OnChanged = func(f float64) {
|
||||
controller.SetVolume(f)
|
||||
}
|
||||
|
||||
controller.MainPlayer.EventHandler.RegisterA(player.EventPlay, "gui.player.updateinfo", func(event *event.Event) {
|
||||
l().Debug("receive EventPlay update player info")
|
||||
media := event.Data.(player.PlayEvent).Media
|
||||
PlayController.Title.SetText(
|
||||
util.StringNormalize(media.Title, 16, 16))
|
||||
PlayController.Artist.SetText(
|
||||
util.StringNormalize(media.Artist, 16, 16))
|
||||
PlayController.Username.SetText(media.ToUser().Name)
|
||||
if media.Cover == "" {
|
||||
PlayController.SetDefaultCover()
|
||||
} else {
|
||||
uri, err := storage.ParseURI(media.Cover)
|
||||
if err != nil {
|
||||
l().Warn("fail to load parse cover url", media.Cover)
|
||||
}
|
||||
// async update
|
||||
go func() {
|
||||
img := canvas.NewImageFromURI(uri)
|
||||
if img == nil {
|
||||
l().Warn("fail to load parse cover url", media.Cover)
|
||||
PlayController.SetDefaultCover()
|
||||
return
|
||||
}
|
||||
PlayController.Cover.Resource = img.Resource
|
||||
PlayController.Cover.Refresh()
|
||||
}()
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
61
gui/player_lyric.go
Normal file
61
gui/player_lyric.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/player"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func createLyricWindow() fyne.Window {
|
||||
|
||||
// create widgets
|
||||
w := App.NewWindow("Lyric")
|
||||
currentLrc := newLabelWithWrapping("", fyne.TextWrapBreak)
|
||||
currentLrc.Alignment = fyne.TextAlignCenter
|
||||
lrcs := make([]string, len(controller.CurrentLyric.Lyrics))
|
||||
for i := 0; i < len(lrcs); i++ {
|
||||
lrcs[i] = controller.CurrentLyric.Lyrics[i].Lyric
|
||||
}
|
||||
fullLrc := widget.NewRichTextWithText(strings.Join(lrcs, "\n\n"))
|
||||
fullLrc.Scroll = container.ScrollVerticalOnly
|
||||
fullLrc.Wrapping = fyne.TextWrapWord
|
||||
w.SetContent(container.NewBorder(nil,
|
||||
container.NewVBox(widget.NewSeparator(), currentLrc),
|
||||
nil, nil,
|
||||
fullLrc))
|
||||
w.Resize(fyne.NewSize(360, 540))
|
||||
w.CenterOnScreen()
|
||||
|
||||
// register handlers
|
||||
controller.CurrentLyric.Handler.RegisterA(player.EventLyricUpdate, "player.lyric.current_lyric", func(event *event.Event) {
|
||||
e := event.Data.(player.LyricUpdateEvent)
|
||||
if e.Lyric == nil {
|
||||
currentLrc.SetText("")
|
||||
return
|
||||
}
|
||||
currentLrc.SetText(e.Lyric.Lyric)
|
||||
})
|
||||
controller.CurrentLyric.Handler.RegisterA(player.EventLyricReload, "player.lyric.new_media", func(event *event.Event) {
|
||||
e := event.Data.(player.LyricReloadEvent)
|
||||
lrcs := make([]string, len(e.Lyrics.Lyrics))
|
||||
for i := 0; i < len(lrcs); i++ {
|
||||
lrcs[i] = e.Lyrics.Lyrics[i].Lyric
|
||||
}
|
||||
fullLrc.Segments[0] = &widget.TextSegment{
|
||||
Style: widget.RichTextStyleInline,
|
||||
Text: strings.Join(lrcs, "\n\n"),
|
||||
}
|
||||
fullLrc.Refresh()
|
||||
})
|
||||
|
||||
w.SetOnClosed(func() {
|
||||
controller.CurrentLyric.Handler.Unregister("player.lyric.current_lyric")
|
||||
controller.CurrentLyric.Handler.Unregister("player.lyric.new_media")
|
||||
PlayController.LrcWindowOpen = false
|
||||
})
|
||||
return w
|
||||
}
|
||||
57
gui/player_playlist.go
Normal file
57
gui/player_playlist.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/player"
|
||||
"fmt"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type PlaylistContainer struct {
|
||||
Playlist *player.Playlist
|
||||
List *widget.List
|
||||
}
|
||||
|
||||
var UserPlaylist = &PlaylistContainer{}
|
||||
|
||||
func createPlaylist() fyne.CanvasObject {
|
||||
UserPlaylist.Playlist = controller.UserPlaylist
|
||||
UserPlaylist.List = widget.NewList(
|
||||
func() int {
|
||||
//debug.PrintStack()
|
||||
// todo: @4
|
||||
return UserPlaylist.Playlist.Size()
|
||||
},
|
||||
func() fyne.CanvasObject {
|
||||
return container.NewBorder(nil, nil, widget.NewLabel("index"), widget.NewLabel("user"),
|
||||
container.NewGridWithColumns(2,
|
||||
newLabelWithWrapping("title", fyne.TextTruncate),
|
||||
newLabelWithWrapping("artist", fyne.TextTruncate)))
|
||||
},
|
||||
func(id widget.ListItemID, object fyne.CanvasObject) {
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[0].(*widget.Label).SetText(
|
||||
UserPlaylist.Playlist.Playlist[id].Title)
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[1].(*widget.Label).SetText(
|
||||
UserPlaylist.Playlist.Playlist[id].Artist)
|
||||
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
|
||||
object.(*fyne.Container).Objects[2].(*widget.Label).SetText(UserPlaylist.Playlist.Playlist[id].ToUser().Name)
|
||||
})
|
||||
registerPlaylistHandler()
|
||||
return container.NewBorder(
|
||||
container.NewBorder(nil, nil,
|
||||
widget.NewLabel("#"), widget.NewLabel("User"),
|
||||
container.NewGridWithColumns(2, widget.NewLabel("Title"), widget.NewLabel("Artist"))),
|
||||
widget.NewSeparator(),
|
||||
nil, nil,
|
||||
UserPlaylist.List,
|
||||
)
|
||||
}
|
||||
|
||||
func registerPlaylistHandler() {
|
||||
UserPlaylist.Playlist.Handler.RegisterA(player.EventPlaylistUpdate, "gui.playlist.update", func(event *event.Event) {
|
||||
UserPlaylist.List.Refresh()
|
||||
})
|
||||
}
|
||||
149
gui/playlist_list.go
Normal file
149
gui/playlist_list.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"fmt"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type PlaylistManagerContainer struct {
|
||||
Playlists *widget.List
|
||||
PlaylistMedia *widget.List
|
||||
Index int
|
||||
AddBtn *widget.Button
|
||||
RemoveBtn *widget.Button
|
||||
SetAsSystemBtn *widget.Button
|
||||
RefreshBtn *widget.Button
|
||||
CurrentSystemPlaylist *widget.Label
|
||||
}
|
||||
|
||||
func (p *PlaylistManagerContainer) UpdateCurrentSystemPlaylist() {
|
||||
if config.Player.PlaylistIndex >= len(controller.PlaylistManager) {
|
||||
p.CurrentSystemPlaylist.SetText("Current: None")
|
||||
}
|
||||
p.CurrentSystemPlaylist.SetText("Current: " + controller.PlaylistManager[config.Player.PlaylistIndex].Name)
|
||||
}
|
||||
|
||||
var PlaylistManager = &PlaylistManagerContainer{}
|
||||
|
||||
func createPlaylists() fyne.CanvasObject {
|
||||
PlaylistManager.Playlists = widget.NewList(
|
||||
func() int {
|
||||
return len(controller.PlaylistManager)
|
||||
},
|
||||
func() fyne.CanvasObject {
|
||||
return widget.NewLabel("AAAAAAAAAAAAAAAA")
|
||||
},
|
||||
func(id widget.ListItemID, object fyne.CanvasObject) {
|
||||
object.(*widget.Label).SetText(
|
||||
controller.PlaylistManager[id].Name)
|
||||
})
|
||||
PlaylistManager.AddBtn = widget.NewButton("Add", func() {
|
||||
providerEntry := widget.NewSelect(config.Provider.Priority, nil)
|
||||
idEntry := widget.NewEntry()
|
||||
dia := dialog.NewCustomConfirm(
|
||||
"Add Playlist",
|
||||
"Add",
|
||||
"Cancel",
|
||||
container.NewVBox(
|
||||
container.New(
|
||||
layout.NewFormLayout(),
|
||||
widget.NewLabel("Provider"),
|
||||
providerEntry,
|
||||
widget.NewLabel("ID/URL"),
|
||||
idEntry,
|
||||
),
|
||||
widget.NewLabel("Please Enter playlist id or playlist url"),
|
||||
),
|
||||
func(b bool) {
|
||||
if b && len(providerEntry.Selected) > 0 && len(idEntry.Text) > 0 {
|
||||
controller.AddPlaylist(providerEntry.Selected, idEntry.Text)
|
||||
PlaylistManager.Playlists.Refresh()
|
||||
PlaylistManager.PlaylistMedia.Refresh()
|
||||
}
|
||||
},
|
||||
MainWindow,
|
||||
)
|
||||
dia.Resize(fyne.NewSize(512, 256))
|
||||
dia.Show()
|
||||
})
|
||||
PlaylistManager.RemoveBtn = widget.NewButton("Remove", func() {
|
||||
controller.RemovePlaylist(PlaylistManager.Index)
|
||||
//PlaylistManager.Index = 0
|
||||
PlaylistManager.Playlists.Select(0)
|
||||
PlaylistManager.Playlists.Refresh()
|
||||
PlaylistManager.PlaylistMedia.Refresh()
|
||||
})
|
||||
PlaylistManager.Playlists.OnSelected = func(id widget.ListItemID) {
|
||||
PlaylistManager.Index = id
|
||||
}
|
||||
return container.NewHBox(
|
||||
container.NewBorder(
|
||||
nil, container.NewCenter(container.NewHBox(PlaylistManager.AddBtn, PlaylistManager.RemoveBtn)),
|
||||
nil, nil,
|
||||
PlaylistManager.Playlists,
|
||||
),
|
||||
widget.NewSeparator(),
|
||||
)
|
||||
}
|
||||
|
||||
func createPlaylistMedias() fyne.CanvasObject {
|
||||
PlaylistManager.RefreshBtn = createAsyncButton(
|
||||
widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), nil),
|
||||
func() {
|
||||
controller.PreparePlaylistByIndex(PlaylistManager.Index)
|
||||
PlaylistManager.PlaylistMedia.Refresh()
|
||||
})
|
||||
PlaylistManager.SetAsSystemBtn = createAsyncButton(
|
||||
widget.NewButton("SetAsSystem", nil),
|
||||
func() {
|
||||
controller.SetSystemPlaylist(PlaylistManager.Index)
|
||||
PlaylistManager.PlaylistMedia.Refresh()
|
||||
PlaylistManager.UpdateCurrentSystemPlaylist()
|
||||
})
|
||||
PlaylistManager.CurrentSystemPlaylist = widget.NewLabel("Current: ")
|
||||
PlaylistManager.UpdateCurrentSystemPlaylist()
|
||||
PlaylistManager.PlaylistMedia = widget.NewList(
|
||||
func() int {
|
||||
if len(controller.PlaylistManager) == 0 {
|
||||
return 0
|
||||
}
|
||||
return controller.PlaylistManager[PlaylistManager.Index].Size()
|
||||
},
|
||||
func() fyne.CanvasObject {
|
||||
return container.NewBorder(nil, nil,
|
||||
widget.NewLabel("index"),
|
||||
container.NewHBox(
|
||||
widget.NewButtonWithIcon("", theme.MediaPlayIcon(), nil),
|
||||
widget.NewButtonWithIcon("", theme.ContentAddIcon(), nil),
|
||||
),
|
||||
container.NewGridWithColumns(2,
|
||||
newLabelWithWrapping("title", fyne.TextTruncate),
|
||||
newLabelWithWrapping("artist", fyne.TextTruncate)))
|
||||
},
|
||||
func(id widget.ListItemID, object fyne.CanvasObject) {
|
||||
m := controller.PlaylistManager[PlaylistManager.Index].Playlist[id]
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[0].(*widget.Label).SetText(
|
||||
m.Title)
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[1].(*widget.Label).SetText(
|
||||
m.Artist)
|
||||
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
|
||||
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
|
||||
btns[0].(*widget.Button).OnTapped = func() {
|
||||
controller.Play(m)
|
||||
}
|
||||
btns[1].(*widget.Button).OnTapped = func() {
|
||||
controller.UserPlaylist.Push(m)
|
||||
}
|
||||
})
|
||||
return container.NewBorder(
|
||||
container.NewHBox(PlaylistManager.RefreshBtn, PlaylistManager.SetAsSystemBtn), nil,
|
||||
nil, nil,
|
||||
PlaylistManager.PlaylistMedia)
|
||||
}
|
||||
56
gui/room_bar.go
Normal file
56
gui/room_bar.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/liveclient"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type RoomControllerContainer struct {
|
||||
Input *widget.SelectEntry
|
||||
ConnectBtn *widget.Button
|
||||
DisConnectBtn *widget.Button
|
||||
Status *widget.Label
|
||||
}
|
||||
|
||||
var RoomController = &RoomControllerContainer{}
|
||||
|
||||
func createRoomController() fyne.CanvasObject {
|
||||
RoomController.Input = widget.NewSelectEntry(config.LiveRoom.History)
|
||||
RoomController.ConnectBtn = widget.NewButton("Connect", func() {
|
||||
RoomController.ConnectBtn.Disable()
|
||||
controller.SetDanmuClient(RoomController.Input.Text)
|
||||
if controller.LiveClient == nil {
|
||||
RoomController.Status.SetText("Set Failed")
|
||||
RoomController.Status.Refresh()
|
||||
return
|
||||
}
|
||||
RoomController.Input.SetOptions(config.LiveRoom.History)
|
||||
controller.LiveClient.Handler().RegisterA(liveclient.EventStatusChange, "gui.liveclient.status", func(event *event.Event) {
|
||||
d := event.Data.(liveclient.StatusChangeEvent)
|
||||
if d.Connected {
|
||||
RoomController.Status.SetText("Connected")
|
||||
} else {
|
||||
RoomController.Status.SetText("Disconnected")
|
||||
}
|
||||
RoomController.Status.Refresh()
|
||||
})
|
||||
go func() {
|
||||
controller.StartDanmuClient()
|
||||
RoomController.ConnectBtn.Enable()
|
||||
}()
|
||||
})
|
||||
RoomController.DisConnectBtn = widget.NewButton("Disconnect", func() {
|
||||
controller.ResetDanmuClient()
|
||||
})
|
||||
RoomController.Status = widget.NewLabel("Waiting")
|
||||
return container.NewBorder(
|
||||
nil, nil,
|
||||
widget.NewLabel("Room ID:"), container.NewHBox(RoomController.ConnectBtn, RoomController.DisConnectBtn),
|
||||
container.NewBorder(nil, nil, nil, RoomController.Status, RoomController.Input),
|
||||
)
|
||||
}
|
||||
15
gui/room_logger.go
Normal file
15
gui/room_logger.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type RoomLoggerContainer struct {
|
||||
}
|
||||
|
||||
var RoomLogger = &RoomLoggerContainer{}
|
||||
|
||||
func createRoomLogger() fyne.CanvasObject {
|
||||
return widget.NewLabel("广告位招租")
|
||||
}
|
||||
53
gui/search_bar.go
Normal file
53
gui/search_bar.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/player"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type SearchBarContainer struct {
|
||||
Input *widget.Entry
|
||||
Button *widget.Button
|
||||
UseSource *widget.CheckGroup
|
||||
Items []*player.Media
|
||||
}
|
||||
|
||||
var SearchBar = &SearchBarContainer{}
|
||||
|
||||
func createSearchBar() fyne.CanvasObject {
|
||||
SearchBar.Input = widget.NewEntry()
|
||||
SearchBar.Input.SetPlaceHolder("Keyword")
|
||||
SearchBar.Button = widget.NewButton("Search", nil)
|
||||
SearchBar.Button.OnTapped = createAsyncOnTapped(SearchBar.Button, func() {
|
||||
keyword := SearchBar.Input.Text
|
||||
s := make([]string, len(SearchBar.UseSource.Selected))
|
||||
|
||||
copy(s, SearchBar.UseSource.Selected)
|
||||
items := make([]*player.Media, 0)
|
||||
for _, p := range s {
|
||||
if r, err := controller.SearchWithProvider(keyword, p); err == nil {
|
||||
items = append(items, r...)
|
||||
}
|
||||
}
|
||||
controller.ApplyUser(items, player.SystemUser)
|
||||
SearchResult.Items = items
|
||||
SearchResult.List.Refresh()
|
||||
})
|
||||
s := make([]string, len(config.Provider.Priority))
|
||||
copy(s, config.Provider.Priority)
|
||||
|
||||
SearchBar.UseSource = widget.NewCheckGroup(s, nil)
|
||||
SearchBar.UseSource.Horizontal = true
|
||||
SearchBar.UseSource.SetSelected(s)
|
||||
searchInput := container.NewBorder(
|
||||
nil, nil, widget.NewLabel("Search"), SearchBar.Button,
|
||||
SearchBar.Input)
|
||||
return container.NewVBox(
|
||||
searchInput,
|
||||
container.NewHBox(widget.NewLabel("Source filter: "), SearchBar.UseSource),
|
||||
widget.NewSeparator())
|
||||
}
|
||||
64
gui/search_list.go
Normal file
64
gui/search_list.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/player"
|
||||
"AynaLivePlayer/provider"
|
||||
"fmt"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type SearchResultContainer struct {
|
||||
List *widget.List
|
||||
Items []*player.Media
|
||||
}
|
||||
|
||||
var SearchResult = &SearchResultContainer{Items: []*player.Media{}}
|
||||
|
||||
func createSearchList() fyne.CanvasObject {
|
||||
SearchResult.List = widget.NewList(
|
||||
func() int {
|
||||
return len(SearchResult.Items)
|
||||
},
|
||||
func() fyne.CanvasObject {
|
||||
return container.NewBorder(nil, nil,
|
||||
widget.NewLabel("index"),
|
||||
container.NewHBox(
|
||||
widget.NewButtonWithIcon("", theme.MediaPlayIcon(), nil),
|
||||
widget.NewButtonWithIcon("", theme.ContentAddIcon(), nil),
|
||||
),
|
||||
container.NewGridWithColumns(3,
|
||||
newLabelWithWrapping("title", fyne.TextTruncate),
|
||||
newLabelWithWrapping("artist", fyne.TextTruncate),
|
||||
newLabelWithWrapping("source", fyne.TextTruncate)))
|
||||
},
|
||||
func(id widget.ListItemID, object fyne.CanvasObject) {
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[0].(*widget.Label).SetText(
|
||||
SearchResult.Items[id].Title)
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[1].(*widget.Label).SetText(
|
||||
SearchResult.Items[id].Artist)
|
||||
object.(*fyne.Container).Objects[0].(*fyne.Container).Objects[2].(*widget.Label).SetText(
|
||||
SearchResult.Items[id].Meta.(provider.Meta).Name)
|
||||
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
|
||||
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
|
||||
btns[0].(*widget.Button).OnTapped = func() {
|
||||
controller.Play(SearchResult.Items[id])
|
||||
}
|
||||
btns[1].(*widget.Button).OnTapped = func() {
|
||||
controller.UserPlaylist.Push(SearchResult.Items[id])
|
||||
}
|
||||
})
|
||||
return container.NewBorder(
|
||||
container.NewBorder(nil, nil,
|
||||
widget.NewLabel("#"), widget.NewLabel("Operation"),
|
||||
container.NewGridWithColumns(3,
|
||||
widget.NewLabel("title"),
|
||||
widget.NewLabel("artist"),
|
||||
widget.NewLabel("source"))),
|
||||
nil, nil, nil,
|
||||
SearchResult.List,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user