Skip to content

Commit 40e6384

Browse files
committed
Refactoring
1 parent d123465 commit 40e6384

File tree

3 files changed

+130
-44
lines changed

3 files changed

+130
-44
lines changed

Ice/MenuBar/Appearance/MenuBarAppearanceEditor/MenuBarAppearanceEditor.swift

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -63,30 +63,10 @@ struct MenuBarAppearanceEditor: View {
6363
isDynamicToggle
6464
}
6565
if appearanceManager.configuration.isDynamic {
66-
VStack(alignment: .leading) {
67-
HStack {
68-
Text("Light Appearance")
69-
.font(.headline)
70-
if case .dark = SystemAppearance.current {
71-
PreviewButton(configuration: appearanceManager.configuration.lightModeConfiguration)
72-
}
73-
}
74-
.frame(height: 16)
75-
MenuBarPartialAppearanceEditor(configuration: appearanceManager.bindings.configuration.lightModeConfiguration)
76-
}
77-
VStack(alignment: .leading) {
78-
HStack {
79-
Text("Dark Appearance")
80-
.font(.headline)
81-
if case .light = SystemAppearance.current {
82-
PreviewButton(configuration: appearanceManager.configuration.darkModeConfiguration)
83-
}
84-
}
85-
.frame(height: 16)
86-
MenuBarPartialAppearanceEditor(configuration: appearanceManager.bindings.configuration.darkModeConfiguration)
87-
}
66+
LabeledPartialEditor(appearance: .light)
67+
LabeledPartialEditor(appearance: .dark)
8868
} else {
89-
MenuBarPartialAppearanceEditor(configuration: appearanceManager.bindings.configuration.staticConfiguration)
69+
StaticPartialEditor()
9070
}
9171
IceSection("Menu Bar Shape") {
9272
shapePicker
@@ -149,7 +129,7 @@ struct MenuBarAppearanceEditor: View {
149129
}
150130
}
151131

152-
private struct MenuBarPartialAppearanceEditor: View {
132+
private struct UnlabeledPartialEditor: View {
153133
@Binding var configuration: MenuBarAppearancePartialConfiguration
154134

155135
var body: some View {
@@ -235,7 +215,85 @@ private struct MenuBarPartialAppearanceEditor: View {
235215
}
236216
}
237217

218+
private struct LabeledPartialEditor: View {
219+
@EnvironmentObject var appearanceManager: MenuBarAppearanceManager
220+
@State private var currentAppearance = SystemAppearance.current
221+
@State private var textFrame = CGRect.zero
222+
223+
let appearance: SystemAppearance
224+
225+
var body: some View {
226+
IceSection {
227+
labelStack
228+
} content: {
229+
partialEditor
230+
}
231+
.bordered(false)
232+
.dividers(false)
233+
.onReceive(NSApp.publisher(for: \.effectiveAppearance)) { _ in
234+
currentAppearance = .current
235+
}
236+
}
237+
238+
@ViewBuilder
239+
private var labelStack: some View {
240+
HStack {
241+
Text(appearance.titleKey)
242+
.font(.headline)
243+
.onFrameChange(update: $textFrame)
244+
245+
if currentAppearance != appearance {
246+
previewButton
247+
}
248+
}
249+
.frame(height: textFrame.height)
250+
}
251+
252+
@ViewBuilder
253+
private var previewButton: some View {
254+
switch appearance {
255+
case .light:
256+
PreviewButton(configuration: appearanceManager.configuration.lightModeConfiguration)
257+
case .dark:
258+
PreviewButton(configuration: appearanceManager.configuration.darkModeConfiguration)
259+
}
260+
}
261+
262+
@ViewBuilder
263+
private var partialEditor: some View {
264+
switch appearance {
265+
case .light:
266+
UnlabeledPartialEditor(configuration: appearanceManager.bindings.configuration.lightModeConfiguration)
267+
case .dark:
268+
UnlabeledPartialEditor(configuration: appearanceManager.bindings.configuration.darkModeConfiguration)
269+
}
270+
}
271+
}
272+
273+
private struct StaticPartialEditor: View {
274+
@EnvironmentObject var appearanceManager: MenuBarAppearanceManager
275+
276+
var body: some View {
277+
UnlabeledPartialEditor(configuration: appearanceManager.bindings.configuration.staticConfiguration)
278+
}
279+
}
280+
238281
private struct PreviewButton: View {
282+
private struct DummyButton: NSViewRepresentable {
283+
@Binding var isPressed: Bool
284+
285+
func makeNSView(context: Context) -> NSButton {
286+
let button = NSButton()
287+
button.title = ""
288+
button.bezelStyle = .accessoryBarAction
289+
return button
290+
}
291+
292+
func updateNSView(_ nsView: NSButton, context: Context) {
293+
nsView.isHighlighted = isPressed
294+
}
295+
}
296+
239297
@EnvironmentObject var appearanceManager: MenuBarAppearanceManager
240298

241299
@State private var frame = CGRect.zero
@@ -268,17 +326,3 @@ private struct PreviewButton: View {
268326
.onFrameChange(update: $frame)
269327
}
270328
}
271-
272-
private struct DummyButton: NSViewRepresentable {
273-
@Binding var isPressed: Bool
274-
275-
func makeNSView(context: Context) -> NSButton {
276-
let button = NSButton()
277-
button.title = ""
278-
return button
279-
}
280-
281-
func updateNSView(_ nsView: NSButton, context: Context) {
282-
nsView.isHighlighted = isPressed
283-
}
284-
}

Ice/UI/IceUI/IceSection.swift

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ struct IceSection<Header: View, Content: View, Footer: View>: View {
1010
private let content: Content
1111
private let footer: Footer
1212
private let spacing: CGFloat = 10
13+
private var isBordered = true
14+
private var hasDividers = true
1315

1416
init(
1517
@ViewBuilder header: () -> Header,
@@ -72,15 +74,47 @@ struct IceSection<Header: View, Content: View, Footer: View>: View {
7274
}
7375

7476
var body: some View {
75-
IceGroupBox(padding: spacing) {
76-
header
77-
} content: {
77+
if isBordered {
78+
IceGroupBox(padding: spacing) {
79+
header
80+
} content: {
81+
dividedContent
82+
} footer: {
83+
footer
84+
}
85+
} else {
86+
VStack(alignment: .leading) {
87+
header
88+
dividedContent
89+
footer
90+
}
91+
}
92+
}
93+
94+
@ViewBuilder
95+
private var dividedContent: some View {
96+
if hasDividers {
7897
_VariadicView.Tree(IceSectionLayout(spacing: spacing)) {
7998
content
8099
.frame(maxWidth: .infinity)
81100
}
82-
} footer: {
83-
footer
101+
} else {
102+
content
103+
.frame(maxWidth: .infinity)
104+
}
105+
}
106+
}
107+
108+
extension IceSection {
109+
func bordered(_ isBordered: Bool = true) -> IceSection {
110+
with(self) { copy in
111+
copy.isBordered = isBordered
112+
}
113+
}
114+
115+
func dividers(_ hasDividers: Bool = true) -> IceSection {
116+
with(self) { copy in
117+
copy.hasDividers = hasDividers
84118
}
85119
}
86120
}

Ice/Utilities/SystemAppearance.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Ice
44
//
55

6-
import Cocoa
6+
import SwiftUI
77

88
/// A value corresponding to a light or dark appearance.
99
enum SystemAppearance {
@@ -72,4 +72,12 @@ enum SystemAppearance {
7272
static var current: SystemAppearance {
7373
systemAppearance(for: NSApp.effectiveAppearance)
7474
}
75+
76+
/// The title key to display in the interface.
77+
var titleKey: LocalizedStringKey {
78+
switch self {
79+
case .light: "Light Appearance"
80+
case .dark: "Dark Appearance"
81+
}
82+
}
7583
}

0 commit comments

Comments
 (0)