mirror of
https://github.com/yattee/yattee.git
synced 2025-12-07 16:48:15 +00:00
Improve playback settings UI controls on macOS
Standardized picker and button sizing with consistent alignment and control sizes. Added SettingsPickerModifier to all macOS pickers with menu style. Improved rate buttons with proper sizing and alignment. Added text truncation for stream descriptions to prevent overflow.
This commit is contained in:
@@ -64,10 +64,10 @@ struct PlaybackSettings: View {
|
|||||||
.padding(.vertical, 10)
|
.padding(.vertical, 10)
|
||||||
|
|
||||||
if player.activeBackend == .mpv || !player.avPlayerUsesSystemControls {
|
if player.activeBackend == .mpv || !player.avPlayerUsesSystemControls {
|
||||||
HStack {
|
HStack(alignment: .center) {
|
||||||
controlsHeader("Rate".localized())
|
controlsHeader("Rate".localized())
|
||||||
Spacer()
|
Spacer()
|
||||||
HStack(spacing: rateButtonsSpacing) {
|
HStack(alignment: .center, spacing: rateButtonsSpacing) {
|
||||||
decreaseRateButton
|
decreaseRateButton
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
.focused($focusedField, equals: .decreaseRate)
|
.focused($focusedField, equals: .decreaseRate)
|
||||||
@@ -205,8 +205,9 @@ struct PlaybackSettings: View {
|
|||||||
@ViewBuilder private var rateButton: some View {
|
@ViewBuilder private var rateButton: some View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
ratePicker
|
ratePicker
|
||||||
.labelsHidden()
|
.modifier(SettingsPickerModifier())
|
||||||
.frame(maxWidth: 100)
|
.controlSize(.large)
|
||||||
|
.frame(width: 100, alignment: .center)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
Menu {
|
Menu {
|
||||||
ratePicker
|
ratePicker
|
||||||
@@ -241,11 +242,15 @@ struct PlaybackSettings: View {
|
|||||||
player.currentRate = rate
|
player.currentRate = rate
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
|
#if os(macOS)
|
||||||
|
Image(systemName: "plus")
|
||||||
|
.imageScale(.large)
|
||||||
|
.frame(width: 16, height: 16)
|
||||||
|
#else
|
||||||
Label("Increase rate", systemImage: "plus")
|
Label("Increase rate", systemImage: "plus")
|
||||||
.foregroundColor(.accentColor)
|
|
||||||
.imageScale(.large)
|
.imageScale(.large)
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
#if os(iOS)
|
.foregroundColor(.accentColor)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
|
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
|
||||||
@@ -254,6 +259,12 @@ struct PlaybackSettings: View {
|
|||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.buttonStyle(.bordered)
|
.buttonStyle(.bordered)
|
||||||
|
.controlSize(.large)
|
||||||
|
.frame(minWidth: 32, minHeight: 28)
|
||||||
|
.fixedSize()
|
||||||
|
#else
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.controlSize(.large)
|
||||||
#endif
|
#endif
|
||||||
.disabled(increasedRate.isNil)
|
.disabled(increasedRate.isNil)
|
||||||
}
|
}
|
||||||
@@ -266,11 +277,15 @@ struct PlaybackSettings: View {
|
|||||||
player.currentRate = rate
|
player.currentRate = rate
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
|
#if os(macOS)
|
||||||
|
Image(systemName: "minus")
|
||||||
|
.imageScale(.large)
|
||||||
|
.frame(width: 16, height: 16)
|
||||||
|
#else
|
||||||
Label("Decrease rate", systemImage: "minus")
|
Label("Decrease rate", systemImage: "minus")
|
||||||
.foregroundColor(.accentColor)
|
|
||||||
.imageScale(.large)
|
.imageScale(.large)
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
#if os(iOS)
|
.foregroundColor(.accentColor)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
|
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
|
||||||
@@ -279,9 +294,14 @@ struct PlaybackSettings: View {
|
|||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.buttonStyle(.bordered)
|
.buttonStyle(.bordered)
|
||||||
#elseif os(iOS)
|
.controlSize(.large)
|
||||||
|
.frame(minWidth: 32, minHeight: 28)
|
||||||
|
.fixedSize()
|
||||||
|
#else
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.controlSize(.large)
|
||||||
#endif
|
#endif
|
||||||
.disabled(decreasedRate.isNil)
|
.disabled(decreasedRate.isNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var rateButtonsSpacing: Double {
|
private var rateButtonsSpacing: Double {
|
||||||
@@ -304,9 +324,8 @@ struct PlaybackSettings: View {
|
|||||||
#elseif os(macOS)
|
#elseif os(macOS)
|
||||||
playbackModePicker
|
playbackModePicker
|
||||||
.modifier(SettingsPickerModifier())
|
.modifier(SettingsPickerModifier())
|
||||||
#if os(macOS)
|
.controlSize(.large)
|
||||||
.frame(maxWidth: 150)
|
.frame(width: 300, alignment: .trailing)
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
Menu {
|
Menu {
|
||||||
playbackModePicker
|
playbackModePicker
|
||||||
@@ -329,8 +348,9 @@ struct PlaybackSettings: View {
|
|||||||
@ViewBuilder private var qualityProfileButton: some View {
|
@ViewBuilder private var qualityProfileButton: some View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
qualityProfilePicker
|
qualityProfilePicker
|
||||||
.labelsHidden()
|
.modifier(SettingsPickerModifier())
|
||||||
.frame(maxWidth: 300)
|
.controlSize(.large)
|
||||||
|
.frame(width: 300, alignment: .trailing)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
Menu {
|
Menu {
|
||||||
qualityProfilePicker
|
qualityProfilePicker
|
||||||
@@ -378,8 +398,9 @@ struct PlaybackSettings: View {
|
|||||||
@ViewBuilder private var streamButton: some View {
|
@ViewBuilder private var streamButton: some View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
StreamControl()
|
StreamControl()
|
||||||
.labelsHidden()
|
.modifier(SettingsPickerModifier())
|
||||||
.frame(maxWidth: 300)
|
.controlSize(.large)
|
||||||
|
.frame(width: 300, alignment: .trailing)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
Menu {
|
Menu {
|
||||||
StreamControl()
|
StreamControl()
|
||||||
@@ -400,8 +421,9 @@ struct PlaybackSettings: View {
|
|||||||
let videoCaptions = player.currentVideo?.captions
|
let videoCaptions = player.currentVideo?.captions
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
captionsPicker
|
captionsPicker
|
||||||
.labelsHidden()
|
.modifier(SettingsPickerModifier())
|
||||||
.frame(maxWidth: 300)
|
.controlSize(.large)
|
||||||
|
.frame(width: 300, alignment: .trailing)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
Menu {
|
Menu {
|
||||||
if videoCaptions?.isEmpty == false {
|
if videoCaptions?.isEmpty == false {
|
||||||
@@ -470,8 +492,9 @@ struct PlaybackSettings: View {
|
|||||||
@ViewBuilder private var audioTrackButton: some View {
|
@ViewBuilder private var audioTrackButton: some View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
audioTrackPicker
|
audioTrackPicker
|
||||||
.labelsHidden()
|
.modifier(SettingsPickerModifier())
|
||||||
.frame(maxWidth: 300)
|
.controlSize(.large)
|
||||||
|
.frame(width: 300, alignment: .trailing)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
Menu {
|
Menu {
|
||||||
audioTrackPicker
|
audioTrackPicker
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ struct StreamControl: View {
|
|||||||
|
|
||||||
ForEach(kinds, id: \.self) { key in
|
ForEach(kinds, id: \.self) { key in
|
||||||
ForEach(availableStreamsByKind[key] ?? []) { stream in
|
ForEach(availableStreamsByKind[key] ?? []) { stream in
|
||||||
Text(stream.description).tag(Stream?.some(stream))
|
Text(stream.description)
|
||||||
|
#if os(macOS)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.middle)
|
||||||
|
#endif
|
||||||
|
.tag(Stream?.some(stream))
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
@@ -36,6 +41,8 @@ struct StreamControl: View {
|
|||||||
.frame(minWidth: 110)
|
.frame(minWidth: 110)
|
||||||
.fixedSize(horizontal: true, vertical: true)
|
.fixedSize(horizontal: true, vertical: true)
|
||||||
.disabled(player.isLoadingAvailableStreams)
|
.disabled(player.isLoadingAvailableStreams)
|
||||||
|
#elseif os(macOS)
|
||||||
|
.fixedSize()
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
ControlsOverlayButton(focusedField: focusedField!, field: .stream) {
|
ControlsOverlayButton(focusedField: focusedField!, field: .stream) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct SettingsPickerModifier: ViewModifier {
|
|||||||
#else
|
#else
|
||||||
content
|
content
|
||||||
.labelsHidden()
|
.labelsHidden()
|
||||||
|
.pickerStyle(.menu)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user