@@ -50,6 +50,7 @@ public final class WinUIBackend: AppBackend {
5050 var textFieldChangeActions : [ ObjectIdentifier : ( String ) -> Void ] = [ : ]
5151 var textFieldSubmitActions : [ ObjectIdentifier : ( ) -> Void ] = [ : ]
5252 var dispatcherQueue : WinAppSDK . DispatcherQueue ?
53+ var themeChangeAction : ( ( ) -> Void ) ?
5354 }
5455
5556 private var internalState : InternalState
@@ -71,6 +72,11 @@ public final class WinUIBackend: AppBackend {
7172 _ = application. resources. insert ( " ToggleSwitchPreContentMargin " , 0.0 as Double )
7273 _ = application. resources. insert ( " ToggleSwitchPostContentMargin " , 0.0 as Double )
7374
75+ // Handle theme changes
76+ UWP . UISettings ( ) . colorValuesChanged. addHandler { _, _ in
77+ self . internalState. themeChangeAction ? ( )
78+ }
79+
7480 // TODO: Read in previously hardcoded values from the application's
7581 // resources dictionary for future-proofing. Example code for getting
7682 // property values;
@@ -185,6 +191,9 @@ public final class WinUIBackend: AppBackend {
185191 public func setChild( ofWindow window: Window , to widget: Widget ) {
186192 window. content = widget
187193 try ! widget. updateLayout ( )
194+ widget. actualThemeChanged. addHandler { _, _ in
195+ self . internalState. themeChangeAction ? ( )
196+ }
188197 }
189198
190199 public func show( window: Window ) {
@@ -196,7 +205,7 @@ public final class WinUIBackend: AppBackend {
196205 }
197206
198207 public func openExternalURL( _ url: URL ) throws {
199- UWP . Launcher. launchUriAsync ( WindowsFoundation . Uri ( url. absoluteString) )
208+ _ = UWP . Launcher. launchUriAsync ( WindowsFoundation . Uri ( url. absoluteString) )
200209 }
201210
202211 public func runInMainThread( action: @escaping ( ) -> Void ) {
@@ -218,14 +227,22 @@ public final class WinUIBackend: AppBackend {
218227 public func computeRootEnvironment(
219228 defaultEnvironment: EnvironmentValues
220229 ) -> 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+
221238 return
222239 defaultEnvironment
223240 . with ( \. font, . system( size: 14 ) )
241+ . with ( \. colorScheme, isLight ? . light : . dark)
224242 }
225243
226244 public func setRootEnvironmentChangeHandler( to action: @escaping ( ) -> Void ) {
227- print ( " Implement set root environment change handler " )
228- // TODO
245+ internalState. themeChangeAction = action
229246 }
230247
231248 public func setIncomingURLHandler( to action: @escaping ( URL ) -> Void ) {
@@ -494,6 +511,13 @@ public final class WinUIBackend: AppBackend {
494511 button. content = block
495512 environment. apply ( to: block)
496513 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+ }
497521 }
498522
499523 public func createScrollContainer( for child: Widget ) -> Widget {
@@ -544,6 +568,14 @@ public final class WinUIBackend: AppBackend {
544568 slider. minimum = minimum
545569 slider. maximum = maximum
546570 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+ // }
547579 }
548580
549581 public func setValue( ofSlider slider: Widget , to value: Double ) {
@@ -585,6 +617,13 @@ public final class WinUIBackend: AppBackend {
585617 environment. apply ( to: picker)
586618 picker. actualForegroundColor = environment. suggestedForegroundColor. uwpColor
587619
620+ switch environment. colorScheme {
621+ case . light:
622+ picker. requestedTheme = . light
623+ case . dark:
624+ picker. requestedTheme = . dark
625+ }
626+
588627 // Only update options past this point, otherwise the early return
589628 // will cause issues.
590629 guard options. count > 0 else {
@@ -622,7 +661,7 @@ public final class WinUIBackend: AppBackend {
622661 }
623662
624663 missing ( " proper picker updating logic " )
625- missing ( " picker environment handling " )
664+ missing ( " picker font handling " )
626665
627666 picker. options = options
628667 }
@@ -664,7 +703,14 @@ public final class WinUIBackend: AppBackend {
664703 internalState. textFieldChangeActions [ ObjectIdentifier ( textField) ] = onChange
665704 internalState. textFieldSubmitActions [ ObjectIdentifier ( textField) ] = onSubmit
666705
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 " )
668714 }
669715
670716 public func setContent( ofTextField textField: Widget , to content: String ) {
@@ -760,6 +806,15 @@ public final class WinUIBackend: AppBackend {
760806 block. text = label
761807 toggle. content = block
762808 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+ // }
763818 }
764819
765820 public func setState( ofToggle toggle: Widget , to state: Bool ) {
@@ -782,6 +837,14 @@ public final class WinUIBackend: AppBackend {
782837
783838 public func updateSwitch( _ toggleSwitch: Widget , onChange: @escaping ( Bool ) -> Void ) {
784839 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+ // }
785848 }
786849
787850 public func setState( ofSwitch switchWidget: Widget , to state: Bool ) {
@@ -811,6 +874,13 @@ public final class WinUIBackend: AppBackend {
811874 if actionLabels. count >= 3 {
812875 alert. closeButtonText = actionLabels [ 2 ]
813876 }
877+
878+ switch environment. colorScheme {
879+ case . light:
880+ alert. requestedTheme = . light
881+ case . dark:
882+ alert. requestedTheme = . dark
883+ }
814884 }
815885
816886 public func showAlert(
@@ -935,6 +1005,15 @@ extension SwiftCrossUI.Color {
9351005 b: UInt8 ( ( blue * Float( UInt8 . max) ) . rounded ( ) )
9361006 )
9371007 }
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+ }
9381017}
9391018
9401019extension EnvironmentValues {
0 commit comments