From 2c3b3cdd558af0d49e9d94905bcb80f4020e2820 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Thu, 13 Aug 2026 23:34:47 +0200 Subject: [PATCH] =?UTF-8?q?Einstellungen:=20die=20Linie=20unter=20den=20Re?= =?UTF-8?q?itern=20ist=20weg,=20und=20eine=20Fl=C3=A4che=20f=C3=BCr=20alle?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Linie kam von `TabView` selbst: es zieht unter seiner Leiste einen Trenner quer durchs Fenster, und der lässt sich nicht abschalten. Der Abstand nach oben, den ich beim letzten Mal eingebaut habe, hat deshalb nichts geändert — der Trenner ist mitgewandert. Jetzt ist die Reiterleiste selbst gebaut, ein Auswahlfeld über dem Inhalt, dann gibt es die Linie gar nicht erst. Der zweite Punkt hat dieselbe Wurzel: die Formulare bringen ihren eigenen Untergrund mit, der Rest des Fensters hat den des Systems. In Dunkelgrau liegen die beiden ein, zwei Prozent auseinander — sichtbar als Kante quer durchs Fenster, genau dort, wo das Formular anfängt. Der Untergrund der Formulare ist jetzt abgeschaltet, und das ganze Fenster hat einen. Co-Authored-By: Claude Opus 5 --- Onyx/ColorSettingsView.swift | 3 ++ Onyx/FanSettingsView.swift | 3 ++ Onyx/SettingsView.swift | 97 +++++++++++++++++++++++++----------- Onyx/WidgetOptionsView.swift | 3 ++ 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/Onyx/ColorSettingsView.swift b/Onyx/ColorSettingsView.swift index 4e49c01..eddefaf 100644 --- a/Onyx/ColorSettingsView.swift +++ b/Onyx/ColorSettingsView.swift @@ -88,6 +88,9 @@ struct ColorSettingsView: View { } } .formStyle(.grouped) + // Der eigene Untergrund des Formulars weicht ein, zwei Prozent von dem + // des Fensters ab. In Dunkelgrau sieht man genau das als Kante. + .scrollContentBackground(.hidden) } } diff --git a/Onyx/FanSettingsView.swift b/Onyx/FanSettingsView.swift index 49e1f32..e6a94cc 100644 --- a/Onyx/FanSettingsView.swift +++ b/Onyx/FanSettingsView.swift @@ -29,6 +29,9 @@ struct FanSettingsView: View { } } .formStyle(.grouped) + // Der eigene Untergrund des Formulars weicht ein, zwei Prozent von dem + // des Fensters ab. In Dunkelgrau sieht man genau das als Kante. + .scrollContentBackground(.hidden) .padding() .onAppear { control.refreshInstallState() diff --git a/Onyx/SettingsView.swift b/Onyx/SettingsView.swift index d73230f..9de829d 100644 --- a/Onyx/SettingsView.swift +++ b/Onyx/SettingsView.swift @@ -24,42 +24,73 @@ struct SettingsView: View { let showOnboarding: () -> Void @Binding var selectedTab: SettingsTab + /// Die Reiter in der Reihenfolge, in der sie oben stehen. + private static let tabs: [(tab: SettingsTab, label: LocalizedStringKey)] = [ + (.widgets, "settings.tab.widgets"), + (.display, "settings.tab.display"), + (.colors, "settings.tab.colors"), + (.sources, "settings.tab.options"), + (.menubar, "settings.tab.menubar"), + (.fans, "settings.tab.fans"), + (.permissions, "settings.tab.permissions"), + ] + var body: some View { - TabView(selection: $selectedTab) { - WidgetSettings(model: model, shelfStore: shelfStore) - .tabItem { Label("settings.tab.widgets", systemImage: "square.grid.2x2") } - .tag(SettingsTab.widgets) - DisplaySettings(model: model) - .tabItem { Label("settings.tab.display", systemImage: "macbook") } - .tag(SettingsTab.display) - ColorSettingsView(theme: OnyxTheme.shared) - .tabItem { Label("settings.tab.colors", systemImage: "paintpalette") } - .tag(SettingsTab.colors) - WidgetOptionsView(calendarModel: calendarModel, weatherModel: weatherModel, - shelfStore: shelfStore) - .tabItem { Label("settings.tab.options", systemImage: "slider.horizontal.3") } - .tag(SettingsTab.sources) - MenuBarSettings(model: model, metricsModel: metricsModel) - .tabItem { Label("settings.tab.menubar", systemImage: "menubar.rectangle") } - .tag(SettingsTab.menubar) - FanSettingsView(control: fanControl) - .tabItem { Label("settings.tab.fans", systemImage: "fan") } - .tag(SettingsTab.fans) - PermissionSettings(calendarModel: calendarModel, weatherModel: weatherModel, - launchAtLogin: launchAtLogin, showOnboarding: showOnboarding) - .tabItem { Label("settings.tab.permissions", systemImage: "hand.raised") } - .tag(SettingsTab.permissions) + // Eigene Reiterleiste statt `TabView`. + // + // `TabView` zieht unter seiner Leiste einen Trenner quer durchs + // Fenster — nicht abschaltbar, und die Leiste sitzt mittig darauf. + // Abstand nach oben half nicht: der Trenner wandert mit. Also die + // Leiste selbst gebaut, dann gibt es die Linie gar nicht erst. + VStack(spacing: 0) { + Picker("", selection: $selectedTab) { + ForEach(Self.tabs, id: \.tab) { entry in + Text(entry.label).tag(entry.tab) + } + } + .pickerStyle(.segmented) + .labelsHidden() + // Nur so breit wie nötig und mittig: über die volle Fensterbreite + // gezogen sähen sieben Reiter aus wie eine Werkzeugleiste. + .fixedSize() + .padding(.top, 10) + .padding(.bottom, 14) + + content } - // Abstand nach oben: ohne ihn sitzt die Reiterleiste genau auf der - // Trennlinie unter dem Titelbalken und sieht aus, als läge sie auf - // einer Kante. `TabView` in einem gewöhnlichen Fenster bekommt diesen - // Abstand nicht von selbst — in Apples `Settings`-Szene schon, und die - // benutzt Onyx bewusst nicht. - .padding(.top, 12) + // Eine Fläche für alles. + // + // Vorher hatte jeder Bereich seinen eigenen Untergrund: die + // Formulare bringen einen mit, der Rest des Fensters hat den des + // Systems, und die beiden liegen in Dunkelgrau ein, zwei Prozent + // auseinander. Sichtbar wurde das als Kante quer durchs Fenster. + .background(Color(nsColor: .windowBackgroundColor)) // Nur ein Mindestmaß, keine feste Größe: sonst kann das Fenster // wachsen, der Inhalt aber nicht mit. .frame(minWidth: 740, minHeight: 460) } + + @ViewBuilder + private var content: some View { + switch selectedTab { + case .widgets: + WidgetSettings(model: model, shelfStore: shelfStore) + case .display: + DisplaySettings(model: model) + case .colors: + ColorSettingsView(theme: OnyxTheme.shared) + case .sources: + WidgetOptionsView(calendarModel: calendarModel, weatherModel: weatherModel, + shelfStore: shelfStore) + case .menubar: + MenuBarSettings(model: model, metricsModel: metricsModel) + case .fans: + FanSettingsView(control: fanControl) + case .permissions: + PermissionSettings(calendarModel: calendarModel, weatherModel: weatherModel, + launchAtLogin: launchAtLogin, showOnboarding: showOnboarding) + } + } } // MARK: - Berechtigungen @@ -141,6 +172,9 @@ private struct PermissionSettings: View { } } .formStyle(.grouped) + // Der eigene Untergrund des Formulars weicht ein, zwei Prozent von dem + // des Fensters ab. In Dunkelgrau sieht man genau das als Kante. + .scrollContentBackground(.hidden) .padding() .task { launchAtLogin.refresh() @@ -517,6 +551,9 @@ private struct DisplaySettings: View { .fixedSize(horizontal: false, vertical: true) } .formStyle(.grouped) + // Der eigene Untergrund des Formulars weicht ein, zwei Prozent von dem + // des Fensters ab. In Dunkelgrau sieht man genau das als Kante. + .scrollContentBackground(.hidden) .padding() } } diff --git a/Onyx/WidgetOptionsView.swift b/Onyx/WidgetOptionsView.swift index 2ced4dc..9116f7c 100644 --- a/Onyx/WidgetOptionsView.swift +++ b/Onyx/WidgetOptionsView.swift @@ -33,6 +33,9 @@ struct WidgetOptionsView: View { } } .formStyle(.grouped) + // Der eigene Untergrund des Formulars weicht ein, zwei Prozent von dem + // des Fensters ab. In Dunkelgrau sieht man genau das als Kante. + .scrollContentBackground(.hidden) .padding() } }