mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
a little upgrade of the settings view
This commit is contained in:
parent
e3a6b6167b
commit
cdc973a45b
3 changed files with 104 additions and 25 deletions
|
|
@ -10497,10 +10497,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Left button" : {
|
|
||||||
"comment" : "A label for a picker that lets the user select a control for the left button on a media player.",
|
|
||||||
"isCommentAutoGenerated" : true
|
|
||||||
},
|
|
||||||
"License key" : {
|
"License key" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"fr" : {
|
"fr" : {
|
||||||
|
|
@ -15582,10 +15578,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Right button" : {
|
|
||||||
"comment" : "A label for the right button in the media controls picker.",
|
|
||||||
"isCommentAutoGenerated" : true
|
|
||||||
},
|
|
||||||
"Rotation:" : {
|
"Rotation:" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"fr" : {
|
"fr" : {
|
||||||
|
|
|
||||||
|
|
@ -904,16 +904,7 @@ struct Media: View {
|
||||||
}
|
}
|
||||||
.disabled(!showShuffleAndRepeat)
|
.disabled(!showShuffleAndRepeat)
|
||||||
if showShuffleAndRepeat {
|
if showShuffleAndRepeat {
|
||||||
Picker("Left button", selection: $musicAuxLeftControl) {
|
mediaControlsGrid
|
||||||
ForEach(MusicAuxiliaryControl.allCases) { control in
|
|
||||||
Text(control.displayName).tag(control)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Picker("Right button", selection: $musicAuxRightControl) {
|
|
||||||
ForEach(MusicAuxiliaryControl.allCases) { control in
|
|
||||||
Text(control.displayName).tag(control)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
Text("Media controls")
|
Text("Media controls")
|
||||||
|
|
@ -1010,6 +1001,102 @@ struct Media: View {
|
||||||
.navigationTitle("Media")
|
.navigationTitle("Media")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var mediaControlsGrid: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 20) {
|
||||||
|
mediaControlsRow(title: "Left button", selection: $musicAuxLeftControl, otherSelection: musicAuxRightControl)
|
||||||
|
mediaControlsRow(title: "Right button", selection: $musicAuxRightControl, otherSelection: musicAuxLeftControl)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func mediaControlsRow(title: String, selection: Binding<MusicAuxiliaryControl>, otherSelection: MusicAuxiliaryControl) -> some View {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
Text(title)
|
||||||
|
.font(.system(size: 13, weight: .semibold))
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
|
||||||
|
HStack(spacing: 16) {
|
||||||
|
ForEach([MusicAuxiliaryControl.mediaOutput, MusicAuxiliaryControl.repeatMode, MusicAuxiliaryControl.lyrics, MusicAuxiliaryControl.shuffle], id: \.self) { control in
|
||||||
|
MediaControlButton(
|
||||||
|
control: control,
|
||||||
|
isSelected: selection.wrappedValue == control,
|
||||||
|
disabled: control == otherSelection
|
||||||
|
) {
|
||||||
|
selection.wrappedValue = control
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MediaControlButton: View {
|
||||||
|
let control: MusicAuxiliaryControl
|
||||||
|
let isSelected: Bool
|
||||||
|
let disabled: Bool
|
||||||
|
let action: () -> Void
|
||||||
|
|
||||||
|
@State private var isHovering = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
ZStack {
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.fill(backgroundColor)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.strokeBorder(borderColor, lineWidth: isSelected ? 2 : 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
Image(systemName: control.symbolName)
|
||||||
|
.font(.system(size: 22, weight: .medium))
|
||||||
|
.foregroundStyle(iconColor)
|
||||||
|
}
|
||||||
|
.frame(width: 80, height: 60)
|
||||||
|
.onHover { hovering in
|
||||||
|
if !disabled {
|
||||||
|
withAnimation(.easeInOut(duration: 0.2)) {
|
||||||
|
isHovering = hovering
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(control.displayName)
|
||||||
|
.font(.caption)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.lineLimit(2)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.frame(width: 100)
|
||||||
|
.foregroundStyle(disabled ? .secondary : .primary)
|
||||||
|
}
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.onTapGesture {
|
||||||
|
if !disabled {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.opacity(disabled ? 0.5 : 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var backgroundColor: Color {
|
||||||
|
if disabled { return Color(nsColor: .controlBackgroundColor) }
|
||||||
|
if isSelected { return Color.accentColor.opacity(0.1) }
|
||||||
|
if isHovering { return Color.primary.opacity(0.05) }
|
||||||
|
return Color(nsColor: .controlBackgroundColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var borderColor: Color {
|
||||||
|
if isSelected { return Color.accentColor }
|
||||||
|
if isHovering { return Color.primary.opacity(0.1) }
|
||||||
|
return Color.clear
|
||||||
|
}
|
||||||
|
|
||||||
|
private var iconColor: Color {
|
||||||
|
if disabled { return .secondary }
|
||||||
|
if isSelected { return .accentColor }
|
||||||
|
return .primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only show controller options that are available on this macOS version
|
// Only show controller options that are available on this macOS version
|
||||||
private var availableMediaControllers: [MediaControllerType] {
|
private var availableMediaControllers: [MediaControllerType] {
|
||||||
if MusicManager.shared.isNowPlayingDeprecated {
|
if MusicManager.shared.isNowPlayingDeprecated {
|
||||||
|
|
@ -2106,34 +2193,34 @@ struct TimerSettings: View {
|
||||||
let nextIndex = timerPresets.count + 1
|
let nextIndex = timerPresets.count + 1
|
||||||
let defaultColor = Defaults[.accentColor]
|
let defaultColor = Defaults[.accentColor]
|
||||||
let newPreset = TimerPreset(name: "Preset \(nextIndex)", duration: 5 * 60, color: defaultColor)
|
let newPreset = TimerPreset(name: "Preset \(nextIndex)", duration: 5 * 60, color: defaultColor)
|
||||||
_ = withAnimation(.smooth) {
|
withAnimation(.smooth) {
|
||||||
timerPresets.append(newPreset)
|
timerPresets.append(newPreset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func movePresetUp(_ index: Int) {
|
private func movePresetUp(_ index: Int) {
|
||||||
guard index > timerPresets.startIndex else { return }
|
guard index > timerPresets.startIndex else { return }
|
||||||
_ = withAnimation(.smooth) {
|
withAnimation(.smooth) {
|
||||||
timerPresets.swapAt(index, index - 1)
|
timerPresets.swapAt(index, index - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func movePresetDown(_ index: Int) {
|
private func movePresetDown(_ index: Int) {
|
||||||
guard index < timerPresets.index(before: timerPresets.endIndex) else { return }
|
guard index < timerPresets.index(before: timerPresets.endIndex) else { return }
|
||||||
_ = withAnimation(.smooth) {
|
withAnimation(.smooth) {
|
||||||
timerPresets.swapAt(index, index + 1)
|
timerPresets.swapAt(index, index + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func removePreset(_ index: Int) {
|
private func removePreset(_ index: Int) {
|
||||||
guard timerPresets.indices.contains(index) else { return }
|
guard timerPresets.indices.contains(index) else { return }
|
||||||
_ = withAnimation(.smooth) {
|
withAnimation(.smooth) {
|
||||||
timerPresets.remove(at: index)
|
timerPresets.remove(at: index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func resetPresets() {
|
private func resetPresets() {
|
||||||
_ = withAnimation(.smooth) {
|
withAnimation(.smooth) {
|
||||||
timerPresets = TimerPreset.defaultPresets
|
timerPresets = TimerPreset.defaultPresets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2386,7 +2473,7 @@ struct StatsSettings: View {
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
Defaults.Toggle("CPU Usage", key: .showCpuGraph)
|
Defaults.Toggle("CPU Usage", key: .showCpuGraph)
|
||||||
Defaults.Toggle("Memory Usage", key: .showMemoryGraph)
|
Defaults.Toggle("Memory Usage", key: .showMemoryGraph)
|
||||||
Defaults.Toggle("GPU Usage", key: .showGpuGraph)
|
Defaults.Toggle("GPU Usage", key: .showGpuGraph)
|
||||||
Defaults.Toggle("Network Activity", key: .showNetworkGraph)
|
Defaults.Toggle("Network Activity", key: .showNetworkGraph)
|
||||||
Defaults.Toggle("Disk I/O", key: .showDiskGraph)
|
Defaults.Toggle("Disk I/O", key: .showDiskGraph)
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ enum MusicAuxiliaryControl: String, CaseIterable, Identifiable, Defaults.Seriali
|
||||||
case .repeatMode:
|
case .repeatMode:
|
||||||
return "repeat"
|
return "repeat"
|
||||||
case .mediaOutput:
|
case .mediaOutput:
|
||||||
return "speaker.wave.2"
|
return "laptopcomputer"
|
||||||
case .lyrics:
|
case .lyrics:
|
||||||
return "quote.bubble"
|
return "quote.bubble"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue