Initial upload
This commit is contained in:
commit
cefd7abe8a
19 changed files with 1027 additions and 0 deletions
141
app/view.go
Normal file
141
app/view.go
Normal file
|
@ -0,0 +1,141 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type CastingScreenElements struct {
|
||||
TimestampLabel, ProgressBar, DurationLabel fyne.CanvasObject
|
||||
}
|
||||
|
||||
type View struct {
|
||||
Controller *Controller
|
||||
Window fyne.Window
|
||||
CastingScreenElements CastingScreenElements
|
||||
}
|
||||
|
||||
func (v *View) PopupError(err error) {
|
||||
dialog.ShowError(err, v.Window)
|
||||
}
|
||||
|
||||
func NewView(controller *Controller) *View {
|
||||
v := &View{
|
||||
Controller: controller,
|
||||
Window: app.New().NewWindow("FCaster"),
|
||||
}
|
||||
v.Window.Resize(fyne.NewSize(300, 300))
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *View) Start() {
|
||||
v.Window.ShowAndRun()
|
||||
}
|
||||
|
||||
func (v *View) LoadingScreen() {
|
||||
|
||||
loading := container.NewVBox(
|
||||
widget.NewLabel("Discovering devices..."),
|
||||
widget.NewProgressBarInfinite(),
|
||||
widget.NewButton("Refresh", func() { v.Controller.DiscoverDevices() }),
|
||||
)
|
||||
fyne.Do(func() {
|
||||
v.Window.SetContent(loading)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (v *View) MainScreen(deviceNames []string) {
|
||||
|
||||
selector := widget.NewSelect(deviceNames, nil)
|
||||
reloadBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
|
||||
v.Controller.DiscoverDevices()
|
||||
})
|
||||
entry := widget.NewEntry()
|
||||
|
||||
fyne.Do(func() {
|
||||
v.Window.SetContent(container.NewVBox(
|
||||
widget.NewLabel("Select the device:"),
|
||||
container.NewBorder(
|
||||
nil, nil, nil,
|
||||
container.NewVBox(reloadBtn),
|
||||
selector,
|
||||
),
|
||||
widget.NewLabel("Enter the media URL:"),
|
||||
entry,
|
||||
widget.NewButton("Start Casting", func() {
|
||||
v.Controller.StartCasting(selector.Selected, entry.Text)
|
||||
}),
|
||||
widget.NewButton("Join Existing Casting", func() {
|
||||
v.Controller.StartCasting(selector.Selected, "")
|
||||
}),
|
||||
))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (v *View) CastingScreen(deviceName string) {
|
||||
|
||||
v.CastingScreenElements = CastingScreenElements{
|
||||
TimestampLabel: widget.NewLabel("00:00"),
|
||||
DurationLabel: widget.NewLabel("00:00"),
|
||||
ProgressBar: widget.NewSlider(0, 100),
|
||||
}
|
||||
el := v.CastingScreenElements
|
||||
|
||||
el.ProgressBar.(*widget.Slider).OnChanged = func(f float64) {
|
||||
fyne.Do(func() {
|
||||
el.TimestampLabel.(*widget.Label).SetText(formatTime(int(f)))
|
||||
})
|
||||
}
|
||||
el.ProgressBar.(*widget.Slider).OnChangeEnded = func(f float64) {
|
||||
v.Controller.PlayerAction(ArgsActionSeek, float32(f))
|
||||
}
|
||||
|
||||
v.Window.SetContent(container.NewVBox(
|
||||
widget.NewLabel(deviceName),
|
||||
container.NewBorder(
|
||||
nil, nil, el.TimestampLabel, el.DurationLabel,
|
||||
el.ProgressBar,
|
||||
),
|
||||
widget.NewButton("Exit", func() { v.Controller.ExitCasting() }),
|
||||
container.NewHBox(
|
||||
widget.NewButtonWithIcon("", theme.MediaPlayIcon(), func() { v.Controller.PlayerAction(ActionPlay) }),
|
||||
widget.NewButtonWithIcon("", theme.MediaPauseIcon(), func() { v.Controller.PlayerAction(ActionPause) }),
|
||||
widget.NewButtonWithIcon("", theme.MediaFastRewindIcon(), func() { v.Controller.PlayerAction(ActionSkipBack) }),
|
||||
widget.NewButtonWithIcon("", theme.MediaFastForwardIcon(), func() { v.Controller.PlayerAction(ActionSkipForward) }),
|
||||
widget.NewButtonWithIcon("", theme.MediaStopIcon(), func() { v.Controller.PlayerAction(ActionStop) }),
|
||||
widget.NewButtonWithIcon("", theme.VolumeDownIcon(), func() { v.Controller.PlayerAction(ActionVolumeDown) }),
|
||||
widget.NewButtonWithIcon("", theme.VolumeUpIcon(), func() { v.Controller.PlayerAction(ActionVolumeUp) }),
|
||||
),
|
||||
))
|
||||
|
||||
}
|
||||
|
||||
func (v *View) UpdateCastingScreen(action int, args ...float32) {
|
||||
fyne.Do(func() {
|
||||
switch action {
|
||||
case RespPlaybackUpdate:
|
||||
v.CastingScreenElements.ProgressBar.(*widget.Slider).Max = float64(args[0])
|
||||
v.CastingScreenElements.ProgressBar.(*widget.Slider).SetValue(float64(args[1]))
|
||||
// timestamp label is updated from ProgressBar OnChange listener
|
||||
v.CastingScreenElements.DurationLabel.(*widget.Label).SetText(formatTime(int(args[0])))
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func formatTime(seconds int) string {
|
||||
hours := seconds / 3600
|
||||
minutes := (seconds % 3600) / 60
|
||||
sec := seconds % 60
|
||||
if hours == 0 {
|
||||
return fmt.Sprintf("%02d:%02d", minutes, sec)
|
||||
}
|
||||
return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, sec)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue