Skip to content

Commit 8927187

Browse files
committed
changing AppKits ProgressSpinner size through replacing it with a spinner sized pre view graph insertion
Doesn't seem to be a performance issue, but its not a nice way. Sadly nothing else I tried works.
1 parent b615c3c commit 8927187

File tree

4 files changed

+109
-58
lines changed

4 files changed

+109
-58
lines changed

Examples/Sources/ControlsExample/ControlsApp.swift

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -22,73 +22,79 @@ struct ControlsApp: App {
2222
var body: some Scene {
2323
WindowGroup("ControlsApp") {
2424
#hotReloadable {
25-
VStack(spacing: 30) {
26-
VStack {
27-
Text("Button")
28-
Button("Click me!") {
29-
count += 1
30-
}
31-
Text("Count: \(count)")
32-
}
33-
.padding(.bottom, 20)
34-
35-
#if !canImport(UIKitBackend)
25+
ScrollView {
26+
VStack(spacing: 30) {
3627
VStack {
37-
Text("Toggle button")
38-
Toggle("Toggle me!", active: $exampleButtonState)
39-
.toggleStyle(.button)
40-
Text("Currently enabled: \(exampleButtonState)")
28+
Text("Button")
29+
Button("Click me!") {
30+
count += 1
31+
}
32+
Text("Count: \(count)")
4133
}
4234
.padding(.bottom, 20)
43-
#endif
4435

45-
VStack {
46-
Text("Toggle switch")
47-
Toggle("Toggle me:", active: $exampleSwitchState)
48-
.toggleStyle(.switch)
49-
Text("Currently enabled: \(exampleSwitchState)")
50-
}
36+
#if !canImport(UIKitBackend)
37+
VStack {
38+
Text("Toggle button")
39+
Toggle("Toggle me!", active: $exampleButtonState)
40+
.toggleStyle(.button)
41+
Text("Currently enabled: \(exampleButtonState)")
42+
}
43+
.padding(.bottom, 20)
44+
#endif
5145

52-
#if !canImport(UIKitBackend)
5346
VStack {
54-
Text("Checkbox")
55-
Toggle("Toggle me:", active: $exampleCheckboxState)
56-
.toggleStyle(.checkbox)
57-
Text("Currently enabled: \(exampleCheckboxState)")
47+
Text("Toggle switch")
48+
Toggle("Toggle me:", active: $exampleSwitchState)
49+
.toggleStyle(.switch)
50+
Text("Currently enabled: \(exampleSwitchState)")
5851
}
59-
#endif
6052

61-
VStack {
62-
Text("Slider")
63-
Slider($sliderValue, minimum: 0, maximum: 10)
64-
.frame(maxWidth: 200)
65-
Text("Value: \(String(format: "%.02f", sliderValue))")
66-
}
53+
#if !canImport(UIKitBackend)
54+
VStack {
55+
Text("Checkbox")
56+
Toggle("Toggle me:", active: $exampleCheckboxState)
57+
.toggleStyle(.checkbox)
58+
Text("Currently enabled: \(exampleCheckboxState)")
59+
}
60+
#endif
6761

68-
VStack {
69-
Text("Text field")
70-
TextField("Text field", text: $text)
71-
Text("Value: \(text)")
72-
}
62+
VStack {
63+
Text("Slider")
64+
Slider($sliderValue, minimum: 0, maximum: 10)
65+
.frame(maxWidth: 200)
66+
Text("Value: \(String(format: "%.02f", sliderValue))")
67+
}
7368

74-
Toggle("Enable ProgressView resizability", active: $isProgressViewResizable)
75-
Slider($progressViewSize, minimum: 10, maximum: 100)
76-
ProgressView()
77-
.resizable(isProgressViewResizable)
78-
.frame(width: progressViewSize, height: progressViewSize)
69+
VStack {
70+
Text("Text field")
71+
TextField("Text field", text: $text)
72+
Text("Value: \(text)")
73+
}
74+
75+
Toggle("Enable ProgressView resizability", active: $isProgressViewResizable)
76+
Slider($progressViewSize, minimum: 10, maximum: 100)
77+
Button("Randomize progress view size") {
78+
progressViewSize = Int.random(in: 10...100)
79+
}
80+
ProgressView()
81+
.resizable(isProgressViewResizable)
82+
.frame(width: progressViewSize, height: progressViewSize)
7983

80-
VStack {
81-
Text("Drop down")
82-
HStack {
83-
Text("Flavor: ")
84-
Picker(of: ["Vanilla", "Chocolate", "Strawberry"], selection: $flavor)
84+
VStack {
85+
Text("Drop down")
86+
HStack {
87+
Text("Flavor: ")
88+
Picker(
89+
of: ["Vanilla", "Chocolate", "Strawberry"], selection: $flavor)
90+
}
91+
Text("You chose: \(flavor ?? "Nothing yet!")")
8592
}
86-
Text("You chose: \(flavor ?? "Nothing yet!")")
87-
}
88-
}.padding().disabled(!enabled)
93+
}.padding().disabled(!enabled)
8994

90-
Toggle(enabled ? "Disable all" : "Enable all", active: $enabled)
91-
.padding()
95+
Toggle(enabled ? "Disable all" : "Enable all", active: $enabled)
96+
.padding()
97+
}
9298
}
9399
}.defaultSize(width: 400, height: 600)
94100
}

Sources/AppKitBackend/AppKitBackend.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,15 @@ public final class AppKitBackend: AppBackend {
484484
}
485485

486486
public func naturalSize(of widget: Widget) -> SIMD2<Int> {
487+
if let spinner = widget.subviews.first as? NSProgressIndicator,
488+
spinner.style == .spinning
489+
{
490+
let size = spinner.intrinsicContentSize
491+
return SIMD2(
492+
Int(size.width),
493+
Int(size.height)
494+
)
495+
}
487496
let size = widget.intrinsicContentSize
488497
return SIMD2(
489498
Int(size.width),
@@ -1181,11 +1190,31 @@ public final class AppKitBackend: AppBackend {
11811190
}
11821191

11831192
public func createProgressSpinner() -> Widget {
1193+
let container = NSView()
1194+
let spinner = NSProgressIndicator()
1195+
spinner.translatesAutoresizingMaskIntoConstraints = false
1196+
spinner.isIndeterminate = true
1197+
spinner.style = .spinning
1198+
spinner.startAnimation(nil)
1199+
container.addSubview(spinner)
1200+
return container
1201+
}
1202+
1203+
public func setProgressSpinnerSize(
1204+
_ widget: Widget,
1205+
_ size: SIMD2<Int>
1206+
) {
1207+
setSize(of: widget, to: size)
11841208
let spinner = NSProgressIndicator()
1209+
spinner.translatesAutoresizingMaskIntoConstraints = false
11851210
spinner.isIndeterminate = true
11861211
spinner.style = .spinning
11871212
spinner.startAnimation(nil)
1188-
return spinner
1213+
spinner.widthAnchor.constraint(equalToConstant: CGFloat(size.x)).isActive = true
1214+
spinner.heightAnchor.constraint(equalToConstant: CGFloat(size.y)).isActive = true
1215+
1216+
widget.subviews = []
1217+
widget.addSubview(spinner)
11891218
}
11901219

11911220
public func createProgressBar() -> Widget {

Sources/SwiftCrossUI/Backend/AppBackend.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,15 @@ public protocol AppBackend: Sendable {
541541
/// Creates an indeterminate progress spinner.
542542
func createProgressSpinner() -> Widget
543543

544+
/// Changes the Spinner's Size.
545+
/// Required due to AppKitBackend needing special treatment.
546+
/// Forward to ``AppBackend/setSize(of widget: Widget, to size: SIMD2<Int>)``
547+
/// on other Backends.
548+
func setProgressSpinnerSize(
549+
_ widget: Widget,
550+
_ size: SIMD2<Int>
551+
)
552+
544553
/// Creates a progress bar.
545554
func createProgressBar() -> Widget
546555
/// Updates a progress bar to reflect the given progress (between 0 and 1), and the
@@ -1028,6 +1037,13 @@ extension AppBackend {
10281037
todo()
10291038
}
10301039

1040+
public func setProgressSpinnerSize(
1041+
_ widget: Widget,
1042+
_ size: SIMD2<Int>
1043+
) {
1044+
setSize(of: widget, to: size)
1045+
}
1046+
10311047
public func createProgressBar() -> Widget {
10321048
todo()
10331049
}

Sources/SwiftCrossUI/Views/ProgressView.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@ struct ProgressSpinnerView: ElementaryView {
131131
guard isResizable else {
132132
// Required to reset its size when resizability
133133
// gets changed at runtime
134-
backend.setSize(of: widget, to: naturalSize)
134+
backend.setProgressSpinnerSize(widget, naturalSize)
135135
return ViewUpdateResult.leafView(size: ViewSize(fixedSize: naturalSize))
136136
}
137-
let minimumDimension = max(min(proposedSize.x, proposedSize.y), 10)
137+
let minimumDimension = max(min(proposedSize.x, proposedSize.y), 0)
138138
let size = SIMD2(
139139
minimumDimension,
140140
minimumDimension
@@ -143,7 +143,7 @@ struct ProgressSpinnerView: ElementaryView {
143143
// Doesn't change the rendered size of ProgressSpinner
144144
// on UIKitBackend, but still sets container size to
145145
// (width: n, height: n) n = min(proposedSize.x, proposedSize.y)
146-
backend.setSize(of: widget, to: size)
146+
backend.setProgressSpinnerSize(widget, size)
147147
}
148148
return ViewUpdateResult.leafView(
149149
size: ViewSize(

0 commit comments

Comments
 (0)