Skip to content

Commit bf6aa23

Browse files
committed
feat(windows): application
1 parent eb05462 commit bf6aa23

1 file changed

Lines changed: 136 additions & 1 deletion

File tree

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,137 @@
11
import { ApplicationCommon } from './application-common';
2-
export class WindowsApplication extends ApplicationCommon {}
2+
import type { NavigationEntry } from '../ui/frame/frame-interfaces';
3+
import { setAppMainEntry, setToggleApplicationEventListenersCallback, setApplicationPropertiesCallback, setA11yUpdatePropertiesCallback } from './helpers-common';
4+
5+
export class WindowsApplication extends ApplicationCommon {
6+
constructor() {
7+
super();
8+
this.setupLifecycleEvents();
9+
}
10+
11+
run(entry?: string | NavigationEntry): void {
12+
if (this.started) {
13+
throw new Error('Application is already started.');
14+
}
15+
16+
this.started = true;
17+
setAppMainEntry(typeof entry === 'string' ? { moduleName: entry } : entry);
18+
}
19+
20+
getNativeApplication() {
21+
return Windows?.UI?.Xaml?.Application?.Current ?? Windows?.ApplicationModel?.Core?.CoreApplication;
22+
}
23+
24+
protected getOrientation(): 'portrait' | 'landscape' | 'unknown' {
25+
try {
26+
const displayInfo = Windows.Graphics.Display.DisplayInformation.GetForCurrentView();
27+
const orientation = displayInfo?.CurrentOrientation;
28+
const DisplayOrientations = Windows.Graphics.Display.DisplayOrientations;
29+
30+
if (orientation === DisplayOrientations.Portrait || orientation === DisplayOrientations.PortraitFlipped) {
31+
return 'portrait';
32+
}
33+
34+
if (orientation === DisplayOrientations.Landscape || orientation === DisplayOrientations.LandscapeFlipped) {
35+
return 'landscape';
36+
}
37+
} catch (e) {}
38+
39+
return 'unknown';
40+
}
41+
42+
protected getSystemAppearance(): 'dark' | 'light' | null {
43+
try {
44+
const content: any = Windows.UI.Xaml.Window.Current.Content;
45+
46+
const actualTheme = content?.ActualTheme;
47+
const ElementTheme = Windows.UI.Xaml.ElementTheme;
48+
if (typeof actualTheme === 'number' && ElementTheme) {
49+
if (actualTheme === ElementTheme.Dark) return 'dark';
50+
if (actualTheme === ElementTheme.Light) return 'light';
51+
}
52+
53+
const appTheme = Windows.UI.Xaml.Application.Current.RequestedTheme;
54+
const ApplicationTheme = Windows.UI.Xaml.ApplicationTheme;
55+
if (appTheme === ApplicationTheme.Dark) return 'dark';
56+
if (appTheme === ApplicationTheme.Light) return 'light';
57+
58+
const UISettings = Windows.UI.ViewManagement.UISettings;
59+
const ui = new UISettings();
60+
const foreground = ui.GetColorValue(Windows.UI.ViewManagement.UIColorType.Foreground);
61+
if (!foreground) {
62+
return null;
63+
}
64+
65+
// In dark mode Windows uses a light (near-white) foreground color
66+
return foreground.R > 128 ? 'dark' : 'light';
67+
} catch (e) {}
68+
69+
return null;
70+
}
71+
72+
private setupLifecycleEvents(): void {
73+
const coreApp = Windows.ApplicationModel.Core.CoreApplication;
74+
75+
if (coreApp) {
76+
coreApp.Suspending = NSWinRT.asDelegate((sender: any, args: any) => this.setSuspended(true, { win: args }));
77+
coreApp.Resuming = NSWinRT.asDelegate((sender: any, args: any) => this.setSuspended(false, { win: args }));
78+
coreApp.EnteredBackground = NSWinRT.asDelegate((sender: any, args: any) => this.setInBackground(true, { win: args }));
79+
coreApp.LeavingBackground = NSWinRT.asDelegate((sender: any, args: any) => this.setInBackground(false, { win: args }));
80+
coreApp.Exiting = NSWinRT.asDelegate((sender: any, args: any) => this.notify({ eventName: this.exitEvent, object: this, win: args }));
81+
coreApp.UnhandledErrorDetected = NSWinRT.asDelegate((sender: any, args: any) => this.notify({ eventName: this.uncaughtErrorEvent, object: this, win: args }));
82+
}
83+
84+
const displayInfo = Windows.Graphics.Display.DisplayInformation.GetForCurrentView();
85+
const onOrientationChanged = () => {
86+
const newValue = this.getOrientation();
87+
this.setOrientation(newValue);
88+
};
89+
90+
if (displayInfo && displayInfo.OrientationChanged !== undefined) {
91+
displayInfo.OrientationChanged = NSWinRT.asDelegate(onOrientationChanged);
92+
}
93+
94+
const ui = new Windows.UI.ViewManagement.UISettings();
95+
const onColorValuesChanged = () => {
96+
const newSys = this.getSystemAppearance();
97+
if (newSys !== null) {
98+
this.setSystemAppearance(newSys);
99+
}
100+
};
101+
102+
if (ui && ui.ColorValuesChanged !== undefined) {
103+
ui.ColorValuesChanged = NSWinRT.asDelegate(onColorValuesChanged);
104+
}
105+
}
106+
}
107+
108+
export const Application: WindowsApplication = new WindowsApplication();
109+
110+
function updateAccessibilityProperties(view: any): void {
111+
if (!view || !view.nativeViewProtected) {
112+
return;
113+
}
114+
115+
// todo
116+
}
117+
118+
setA11yUpdatePropertiesCallback(updateAccessibilityProperties);
119+
120+
const applicationEvents: string[] = [Application.orientationChangedEvent, Application.systemAppearanceChangedEvent];
121+
function toggleApplicationEventListeners(toAdd: boolean, callback: (args: any) => void) {
122+
for (const eventName of applicationEvents) {
123+
if (toAdd) {
124+
Application.on(eventName, callback);
125+
} else {
126+
Application.off(eventName, callback);
127+
}
128+
}
129+
}
130+
setToggleApplicationEventListenersCallback(toggleApplicationEventListeners);
131+
132+
setApplicationPropertiesCallback(() => {
133+
return {
134+
orientation: Application.orientation(),
135+
systemAppearance: Application.systemAppearance(),
136+
};
137+
});

0 commit comments

Comments
 (0)