@@ -50,6 +50,7 @@ public final class WinUIBackend: AppBackend {
50
50
var textFieldChangeActions : [ ObjectIdentifier : ( String ) -> Void ] = [ : ]
51
51
var textFieldSubmitActions : [ ObjectIdentifier : ( ) -> Void ] = [ : ]
52
52
var dispatcherQueue : WinAppSDK . DispatcherQueue ?
53
+ var themeChangeAction : ( ( ) -> Void ) ?
53
54
}
54
55
55
56
private var internalState : InternalState
@@ -71,6 +72,11 @@ public final class WinUIBackend: AppBackend {
71
72
_ = application. resources. insert ( " ToggleSwitchPreContentMargin " , 0.0 as Double )
72
73
_ = application. resources. insert ( " ToggleSwitchPostContentMargin " , 0.0 as Double )
73
74
75
+ // Handle theme changes
76
+ UWP . UISettings ( ) . colorValuesChanged. addHandler { _, _ in
77
+ self . internalState. themeChangeAction ? ( )
78
+ }
79
+
74
80
// TODO: Read in previously hardcoded values from the application's
75
81
// resources dictionary for future-proofing. Example code for getting
76
82
// property values;
@@ -185,6 +191,9 @@ public final class WinUIBackend: AppBackend {
185
191
public func setChild( ofWindow window: Window , to widget: Widget ) {
186
192
window. content = widget
187
193
try ! widget. updateLayout ( )
194
+ widget. actualThemeChanged. addHandler { _, _ in
195
+ self . internalState. themeChangeAction ? ( )
196
+ }
188
197
}
189
198
190
199
public func show( window: Window ) {
@@ -196,7 +205,7 @@ public final class WinUIBackend: AppBackend {
196
205
}
197
206
198
207
public func openExternalURL( _ url: URL ) throws {
199
- UWP . Launcher. launchUriAsync ( WindowsFoundation . Uri ( url. absoluteString) )
208
+ _ = UWP . Launcher. launchUriAsync ( WindowsFoundation . Uri ( url. absoluteString) )
200
209
}
201
210
202
211
public func runInMainThread( action: @escaping ( ) -> Void ) {
@@ -218,14 +227,22 @@ public final class WinUIBackend: AppBackend {
218
227
public func computeRootEnvironment(
219
228
defaultEnvironment: EnvironmentValues
220
229
) -> EnvironmentValues {
230
+ // Source: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/ui/apply-windows-themes#know-when-dark-mode-is-enabled
231
+ let backgroundColor = try ! UWP . UISettings ( ) . getColorValue ( . background)
232
+
233
+ let green = Int ( backgroundColor. g)
234
+ let red = Int ( backgroundColor. r)
235
+ let blue = Int ( backgroundColor. b)
236
+ let isLight = 5 * green + 2 * red + blue > 8 * 128
237
+
221
238
return
222
239
defaultEnvironment
223
240
. with ( \. font, . system( size: 14 ) )
241
+ . with ( \. colorScheme, isLight ? . light : . dark)
224
242
}
225
243
226
244
public func setRootEnvironmentChangeHandler( to action: @escaping ( ) -> Void ) {
227
- print ( " Implement set root environment change handler " )
228
- // TODO
245
+ internalState. themeChangeAction = action
229
246
}
230
247
231
248
public func setIncomingURLHandler( to action: @escaping ( URL ) -> Void ) {
@@ -494,6 +511,13 @@ public final class WinUIBackend: AppBackend {
494
511
button. content = block
495
512
environment. apply ( to: block)
496
513
internalState. buttonClickActions [ ObjectIdentifier ( button) ] = action
514
+
515
+ switch environment. colorScheme {
516
+ case . light:
517
+ button. requestedTheme = . light
518
+ case . dark:
519
+ button. requestedTheme = . dark
520
+ }
497
521
}
498
522
499
523
public func createScrollContainer( for child: Widget ) -> Widget {
@@ -544,6 +568,14 @@ public final class WinUIBackend: AppBackend {
544
568
slider. minimum = minimum
545
569
slider. maximum = maximum
546
570
internalState. sliderChangeActions [ ObjectIdentifier ( slider) ] = onChange
571
+
572
+ // TODO: Add environment to updateSlider API
573
+ // switch environment.colorScheme {
574
+ // case .light:
575
+ // slider.requestedTheme = .light
576
+ // case .dark:
577
+ // slider.requestedTheme = .dark
578
+ // }
547
579
}
548
580
549
581
public func setValue( ofSlider slider: Widget , to value: Double ) {
@@ -585,6 +617,13 @@ public final class WinUIBackend: AppBackend {
585
617
environment. apply ( to: picker)
586
618
picker. actualForegroundColor = environment. suggestedForegroundColor. uwpColor
587
619
620
+ switch environment. colorScheme {
621
+ case . light:
622
+ picker. requestedTheme = . light
623
+ case . dark:
624
+ picker. requestedTheme = . dark
625
+ }
626
+
588
627
// Only update options past this point, otherwise the early return
589
628
// will cause issues.
590
629
guard options. count > 0 else {
@@ -622,7 +661,7 @@ public final class WinUIBackend: AppBackend {
622
661
}
623
662
624
663
missing ( " proper picker updating logic " )
625
- missing ( " picker environment handling " )
664
+ missing ( " picker font handling " )
626
665
627
666
picker. options = options
628
667
}
@@ -664,7 +703,14 @@ public final class WinUIBackend: AppBackend {
664
703
internalState. textFieldChangeActions [ ObjectIdentifier ( textField) ] = onChange
665
704
internalState. textFieldSubmitActions [ ObjectIdentifier ( textField) ] = onSubmit
666
705
667
- missing ( " text field environment handling " )
706
+ switch environment. colorScheme {
707
+ case . light:
708
+ textField. requestedTheme = . light
709
+ case . dark:
710
+ textField. requestedTheme = . dark
711
+ }
712
+
713
+ missing ( " text field font handling " )
668
714
}
669
715
670
716
public func setContent( ofTextField textField: Widget , to content: String ) {
@@ -760,6 +806,15 @@ public final class WinUIBackend: AppBackend {
760
806
block. text = label
761
807
toggle. content = block
762
808
internalState. toggleClickActions [ ObjectIdentifier ( toggle) ] = onChange
809
+
810
+ // TODO: Add environment to updateToggle API. Rename updateToggle etc to
811
+ // updateToggleButton etc
812
+ // switch environment.colorScheme {
813
+ // case .light:
814
+ // toggle.requestedTheme = .light
815
+ // case .dark:
816
+ // toggle.requestedTheme = .dark
817
+ // }
763
818
}
764
819
765
820
public func setState( ofToggle toggle: Widget , to state: Bool ) {
@@ -782,6 +837,14 @@ public final class WinUIBackend: AppBackend {
782
837
783
838
public func updateSwitch( _ toggleSwitch: Widget , onChange: @escaping ( Bool ) -> Void ) {
784
839
internalState. switchClickActions [ ObjectIdentifier ( toggleSwitch) ] = onChange
840
+
841
+ // TODO: Add environment to updateSwitch API
842
+ // switch environment.colorScheme {
843
+ // case .light:
844
+ // toggleSwitch.requestedTheme = .light
845
+ // case .dark:
846
+ // toggleSwitch.requestedTheme = .dark
847
+ // }
785
848
}
786
849
787
850
public func setState( ofSwitch switchWidget: Widget , to state: Bool ) {
@@ -811,6 +874,13 @@ public final class WinUIBackend: AppBackend {
811
874
if actionLabels. count >= 3 {
812
875
alert. closeButtonText = actionLabels [ 2 ]
813
876
}
877
+
878
+ switch environment. colorScheme {
879
+ case . light:
880
+ alert. requestedTheme = . light
881
+ case . dark:
882
+ alert. requestedTheme = . dark
883
+ }
814
884
}
815
885
816
886
public func showAlert(
@@ -935,6 +1005,15 @@ extension SwiftCrossUI.Color {
935
1005
b: UInt8 ( ( blue * Float( UInt8 . max) ) . rounded ( ) )
936
1006
)
937
1007
}
1008
+
1009
+ init ( uwpColor: UWP . Color ) {
1010
+ self . init (
1011
+ Float ( uwpColor. r) / Float( UInt8 . max) ,
1012
+ Float ( uwpColor. g) / Float( UInt8 . max) ,
1013
+ Float ( uwpColor. b) / Float( UInt8 . max) ,
1014
+ Float ( uwpColor. a) / Float( UInt8 . max)
1015
+ )
1016
+ }
938
1017
}
939
1018
940
1019
extension EnvironmentValues {
0 commit comments