diff --git a/Ursa.sln b/Ursa.sln
index 51966e5..9b2953a 100644
--- a/Ursa.sln
+++ b/Ursa.sln
@@ -8,6 +8,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Themes.Semi", "src\Urs
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{A41BAF0D-DA61-4A63-889A-084BAD36FD66}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.Android", "demo\Ursa.Demo.Android\Ursa.Demo.Android.csproj", "{3FC76CD9-CE5D-4804-A8D6-4E292EB296AA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.Desktop", "demo\Ursa.Demo.Desktop\Ursa.Demo.Desktop.csproj", "{B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.iOS", "demo\Ursa.Demo.iOS\Ursa.Demo.iOS.csproj", "{94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.Browser", "demo\Ursa.Demo.Browser\Ursa.Demo.Browser.csproj", "{D1942476-8473-4608-BB9F-5AC01083BBDA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -26,8 +34,28 @@ Global
{53B5F277-3AEB-4661-ACAE-15CFFF2ED800}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53B5F277-3AEB-4661-ACAE-15CFFF2ED800}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53B5F277-3AEB-4661-ACAE-15CFFF2ED800}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3FC76CD9-CE5D-4804-A8D6-4E292EB296AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3FC76CD9-CE5D-4804-A8D6-4E292EB296AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3FC76CD9-CE5D-4804-A8D6-4E292EB296AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3FC76CD9-CE5D-4804-A8D6-4E292EB296AA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1942476-8473-4608-BB9F-5AC01083BBDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1942476-8473-4608-BB9F-5AC01083BBDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1942476-8473-4608-BB9F-5AC01083BBDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1942476-8473-4608-BB9F-5AC01083BBDA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
+ {3FC76CD9-CE5D-4804-A8D6-4E292EB296AA} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
+ {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
+ {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
+ {D1942476-8473-4608-BB9F-5AC01083BBDA} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
EndGlobalSection
EndGlobal
diff --git a/demo/Directory.Build.props b/demo/Directory.Build.props
new file mode 100644
index 0000000..ae8bdf5
--- /dev/null
+++ b/demo/Directory.Build.props
@@ -0,0 +1,6 @@
+
+
+ enable
+ 11.0.0
+
+
diff --git a/demo/Ursa.Demo.Android/Icon.png b/demo/Ursa.Demo.Android/Icon.png
new file mode 100644
index 0000000..b128518
Binary files /dev/null and b/demo/Ursa.Demo.Android/Icon.png differ
diff --git a/demo/Ursa.Demo.Android/MainActivity.cs b/demo/Ursa.Demo.Android/MainActivity.cs
new file mode 100644
index 0000000..716383b
--- /dev/null
+++ b/demo/Ursa.Demo.Android/MainActivity.cs
@@ -0,0 +1,17 @@
+using Android.App;
+using Android.Content.PM;
+using Avalonia.Android;
+
+namespace Ursa.Demo.Android;
+
+[Activity(
+ Label = "Ursa",
+ Theme = "@style/MyTheme.NoActionBar",
+ Icon = "@drawable/icon",
+ MainLauncher = true,
+ LaunchMode = LaunchMode.SingleTop,
+ ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
+public class MainActivity : AvaloniaMainActivity
+{
+
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Android/Properties/AndroidManifest.xml b/demo/Ursa.Demo.Android/Properties/AndroidManifest.xml
new file mode 100644
index 0000000..1142897
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Properties/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Resources/AboutResources.txt b/demo/Ursa.Demo.Android/Resources/AboutResources.txt
new file mode 100644
index 0000000..c2bca97
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/AboutResources.txt
@@ -0,0 +1,44 @@
+Images, layout descriptions, binary blobs and string dictionaries can be included
+in your application as resource files. Various Android APIs are designed to
+operate on the resource IDs instead of dealing with images, strings or binary blobs
+directly.
+
+For example, a sample Android app that contains a user interface layout (main.axml),
+an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
+would keep its resources in the "Resources" directory of the application:
+
+Resources/
+ drawable/
+ icon.png
+
+ layout/
+ main.axml
+
+ values/
+ strings.xml
+
+In order to get the build system to recognize Android resources, set the build action to
+"AndroidResource". The native Android APIs do not operate directly with filenames, but
+instead operate on resource IDs. When you compile an Android application that uses resources,
+the build system will package the resources for distribution and generate a class called "R"
+(this is an Android convention) that contains the tokens for each one of the resources
+included. For example, for the above Resources layout, this is what the R class would expose:
+
+public class R {
+ public class drawable {
+ public const int icon = 0x123;
+ }
+
+ public class layout {
+ public const int main = 0x456;
+ }
+
+ public class strings {
+ public const int first_string = 0xabc;
+ public const int second_string = 0xbcd;
+ }
+}
+
+You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
+to reference the layout/main.axml file, or R.strings.first_string to reference the first
+string in the dictionary file values/strings.xml.
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Android/Resources/drawable-night-v31/avalonia_anim.xml b/demo/Ursa.Demo.Android/Resources/drawable-night-v31/avalonia_anim.xml
new file mode 100644
index 0000000..dde4b5a
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/drawable-night-v31/avalonia_anim.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Resources/drawable-v31/avalonia_anim.xml b/demo/Ursa.Demo.Android/Resources/drawable-v31/avalonia_anim.xml
new file mode 100644
index 0000000..94f27d9
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/drawable-v31/avalonia_anim.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Resources/drawable/splash_screen.xml b/demo/Ursa.Demo.Android/Resources/drawable/splash_screen.xml
new file mode 100644
index 0000000..2e920b4
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/drawable/splash_screen.xml
@@ -0,0 +1,13 @@
+
+
+
+ -
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Resources/values-night/colors.xml b/demo/Ursa.Demo.Android/Resources/values-night/colors.xml
new file mode 100644
index 0000000..3d47b6f
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/values-night/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #212121
+
diff --git a/demo/Ursa.Demo.Android/Resources/values-v31/styles.xml b/demo/Ursa.Demo.Android/Resources/values-v31/styles.xml
new file mode 100644
index 0000000..d5ecec4
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/values-v31/styles.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Resources/values/colors.xml b/demo/Ursa.Demo.Android/Resources/values/colors.xml
new file mode 100644
index 0000000..59279d5
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
diff --git a/demo/Ursa.Demo.Android/Resources/values/styles.xml b/demo/Ursa.Demo.Android/Resources/values/styles.xml
new file mode 100644
index 0000000..6e534de
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Resources/values/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Android/Ursa.Demo.Android.csproj b/demo/Ursa.Demo.Android/Ursa.Demo.Android.csproj
new file mode 100644
index 0000000..4071d05
--- /dev/null
+++ b/demo/Ursa.Demo.Android/Ursa.Demo.Android.csproj
@@ -0,0 +1,30 @@
+
+
+ Exe
+ net7.0-android
+ 21
+ enable
+ com.irihitech.Ursa
+ 1
+ 1.0
+ apk
+ False
+ true
+ Ursa.Demo.Android
+
+
+
+
+ Resources\drawable\Icon.png
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Browser/AppBundle/Logo.svg b/demo/Ursa.Demo.Browser/AppBundle/Logo.svg
new file mode 100644
index 0000000..4cb587d
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/AppBundle/Logo.svg
@@ -0,0 +1,60 @@
+
+
+
+
diff --git a/demo/Ursa.Demo.Browser/AppBundle/app.css b/demo/Ursa.Demo.Browser/AppBundle/app.css
new file mode 100644
index 0000000..a424538
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/AppBundle/app.css
@@ -0,0 +1,74 @@
+:root {
+ --sat: env(safe-area-inset-top);
+ --sar: env(safe-area-inset-right);
+ --sab: env(safe-area-inset-bottom);
+ --sal: env(safe-area-inset-left);
+}
+
+/* HTML styles for the splash screen */
+
+.highlight {
+ color: white;
+ font-size: 2.5rem;
+ display: block;
+}
+
+.purple {
+ color: #8b44ac;
+}
+
+.icon {
+ opacity: 0.05;
+ height: 35%;
+ width: 35%;
+ position: absolute;
+ background-repeat: no-repeat;
+ right: 0px;
+ bottom: 0px;
+ margin-right: 3%;
+ margin-bottom: 5%;
+ z-index: 5000;
+ background-position: right bottom;
+ pointer-events: none;
+}
+
+#avalonia-splash a {
+ color: whitesmoke;
+ text-decoration: none;
+}
+
+.center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+}
+
+#avalonia-splash {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ color: whitesmoke;
+ background: #1b2a4e;
+ font-family: 'Nunito', sans-serif;
+ background-position: center;
+ background-size: cover;
+ background-repeat: no-repeat;
+ justify-content: center;
+ align-items: center;
+}
+
+.splash-close {
+ animation: fadeout 0.25s linear forwards;
+}
+
+@keyframes fadeout {
+ 0% {
+ opacity: 100%;
+ }
+
+ 100% {
+ opacity: 0;
+ visibility: collapse;
+ }
+}
diff --git a/demo/Ursa.Demo.Browser/AppBundle/favicon.ico b/demo/Ursa.Demo.Browser/AppBundle/favicon.ico
new file mode 100644
index 0000000..da28783
Binary files /dev/null and b/demo/Ursa.Demo.Browser/AppBundle/favicon.ico differ
diff --git a/demo/Ursa.Demo.Browser/AppBundle/index.html b/demo/Ursa.Demo.Browser/AppBundle/index.html
new file mode 100644
index 0000000..184f7ca
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/AppBundle/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Ursa.Demo.Browser
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Powered by
+ Ursa
+
+
+

+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Browser/AppBundle/main.js b/demo/Ursa.Demo.Browser/AppBundle/main.js
new file mode 100644
index 0000000..0dbe2e4
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/AppBundle/main.js
@@ -0,0 +1,13 @@
+import { dotnet } from './dotnet.js'
+
+const is_browser = typeof window != "undefined";
+if (!is_browser) throw new Error(`Expected to be running in a browser`);
+
+const dotnetRuntime = await dotnet
+ .withDiagnosticTracing(false)
+ .withApplicationArgumentsFromQuery()
+ .create();
+
+const config = dotnetRuntime.getConfig();
+
+await dotnetRuntime.runMainAndExit(config.mainAssemblyName, [window.location.search]);
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Browser/Program.cs b/demo/Ursa.Demo.Browser/Program.cs
new file mode 100644
index 0000000..4fa7162
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/Program.cs
@@ -0,0 +1,17 @@
+using System.Runtime.Versioning;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Browser;
+
+[assembly: SupportedOSPlatform("browser")]
+
+namespace Ursa.Demo.Browser;
+
+internal partial class Program
+{
+ private static async Task Main(string[] args) => await BuildAvaloniaApp()
+ .StartBrowserAppAsync("out");
+
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure();
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Browser/Properties/launchSettings.json b/demo/Ursa.Demo.Browser/Properties/launchSettings.json
new file mode 100644
index 0000000..a1d7d0a
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "profiles": {
+ "Ursa.Demo.Browser": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/debug?browser={browserInspectUri}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Browser/Ursa.Demo.Browser.csproj b/demo/Ursa.Demo.Browser/Ursa.Demo.Browser.csproj
new file mode 100644
index 0000000..f51b5fb
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/Ursa.Demo.Browser.csproj
@@ -0,0 +1,20 @@
+
+
+ net7.0
+ browser-wasm
+ AppBundle\main.js
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.Browser/runtimeconfig.template.json b/demo/Ursa.Demo.Browser/runtimeconfig.template.json
new file mode 100644
index 0000000..c6990ba
--- /dev/null
+++ b/demo/Ursa.Demo.Browser/runtimeconfig.template.json
@@ -0,0 +1,11 @@
+{
+ "wasmHostProperties": {
+ "perHostConfig": [
+ {
+ "name": "browser",
+ "html-path": "index.html",
+ "Host": "browser"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Program.cs b/demo/Ursa.Demo.Desktop/Program.cs
similarity index 56%
rename from demo/Ursa.Demo/Program.cs
rename to demo/Ursa.Demo.Desktop/Program.cs
index 66ec68f..b74f9d3 100644
--- a/demo/Ursa.Demo/Program.cs
+++ b/demo/Ursa.Demo.Desktop/Program.cs
@@ -1,7 +1,9 @@
-using Avalonia;
-using System;
+using System;
+using Avalonia;
+using Avalonia.Dialogs;
+using Avalonia.Media;
-namespace Ursa.Demo;
+namespace Ursa.Demo.Desktop;
class Program
{
@@ -10,11 +12,23 @@ class Program
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
+ .With(new FontManagerOptions
+ {
+ FontFallbacks = new[]
+ {
+ new FontFallback
+ {
+ FontFamily = new FontFamily("Microsoft YaHei")
+ }
+ }
+ })
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
+ .UseManagedSystemDialogs()
.UsePlatformDetect()
+ .With(new Win32PlatformOptions())
.LogToTrace();
}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj
new file mode 100644
index 0000000..3d3f388
--- /dev/null
+++ b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj
@@ -0,0 +1,24 @@
+
+
+ WinExe
+
+ net7.0
+ enable
+ true
+
+
+
+ app.manifest
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/app.manifest b/demo/Ursa.Demo.Desktop/app.manifest
similarity index 92%
rename from demo/Ursa.Demo/app.manifest
rename to demo/Ursa.Demo.Desktop/app.manifest
index e0ce8d0..830f6a5 100644
--- a/demo/Ursa.Demo/app.manifest
+++ b/demo/Ursa.Demo.Desktop/app.manifest
@@ -3,7 +3,7 @@
-
+
diff --git a/demo/Ursa.Demo.iOS/AppDelegate.cs b/demo/Ursa.Demo.iOS/AppDelegate.cs
new file mode 100644
index 0000000..a565165
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/AppDelegate.cs
@@ -0,0 +1,20 @@
+using Foundation;
+using UIKit;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.iOS;
+using Avalonia.Media;
+
+namespace Ursa.Demo.iOS;
+
+// The UIApplicationDelegate for the application. This class is responsible for launching the
+// User Interface of the application, as well as listening (and optionally responding) to
+// application events from iOS.
+[Register("AppDelegate")]
+public partial class AppDelegate : AvaloniaAppDelegate
+{
+ protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
+ {
+ return base.CustomizeAppBuilder(builder);
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.iOS/Entitlements.plist b/demo/Ursa.Demo.iOS/Entitlements.plist
new file mode 100644
index 0000000..0c67376
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/Entitlements.plist
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/demo/Ursa.Demo.iOS/Info.plist b/demo/Ursa.Demo.iOS/Info.plist
new file mode 100644
index 0000000..6ce68c9
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CFBundleDisplayName
+ Ursa.Demo
+ CFBundleIdentifier
+ companyName.Ursa.Demo
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ MinimumOSVersion
+ 10.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIStatusBarHidden
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/demo/Ursa.Demo.iOS/Main.cs b/demo/Ursa.Demo.iOS/Main.cs
new file mode 100644
index 0000000..691c60d
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/Main.cs
@@ -0,0 +1,14 @@
+using UIKit;
+
+namespace Ursa.Demo.iOS;
+
+public class Application
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo.iOS/Resources/LaunchScreen.xib b/demo/Ursa.Demo.iOS/Resources/LaunchScreen.xib
new file mode 100644
index 0000000..6e888e7
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/Resources/LaunchScreen.xib
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo.iOS/Ursa.Demo.iOS.csproj b/demo/Ursa.Demo.iOS/Ursa.Demo.iOS.csproj
new file mode 100644
index 0000000..5f70ccb
--- /dev/null
+++ b/demo/Ursa.Demo.iOS/Ursa.Demo.iOS.csproj
@@ -0,0 +1,17 @@
+
+
+ Exe
+ net6.0-ios
+ 13.0
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/App.axaml b/demo/Ursa.Demo/App.axaml
index e9083c2..8326f56 100644
--- a/demo/Ursa.Demo/App.axaml
+++ b/demo/Ursa.Demo/App.axaml
@@ -1,10 +1,9 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
+
\ No newline at end of file
diff --git a/demo/Ursa.Demo/App.axaml.cs b/demo/Ursa.Demo/App.axaml.cs
index 47a67b5..169a116 100644
--- a/demo/Ursa.Demo/App.axaml.cs
+++ b/demo/Ursa.Demo/App.axaml.cs
@@ -1,7 +1,5 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Data.Core;
-using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Ursa.Demo.ViewModels;
using Ursa.Demo.Views;
@@ -19,11 +17,16 @@ public partial class App : Application
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
- // Line below is needed to remove Avalonia data validation.
- // Without this line you will get duplicate validations from both Avalonia and CT
- desktop.MainWindow = new MainWindow
+ desktop.MainWindow = new MainWindow()
{
- DataContext = new MainWindowViewModel(),
+ DataContext = new MainViewViewModel(),
+ };
+ }
+ else if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
+ {
+ singleView.MainView = new MainView()
+ {
+ DataContext = new MainViewViewModel(),
};
}
diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj
index f11d2df..4f0188d 100644
--- a/demo/Ursa.Demo/Ursa.Demo.csproj
+++ b/demo/Ursa.Demo/Ursa.Demo.csproj
@@ -1,33 +1,29 @@
- WinExe
net6.0
enable
- true
- app.manifest
+ latest
false
-
-
+
-
+
-
-
+
-
-
-
+
+
+
-
-
+
+
diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
new file mode 100644
index 0000000..6641f1f
--- /dev/null
+++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
@@ -0,0 +1,39 @@
+using CommunityToolkit.Mvvm.Messaging;
+
+namespace Ursa.Demo.ViewModels;
+
+public class MainViewViewModel : ViewModelBase
+{
+ public MenuViewModel Menus { get; set; } = new MenuViewModel();
+
+ private object? _content;
+
+ public object? Content
+ {
+ get => _content;
+ set => SetProperty(ref _content, value);
+ }
+
+ public MainViewViewModel()
+ {
+ WeakReferenceMessenger.Default.Register(this, OnNavigation);
+ }
+
+
+ private void OnNavigation(MainViewViewModel vm, string s)
+ {
+ Content = s switch
+ {
+ MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(),
+ MenuKeys.MenuKeyBanner => new BannerDemoViewModel(),
+ MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(),
+ MenuKeys.MenuKeyDivider => new DividerDemoViewModel(),
+ MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(),
+ MenuKeys.MenuKeyLoading => new LoadingDemoViewModel(),
+ MenuKeys.MenuKeyNavigation => new NavigationMenuDemoViewModel(),
+ MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(),
+ MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
+ MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
+ };
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs b/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs
index 7fdbd75..522e47b 100644
--- a/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MainWindowViewModel.cs
@@ -1,40 +1,6 @@
-
-using CommunityToolkit.Mvvm.Messaging;
-
-namespace Ursa.Demo.ViewModels;
+namespace Ursa.Demo.ViewModels;
public class MainWindowViewModel : ViewModelBase
{
- public MenuViewModel Menus { get; set; } = new MenuViewModel();
-
- private object? _content;
- public object? Content
- {
- get => _content;
- set => SetProperty(ref _content, value);
- }
-
- public MainWindowViewModel()
- {
- WeakReferenceMessenger.Default.Register(this, OnNavigation);
- }
-
-
-
- private void OnNavigation(MainWindowViewModel vm, string s)
- {
- Content = s switch
- {
- MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(),
- MenuKeys.MenuKeyBanner => new BannerDemoViewModel(),
- MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(),
- MenuKeys.MenuKeyDivider => new DividerDemoViewModel(),
- MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(),
- MenuKeys.MenuKeyLoading => new LoadingDemoViewModel(),
- MenuKeys.MenuKeyNavigation => new NavigationMenuDemoViewModel(),
- MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(),
- MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
- MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
- };
- }
+ public MainViewViewModel MainViewViewModel { get; set; } = new MainViewViewModel();
}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Views/MainView.axaml b/demo/Ursa.Demo/Views/MainView.axaml
new file mode 100644
index 0000000..710026c
--- /dev/null
+++ b/demo/Ursa.Demo/Views/MainView.axaml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/Views/MainView.axaml.cs b/demo/Ursa.Demo/Views/MainView.axaml.cs
new file mode 100644
index 0000000..563f7ea
--- /dev/null
+++ b/demo/Ursa.Demo/Views/MainView.axaml.cs
@@ -0,0 +1,24 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Styling;
+
+namespace Ursa.Demo.Views;
+
+public partial class MainView : UserControl
+{
+ public MainView()
+ {
+ InitializeComponent();
+ }
+
+ private void ToggleButton_OnIsCheckedChanged(object? sender, RoutedEventArgs e)
+ {
+ var app = Application.Current;
+ if (app is not null)
+ {
+ var theme = app.ActualThemeVariant;
+ app.RequestedThemeVariant = theme == ThemeVariant.Dark ? ThemeVariant.Light : ThemeVariant.Dark;
+ }
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Views/MainWindow.axaml b/demo/Ursa.Demo/Views/MainWindow.axaml
index 7a80188..054e043 100644
--- a/demo/Ursa.Demo/Views/MainWindow.axaml
+++ b/demo/Ursa.Demo/Views/MainWindow.axaml
@@ -2,87 +2,16 @@
x:Class="Ursa.Demo.Views.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:converters="clr-namespace:Ursa.Demo.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:pages="clr-namespace:Ursa.Demo.Pages"
- xmlns:u="https://irihi.tech/ursa"
- xmlns:vm="using:Ursa.Demo.ViewModels"
+ xmlns:views="clr-namespace:Ursa.Demo.Views"
+ xmlns:viewModels="clr-namespace:Ursa.Demo.ViewModels"
Title="Ursa.Demo"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
- x:DataType="vm:MainWindowViewModel"
+ x:DataType="viewModels:MainWindowViewModel"
Icon="/Assets/Ursa.ico"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Views/MainWindow.axaml.cs b/demo/Ursa.Demo/Views/MainWindow.axaml.cs
index ff545b9..45aa4b8 100644
--- a/demo/Ursa.Demo/Views/MainWindow.axaml.cs
+++ b/demo/Ursa.Demo/Views/MainWindow.axaml.cs
@@ -1,7 +1,4 @@
-using Avalonia;
using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Styling;
namespace Ursa.Demo.Views;
@@ -11,14 +8,4 @@ public partial class MainWindow : Window
{
InitializeComponent();
}
-
- private void ToggleButton_OnIsCheckedChanged(object? sender, RoutedEventArgs e)
- {
- var app = Application.Current;
- if (app is not null)
- {
- var theme = app.ActualThemeVariant;
- app.RequestedThemeVariant = theme == ThemeVariant.Dark ? ThemeVariant.Light : ThemeVariant.Dark;
- }
- }
}
\ No newline at end of file
diff --git a/src/Package.props b/src/Package.props
new file mode 100644
index 0000000..0567ced
--- /dev/null
+++ b/src/Package.props
@@ -0,0 +1,5 @@
+
+
+ 11.0.0
+
+
\ No newline at end of file
diff --git a/src/Ursa.Themes.Semi/Controls/Badge.axaml b/src/Ursa.Themes.Semi/Controls/Badge.axaml
index cf6896f..fdb21ed 100644
--- a/src/Ursa.Themes.Semi/Controls/Badge.axaml
+++ b/src/Ursa.Themes.Semi/Controls/Badge.axaml
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
index 7e5a426..5bb0d73 100644
--- a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
+++ b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
@@ -1,5 +1,7 @@
+
+
netstandard2.0
enable
@@ -11,11 +13,11 @@
-
+
-
+
-
+
diff --git a/src/Ursa/Controls/Badge.cs b/src/Ursa/Controls/Badge.cs
index 72b2c0f..9956352 100644
--- a/src/Ursa/Controls/Badge.cs
+++ b/src/Ursa/Controls/Badge.cs
@@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
+using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Styling;
using Ursa.Common;
@@ -75,9 +76,9 @@ public class Badge: ContentControl
_badgeContent = e.NameScope.Find(PART_BadgeContentPresenter);
}
- protected override void OnLoaded()
+ protected override void OnLoaded(RoutedEventArgs e)
{
- base.OnLoaded();
+ base.OnLoaded(e);
UpdateBadgePosition();
}
diff --git a/src/Ursa/Ursa.csproj b/src/Ursa/Ursa.csproj
index 08660c0..01a32db 100644
--- a/src/Ursa/Ursa.csproj
+++ b/src/Ursa/Ursa.csproj
@@ -1,5 +1,7 @@
+
+
netstandard2.0
enable
@@ -11,11 +13,7 @@
-
-
-
-
-
+