diff --git a/ui/dialogs/settingsdialog.go b/ui/dialogs/settingsdialog.go index 3b19008..67bba8e 100644 --- a/ui/dialogs/settingsdialog.go +++ b/ui/dialogs/settingsdialog.go @@ -1,6 +1,8 @@ package dialogs import ( + "math" + "strconv" "supersonic/backend" "supersonic/ui/widgets" "unicode" @@ -30,32 +32,9 @@ func NewSettingsDialog(config *backend.Config) *SettingsDialog { s := &SettingsDialog{config: config} s.ExtendBaseWidget(s) - replayGainSelect := widget.NewSelect([]string{"None", "Album", "Track"}, nil) - - percentEntry := widgets.NewTextRestrictedEntry(func(text string, r rune) bool { - return unicode.IsDigit(r) && len(text) < 2 - }) - percentEntry.SetMinCharWidth(2) - tabs := container.NewAppTabs( - container.NewTabItem("General", container.NewVBox( - widget.NewRichText(&widget.TextSegment{Text: "Scrobbling", Style: boldStyle}), - widget.NewCheckWithData("Send playback statistics to server", binding.BindBool(&config.Scrobbling.Enabled)), - container.NewHBox( - widget.NewLabel("Scrobble when"), - percentEntry, - widget.NewLabel("percent of track is played"), - ), - )), - container.NewTabItem("Playback", container.NewVBox( - widget.NewRichText(&widget.TextSegment{Text: "ReplayGain", Style: boldStyle}), - container.New(layout.NewFormLayout(), - widget.NewLabel("ReplayGain mode"), replayGainSelect, - widget.NewLabel("Prevent clipping"), widget.NewCheckWithData("", binding.BindBool(&config.ReplayGain.PreventClipping)), - ), - widget.NewSeparator(), - widget.NewCheckWithData("Audio exclusive mode", binding.BindBool(&config.LocalPlayback.AudioExclusive)), - )), + s.createGeneralTab(), + s.createPlaybackTab(), ) s.content = container.NewVBox(tabs, widget.NewSeparator(), container.NewHBox(layout.NewSpacer(), widget.NewButton("Close", func() { @@ -67,6 +46,96 @@ func NewSettingsDialog(config *backend.Config) *SettingsDialog { return s } +func (s *SettingsDialog) createGeneralTab() *container.TabItem { + twoDigitValidator := func(text string, r rune) bool { + return unicode.IsDigit(r) && len(text) < 2 + } + + percentEntry := widgets.NewTextRestrictedEntry(twoDigitValidator) + percentEntry.SetMinCharWidth(2) + percentEntry.OnChanged = func(str string) { + if i, err := strconv.Atoi(str); err == nil { + s.config.Scrobbling.ThresholdPercent = i + } + } + percentEntry.Text = strconv.Itoa(s.config.Scrobbling.ThresholdPercent) + + durationEntry := widgets.NewTextRestrictedEntry(twoDigitValidator) + durationEntry.SetMinCharWidth(2) + durationEntry.OnChanged = func(str string) { + if i, err := strconv.Atoi(str); err == nil { + s.config.Scrobbling.ThresholdTimeSeconds = i * 60 + } + } + if secs := s.config.Scrobbling.ThresholdTimeSeconds; secs >= 0 { + val := int(math.Round(float64(secs) / 60.)) + durationEntry.Text = strconv.Itoa(val) + } + + lastScrobbleText := durationEntry.Text + if lastScrobbleText == "" { + lastScrobbleText = "4" // default scrobble minutes + } + durationEnabled := widget.NewCheck("or when", func(checked bool) { + if !checked { + s.config.Scrobbling.ThresholdTimeSeconds = -1 + lastScrobbleText = durationEntry.Text + durationEntry.Text = "" + durationEntry.Disable() + } else { + durationEntry.Text = lastScrobbleText + durationEntry.Enable() + durationEntry.Refresh() + durationEntry.OnChanged(durationEntry.Text) + } + }) + durationEnabled.Checked = s.config.Scrobbling.ThresholdTimeSeconds >= 0 + + scrobbleEnabled := widget.NewCheckWithData("Send playback statistics to server", binding.BindBool(&s.config.Scrobbling.Enabled)) + scrobbleEnabled.OnChanged = func(checked bool) { + if !checked { + percentEntry.Disable() + durationEnabled.Disable() + durationEntry.Disable() + } else { + percentEntry.Enable() + durationEnabled.Enable() + if durationEnabled.Checked { + durationEntry.Enable() + } + } + } + + return container.NewTabItem("General", container.NewVBox( + widget.NewRichText(&widget.TextSegment{Text: "Scrobbling", Style: boldStyle}), + scrobbleEnabled, + container.NewHBox( + widget.NewLabel("Scrobble when"), + percentEntry, + widget.NewLabel("percent of track is played"), + ), + container.NewHBox( + durationEnabled, + durationEntry, + widget.NewLabel("minutes of track have been played"), + ), + )) +} + +func (s *SettingsDialog) createPlaybackTab() *container.TabItem { + replayGainSelect := widget.NewSelect([]string{"None", "Album", "Track"}, nil) + + return container.NewTabItem("Playback", container.NewVBox( + widget.NewRichText(&widget.TextSegment{Text: "ReplayGain", Style: boldStyle}), + container.New(layout.NewFormLayout(), + widget.NewLabel("ReplayGain mode"), replayGainSelect, + widget.NewLabel("Prevent clipping"), widget.NewCheckWithData("", binding.BindBool(&s.config.ReplayGain.PreventClipping)), + ), + widget.NewSeparator(), + widget.NewCheckWithData("Audio exclusive mode", binding.BindBool(&s.config.LocalPlayback.AudioExclusive)), + )) +} + func (s *SettingsDialog) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(s.content) }