Skip to content

Commit 9961828

Browse files
committed
Implement WinUIBackend Toggle support
1 parent 9e58521 commit 9961828

File tree

1 file changed

+76
-45
lines changed

1 file changed

+76
-45
lines changed

Sources/WinUIBackend/WinUIBackend.swift

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ extension App {
1919
}
2020

2121
class WinUIApplication: SwiftApplication {
22-
static var callback: (() -> Void)?
22+
static var callback: ((WinUIApplication) -> Void)?
2323

2424
override func onLaunched(_ args: WinUI.LaunchActivatedEventArgs) {
25-
Self.callback?()
25+
Self.callback?(self)
2626
}
2727
}
2828

@@ -57,7 +57,12 @@ public struct WinUIBackend: AppBackend {
5757
}
5858

5959
public func runMainLoop(_ callback: @escaping () -> Void) {
60-
WinUIApplication.callback = {
60+
WinUIApplication.callback = { application in
61+
// Toggle Switch has annoying default 'internal margins' (not Control
62+
// margins that we can set directly) that we can luckily get rid of by
63+
// overriding the relevant resource values.
64+
application.resources.insert("ToggleSwitchPreContentMargin", 0.0 as Double)
65+
application.resources.insert("ToggleSwitchPostContentMargin", 0.0 as Double)
6166
callback()
6267
}
6368
WinUIApplication.main()
@@ -181,7 +186,9 @@ public struct WinUIBackend: AppBackend {
181186
public func computeRootEnvironment(
182187
defaultEnvironment: EnvironmentValues
183188
) -> EnvironmentValues {
184-
return defaultEnvironment
189+
return
190+
defaultEnvironment
191+
.with(\.font, .system(size: 14))
185192
}
186193

187194
private func fatalError(_ message: String) -> Never {
@@ -271,6 +278,15 @@ public struct WinUIBackend: AppBackend {
271278
18 + 8,
272279
18 + 8
273280
)
281+
} else if widget is WinUI.ToggleSwitch {
282+
// WinUI sets the min-width of switches to 154 for whatever reason,
283+
// and I don't know how to override that default from Swift, so I'm
284+
// just hardcoding the size. This keeps getting jankier and
285+
// jankier...
286+
return SIMD2(
287+
40,
288+
20
289+
)
274290
} else if let picker = widget as? CustomComboBox, picker.padding == noPadding {
275291
let label = TextBlock()
276292
label.text = picker.options[Int(max(picker.selectedIndex, 0))]
@@ -334,6 +350,14 @@ public struct WinUIBackend: AppBackend {
334350
11 + 11 + 2,
335351
5 + 6 + 2
336352
)
353+
} else if let toggleButton = widget as? WinUI.ToggleButton,
354+
toggleButton.padding == noPadding
355+
{
356+
// See the above comment regarding Button. Very similar situation.
357+
adjustment = SIMD2(
358+
11 + 11 + 2,
359+
5 + 6 + 2
360+
)
337361
} else if let textField = widget as? WinUI.TextBox, textField.padding == noPadding {
338362
// The default padding applied to text boxes can be found here:
339363
// https://github.com/microsoft/microsoft-ui-xaml/blob/650b2c1bad272393400403ca323b3cb8745f95d0/src/controls/dev/CommonStyles/Common_themeresources.xaml#L12
@@ -655,6 +679,54 @@ public struct WinUIBackend: AppBackend {
655679
}
656680
}
657681

682+
public func createToggle() -> Widget {
683+
let toggle = ToggleButton()
684+
toggle.click.addHandler { [weak internalState] _, _ in
685+
guard let internalState = internalState else {
686+
return
687+
}
688+
internalState.toggleClickActions[ObjectIdentifier(toggle)]?(toggle.isChecked ?? false)
689+
}
690+
return toggle
691+
}
692+
693+
public func updateToggle(_ toggle: Widget, label: String, onChange: @escaping (Bool) -> Void) {
694+
let toggle = toggle as! ToggleButton
695+
let block = TextBlock()
696+
block.text = label
697+
toggle.content = block
698+
internalState.toggleClickActions[ObjectIdentifier(toggle)] = onChange
699+
}
700+
701+
public func setState(ofToggle toggle: Widget, to state: Bool) {
702+
(toggle as! ToggleButton).isChecked = state
703+
}
704+
705+
public func createSwitch() -> Widget {
706+
let toggleSwitch = ToggleSwitch()
707+
toggleSwitch.offContent = ""
708+
toggleSwitch.onContent = ""
709+
toggleSwitch.padding = Thickness(left: 0, top: 0, right: 0, bottom: 0)
710+
toggleSwitch.toggled.addHandler { [weak internalState] _, _ in
711+
guard let internalState = internalState else {
712+
return
713+
}
714+
internalState.switchClickActions[ObjectIdentifier(toggleSwitch)]?(toggleSwitch.isOn)
715+
}
716+
return toggleSwitch
717+
}
718+
719+
public func updateSwitch(_ toggleSwitch: Widget, onChange: @escaping (Bool) -> Void) {
720+
internalState.switchClickActions[ObjectIdentifier(toggleSwitch)] = onChange
721+
}
722+
723+
public func setState(ofSwitch switchWidget: Widget, to state: Bool) {
724+
let switchWidget = switchWidget as! ToggleSwitch
725+
if switchWidget.isOn != state {
726+
switchWidget.isOn = state
727+
}
728+
}
729+
658730
// public func createTable(rows: Int, columns: Int) -> Widget {
659731
// let grid = Grid()
660732
// grid.columnSpacing = 10
@@ -699,47 +771,6 @@ public struct WinUIBackend: AppBackend {
699771
// Grid.setRow(widget, Int32(position.row))
700772
// grid.children.append(widget)
701773
// }
702-
703-
// public func createToggle() -> Widget {
704-
// let toggle = ToggleButton()
705-
// toggle.click.addHandler { [weak internalState] _, _ in
706-
// guard let internalState = internalState else {
707-
// return
708-
// }
709-
// internalState.toggleClickActions[ObjectIdentifier(toggle)]?(toggle.isChecked ?? false)
710-
// }
711-
// return toggle
712-
// }
713-
714-
// public func updateToggle(_ toggle: Widget, label: String, onChange: @escaping (Bool) -> Void) {
715-
// (toggle as! ToggleButton).content = label
716-
// internalState.toggleClickActions[ObjectIdentifier(toggle)] = onChange
717-
// }
718-
719-
// public func setState(ofToggle toggle: Widget, to state: Bool) {
720-
// (toggle as! ToggleButton).isChecked = state
721-
// }
722-
723-
// public func createSwitch() -> Widget {
724-
// let toggleSwitch = ToggleSwitch()
725-
// toggleSwitch.onContent = ""
726-
// toggleSwitch.offContent = ""
727-
// toggleSwitch.toggled.addHandler { [weak internalState] _, _ in
728-
// guard let internalState = internalState else {
729-
// return
730-
// }
731-
// internalState.switchClickActions[ObjectIdentifier(toggleSwitch)]?(toggleSwitch.isOn)
732-
// }
733-
// return toggleSwitch
734-
// }
735-
736-
// public func updateSwitch(_ toggleSwitch: Widget, onChange: @escaping (Bool) -> Void) {
737-
// internalState.switchClickActions[ObjectIdentifier(toggleSwitch)] = onChange
738-
// }
739-
740-
// public func setState(ofSwitch switchWidget: Widget, to state: Bool) {
741-
// (switchWidget as! ToggleSwitch).isOn = state
742-
// }
743774
}
744775

745776
extension SwiftCrossUI.Color {

0 commit comments

Comments
 (0)