From 467063b54b049402fad932cbd515b17c0fdbb165 Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Mon, 6 Oct 2025 09:31:20 +0200 Subject: [PATCH] Remove Tizen (#19722) * Remove Tizen * Address review --- Avalonia.sln | 18 -- build/DevSingleProject.targets | 2 - build/TargetFrameworks.props | 3 - dirs.proj | 6 - .../Avalonia/AvaloniaSingleProject.targets | 2 +- .../ControlCatalog.Tizen.csproj | 25 --- .../EmbedSampleNuiTizen.cs | 41 ---- samples/ControlCatalog.Tizen/Main.cs | 23 -- .../shared/res/Avalonia.png | Bin 16599 -> 0 bytes .../ControlCatalog.Tizen/tizen-manifest.xml | 23 -- .../Platforms/Tizen/Main.cs | 16 -- .../Platforms/Tizen/shared/res/Avalonia.png | Bin 16599 -> 0 bytes .../Platforms/Tizen/tizen-manifest.xml | 23 -- .../SingleProjectSandbox.csproj | 1 - .../Avalonia.Tizen/Avalonia.Tizen.csproj | 26 --- src/Tizen/Avalonia.Tizen/ITizenView.cs | 12 - src/Tizen/Avalonia.Tizen/NuiAvaloniaView.cs | 188 ---------------- .../NuiAvaloniaViewTextEditable.cs | 211 ------------------ src/Tizen/Avalonia.Tizen/NuiClipboardImpl.cs | 98 -------- src/Tizen/Avalonia.Tizen/NuiGlLayerSurface.cs | 73 ------ src/Tizen/Avalonia.Tizen/NuiGlPlatform.cs | 87 -------- .../Avalonia.Tizen/NuiKeyboardHandler.cs | 114 ---------- .../NuiNativeControlHostImpl.cs | 117 ---------- src/Tizen/Avalonia.Tizen/NuiScreens.cs | 73 ------ .../Avalonia.Tizen/NuiTizenApplication.cs | 72 ------ src/Tizen/Avalonia.Tizen/NuiTouchHandler.cs | 99 -------- .../Avalonia.Tizen/NuiViewControlHandle.cs | 39 ---- src/Tizen/Avalonia.Tizen/Platform/Consts.cs | 29 --- .../Platform/Input/TizenKeyboardDevice.cs | 139 ------------ .../Avalonia.Tizen/Platform/Interop/Strucs.cs | 20 -- .../Avalonia.Tizen/Platform/Permissions.cs | 115 ---------- .../Avalonia.Tizen/Platform/TizenLauncher.cs | 71 ------ .../Platform/TizenPlatformSettings.cs | 10 - src/Tizen/Avalonia.Tizen/Stubs.cs | 67 ------ .../TizenApplicationExtensions.cs | 23 -- src/Tizen/Avalonia.Tizen/TizenPlatform.cs | 48 ---- src/Tizen/Avalonia.Tizen/TizenRenderTimer.cs | 44 ---- .../Avalonia.Tizen/TizenRuntimePlatform.cs | 38 ---- .../Avalonia.Tizen/TizenStorageProvider.cs | 152 ------------- .../Avalonia.Tizen/TizenThreadingInterface.cs | 54 ----- src/Tizen/Avalonia.Tizen/TopLevelImpl.cs | 132 ----------- 41 files changed, 1 insertion(+), 2333 deletions(-) delete mode 100644 samples/ControlCatalog.Tizen/ControlCatalog.Tizen.csproj delete mode 100644 samples/ControlCatalog.Tizen/EmbedSampleNuiTizen.cs delete mode 100644 samples/ControlCatalog.Tizen/Main.cs delete mode 100644 samples/ControlCatalog.Tizen/shared/res/Avalonia.png delete mode 100644 samples/ControlCatalog.Tizen/tizen-manifest.xml delete mode 100644 samples/SingleProjectSandbox/Platforms/Tizen/Main.cs delete mode 100644 samples/SingleProjectSandbox/Platforms/Tizen/shared/res/Avalonia.png delete mode 100644 samples/SingleProjectSandbox/Platforms/Tizen/tizen-manifest.xml delete mode 100644 src/Tizen/Avalonia.Tizen/Avalonia.Tizen.csproj delete mode 100644 src/Tizen/Avalonia.Tizen/ITizenView.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiAvaloniaView.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiClipboardImpl.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiGlLayerSurface.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiGlPlatform.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiKeyboardHandler.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiNativeControlHostImpl.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiScreens.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiTizenApplication.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiTouchHandler.cs delete mode 100644 src/Tizen/Avalonia.Tizen/NuiViewControlHandle.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/Consts.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/Input/TizenKeyboardDevice.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/Interop/Strucs.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/Permissions.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/TizenLauncher.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Platform/TizenPlatformSettings.cs delete mode 100644 src/Tizen/Avalonia.Tizen/Stubs.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenApplicationExtensions.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenPlatform.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenRenderTimer.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenRuntimePlatform.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenStorageProvider.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TizenThreadingInterface.cs delete mode 100644 src/Tizen/Avalonia.Tizen/TopLevelImpl.cs diff --git a/Avalonia.sln b/Avalonia.sln index 79829e8fdf..5dfd11b671 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -274,12 +274,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.NUnit.Uni EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.XUnit.UnitTests", "tests\Avalonia.Headless.XUnit.UnitTests\Avalonia.Headless.XUnit.UnitTests.csproj", "{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tizen", "Tizen", "{D1300000-7217-4693-8B0F-57CBD5814302}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Tizen", "src\Tizen\Avalonia.Tizen\Avalonia.Tizen.csproj", "{DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Tizen", "samples\ControlCatalog.Tizen\ControlCatalog.Tizen.csproj", "{A0B29221-2B6F-4B29-A4D5-2227811B5915}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Metal", "src\Avalonia.Metal\Avalonia.Metal.csproj", "{60B4ED1F-ECFA-453B-8A70-1788261C8355}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Build.Tasks.UnitTest", "tests\Avalonia.Build.Tasks.UnitTest\Avalonia.Build.Tasks.UnitTest.csproj", "{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}" @@ -666,16 +660,6 @@ Global {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.Build.0 = Release|Any CPU - {DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8}.Release|Any CPU.Build.0 = Release|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Release|Any CPU.Build.0 = Release|Any CPU - {A0B29221-2B6F-4B29-A4D5-2227811B5915}.Release|Any CPU.Deploy.0 = Release|Any CPU {60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.Build.0 = Debug|Any CPU {60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -797,8 +781,6 @@ Global {4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {2999D79E-3C20-4A90-B651-CA7E0AC92D35} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} - {DFFBDBF5-5DBE-47ED-9EAE-D40B75AC99E8} = {D1300000-7217-4693-8B0F-57CBD5814302} - {A0B29221-2B6F-4B29-A4D5-2227811B5915} = {9B9E3891-2366-4253-A952-D08BCEB71098} {B0FD6A48-FBAB-4676-B36A-DE76B0922B12} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {9D6AEF22-221F-4F4B-B335-A4BA510F002C} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {5BF0C3B8-E595-4940-AB30-2DA206C2F085} = {9D6AEF22-221F-4F4B-B335-A4BA510F002C} diff --git a/build/DevSingleProject.targets b/build/DevSingleProject.targets index f6b9b54d02..6387123429 100644 --- a/build/DevSingleProject.targets +++ b/build/DevSingleProject.targets @@ -9,8 +9,6 @@ - - diff --git a/build/TargetFrameworks.props b/build/TargetFrameworks.props index e48c9933f3..f14a3876ff 100644 --- a/build/TargetFrameworks.props +++ b/build/TargetFrameworks.props @@ -8,8 +8,6 @@ $(AvsCurrentTargetFramework)-ios17.0 $(AvsCurrentTargetFramework)-tvos17.0 $(AvsCurrentTargetFramework)-browser - $(AvsCurrentTargetFramework)-tizen - 8.0.155 net6.0 @@ -22,7 +20,6 @@ 13.0 13.0 13.1 - 6.5 21.0 diff --git a/dirs.proj b/dirs.proj index 3f5e8a3f25..43de2e0b55 100644 --- a/dirs.proj +++ b/dirs.proj @@ -14,7 +14,6 @@ - @@ -23,11 +22,6 @@ - - - - - diff --git a/packages/Avalonia/AvaloniaSingleProject.targets b/packages/Avalonia/AvaloniaSingleProject.targets index 17b456f145..a776f12a7d 100644 --- a/packages/Avalonia/AvaloniaSingleProject.targets +++ b/packages/Avalonia/AvaloniaSingleProject.targets @@ -278,7 +278,7 @@ Include="$(TizenSharedPrefix)\**\*" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);@(TizenTpkUserExcludeFiles)" /> - + diff --git a/samples/ControlCatalog.Tizen/ControlCatalog.Tizen.csproj b/samples/ControlCatalog.Tizen/ControlCatalog.Tizen.csproj deleted file mode 100644 index 4b12a096d4..0000000000 --- a/samples/ControlCatalog.Tizen/ControlCatalog.Tizen.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - $(AvsCurrentTizenTargetFramework) - Exe - - - - - - - - - - - - - - - - - - - - diff --git a/samples/ControlCatalog.Tizen/EmbedSampleNuiTizen.cs b/samples/ControlCatalog.Tizen/EmbedSampleNuiTizen.cs deleted file mode 100644 index 728ea58e3b..0000000000 --- a/samples/ControlCatalog.Tizen/EmbedSampleNuiTizen.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia.Platform; -using Avalonia.Tizen; -using ControlCatalog.Pages; -using Tizen.NUI.BaseComponents; -using Tizen.NUI.Components; -using Tizen.Pims.Contacts.ContactsViews; - -namespace ControlCatalog.Tizen; -public class EmbedSampleNuiTizen : INativeDemoControl -{ - public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func createDefault) - { - if (isSecond) - { - var webView = new WebView(); - webView.LoadUrl("https://avaloniaui.net/"); - return new NuiViewControlHandle(webView); - } - else - { - var clickCount = 0; - var button = new Button - { - Text = "Hello world" - }; - - button.Clicked += (sender, e) => - { - clickCount++; - button.Text = $"Click count {clickCount}"; - }; - - return new NuiViewControlHandle(button); - } - } -} diff --git a/samples/ControlCatalog.Tizen/Main.cs b/samples/ControlCatalog.Tizen/Main.cs deleted file mode 100644 index 2d611ef5a3..0000000000 --- a/samples/ControlCatalog.Tizen/Main.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Avalonia; -using Avalonia.Tizen; -using ElmSharp; -using SkiaSharp; -using Tizen.Applications; - -namespace ControlCatalog.Tizen; - -class Program : NuiTizenApplication -{ - protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) => - base.CustomizeAppBuilder(builder).AfterSetup(_ => - { - Pages.EmbedSample.Implementation = new EmbedSampleNuiTizen(); - }); - - static void Main(string[] args) - { - var app = new Program(); - app.Run(args); - } -} diff --git a/samples/ControlCatalog.Tizen/shared/res/Avalonia.png b/samples/ControlCatalog.Tizen/shared/res/Avalonia.png deleted file mode 100644 index ea0bb4986fcd6da94355b980dd9e6b6a6c13f02d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16599 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 diff --git a/samples/ControlCatalog.Tizen/tizen-manifest.xml b/samples/ControlCatalog.Tizen/tizen-manifest.xml deleted file mode 100644 index 50101d37ff..0000000000 --- a/samples/ControlCatalog.Tizen/tizen-manifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - Avalonia.png - - - - - - http://tizen.org/privilege/appdir.shareddata - http://tizen.org/privilege/appmanager.launch - http://tizen.org/privilege/externalstorage - http://tizen.org/privilege/externalstorage.appdata - http://tizen.org/privilege/internet - http://tizen.org/privilege/network.get - - - - http://tizen.org/feature/opengles.surfaceless_context - http://tizen.org/feature/opengles.version.2_0 - diff --git a/samples/SingleProjectSandbox/Platforms/Tizen/Main.cs b/samples/SingleProjectSandbox/Platforms/Tizen/Main.cs deleted file mode 100644 index 94e621ec25..0000000000 --- a/samples/SingleProjectSandbox/Platforms/Tizen/Main.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia; -using Avalonia.Tizen; - -namespace SingleProjectSandbox; - -internal class Program : NuiTizenApplication -{ - protected override AppBuilder CreateAppBuilder() => - App.BuildAvaloniaApp().UseTizen(); - - internal static void Main(string[] args) - { - var app = new Program(); - app.Run(args); - } -} diff --git a/samples/SingleProjectSandbox/Platforms/Tizen/shared/res/Avalonia.png b/samples/SingleProjectSandbox/Platforms/Tizen/shared/res/Avalonia.png deleted file mode 100644 index ea0bb4986fcd6da94355b980dd9e6b6a6c13f02d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16599 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 diff --git a/samples/SingleProjectSandbox/Platforms/Tizen/tizen-manifest.xml b/samples/SingleProjectSandbox/Platforms/Tizen/tizen-manifest.xml deleted file mode 100644 index 3ba13e8946..0000000000 --- a/samples/SingleProjectSandbox/Platforms/Tizen/tizen-manifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - Avalonia.png - - - - - - http://tizen.org/privilege/appdir.shareddata - http://tizen.org/privilege/appmanager.launch - http://tizen.org/privilege/externalstorage - http://tizen.org/privilege/externalstorage.appdata - http://tizen.org/privilege/internet - http://tizen.org/privilege/network.get - - - - http://tizen.org/feature/opengles.surfaceless_context - http://tizen.org/feature/opengles.version.2_0 - diff --git a/samples/SingleProjectSandbox/SingleProjectSandbox.csproj b/samples/SingleProjectSandbox/SingleProjectSandbox.csproj index bbf83d66fa..4c7c49ed3e 100644 --- a/samples/SingleProjectSandbox/SingleProjectSandbox.csproj +++ b/samples/SingleProjectSandbox/SingleProjectSandbox.csproj @@ -3,7 +3,6 @@ $(AvsCurrentTargetFramework);$(AvsCurrentAndroidTargetFramework);$(AvsCurrentBrowserTargetFramework) $(TargetFrameworks);$(AvsCurrentIOSTargetFramework) $(TargetFrameworks);$(AvsCurrentMacOSTargetFramework) - $(TargetFrameworks);$(AvsCurrentTizenTargetFramework) Exe true enable diff --git a/src/Tizen/Avalonia.Tizen/Avalonia.Tizen.csproj b/src/Tizen/Avalonia.Tizen/Avalonia.Tizen.csproj deleted file mode 100644 index 76654fc64a..0000000000 --- a/src/Tizen/Avalonia.Tizen/Avalonia.Tizen.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - $(AvsCurrentTizenTargetFramework) - $(AvsMinSupportedTizenVersion) - enable - - - - - - - - - - - - - - - - - - - - diff --git a/src/Tizen/Avalonia.Tizen/ITizenView.cs b/src/Tizen/Avalonia.Tizen/ITizenView.cs deleted file mode 100644 index 87ddba0b6b..0000000000 --- a/src/Tizen/Avalonia.Tizen/ITizenView.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Avalonia.Controls.Platform; -using Avalonia.Input; - -namespace Avalonia.Tizen; - -internal interface ITizenView -{ - Size ClientSize { get; } - double Scaling { get; } - IInputRoot InputRoot { get; set; } - INativeControlHostImpl NativeControlHost { get; } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiAvaloniaView.cs b/src/Tizen/Avalonia.Tizen/NuiAvaloniaView.cs deleted file mode 100644 index 8118ae2707..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiAvaloniaView.cs +++ /dev/null @@ -1,188 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Controls.Embedding; -using Avalonia.Controls.Platform; -using Avalonia.Input; -using Avalonia.Input.TextInput; -using Avalonia.Rendering; -using Avalonia.Rendering.Composition; -using Avalonia.Rendering.Composition.Server; -using Tizen.NUI; -using Tizen.NUI.BaseComponents; - -namespace Avalonia.Tizen; - -/// -/// Avalonia View for Tizen NUI controls -/// -public class NuiAvaloniaView : GLView, ITizenView, ITextInputMethodImpl -{ - private readonly NuiKeyboardHandler _keyboardHandler; - private readonly NuiTouchHandler _touchHandler; - private readonly NuiAvaloniaViewTextEditable _textEditor; - private TizenRenderTimer? _renderTimer; - private TopLevelImpl? _topLevelImpl; - private EmbeddableControlRoot? _topLevel; - private readonly TouchDevice _device = new(); - private ServerCompositionTarget? _compositionTargetServer; - private IInputRoot? _inputRoot; - - public INativeControlHostImpl NativeControlHost { get; } - public double Scaling => 1; - public Size ClientSize => new(Size.Width, Size.Height); - - public IInputRoot InputRoot - { - get => _inputRoot ?? throw new InvalidOperationException($"{nameof(InputRoot)} hasn't been set"); - set => _inputRoot = value; - } - - internal TopLevel TopLevel - => _topLevel ?? throw new InvalidOperationException($"{nameof(NuiAvaloniaView)} hasn't been initialized"); - - internal TopLevelImpl TopLevelImpl - => _topLevelImpl ?? throw new InvalidOperationException($"{nameof(NuiAvaloniaView)} hasn't been initialized"); - - public Control? Content - { - get => TopLevel.Content as Control; - set => TopLevel.Content = value; - } - - internal NuiAvaloniaViewTextEditable TextEditor => _textEditor; - internal NuiKeyboardHandler KeyboardHandler => _keyboardHandler; - - #region Setup - - public event Action? OnSurfaceInit; - - public NuiAvaloniaView() : base(ColorFormat.RGBA8888) - { - RenderingMode = GLRenderingMode.OnDemand; - SetGraphicsConfig(true, true, 0, GLESVersion.Version30); - RegisterGLCallbacks(GlInit, GlRenderFrame, GlTerminate); - - _textEditor = new NuiAvaloniaViewTextEditable(this); - _keyboardHandler = new NuiKeyboardHandler(this); - _touchHandler = new NuiTouchHandler(this); - NativeControlHost = new NuiNativeControlHostImpl(this); - - Layout = new CustomLayout - { - SizeUpdated = OnResized - }; - - TouchEvent += OnTouchEvent; - WheelEvent += OnWheelEvent; - } - - private void GlInit() - { - OnSurfaceInit?.Invoke(); - } - - private int GlRenderFrame() - { - if (_renderTimer == null || _compositionTargetServer == null) - return 0; - - var rev = _compositionTargetServer.Revision; - _renderTimer.ManualTick(); - return rev == _compositionTargetServer.Revision ? 0 : 1; - } - - private void GlTerminate() - { - } - - internal void Initialise() - { - _topLevelImpl = new TopLevelImpl(this, new[] { new NuiGlLayerSurface(this) }); - _topLevelImpl.Compositor.AfterCommit += RenderOnce; - TizenPlatform.ThreadingInterface.TickExecuted += RenderOnce; - - _topLevel = new(_topLevelImpl); - _topLevel.Prepare(); - _topLevel.StartRendering(); - - _compositionTargetServer = ((CompositingRenderer)((IRenderRoot)_topLevel).Renderer).CompositionTarget.Server; - - _renderTimer = (TizenRenderTimer)AvaloniaLocator.Current.GetRequiredService(); - _renderTimer.RenderTick += RenderOnce; - - OnResized(); - } - - #endregion - - #region Resize and layout - - private class CustomLayout : AbsoluteLayout - { - float _width; - float _height; - - public Action? SizeUpdated { get; set; } - - protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom) - { - var sizeChanged = _width != Owner.SizeWidth || _height != Owner.SizeHeight; - _width = Owner.SizeWidth; - _height = Owner.SizeHeight; - if (sizeChanged) - { - SizeUpdated?.Invoke(); - } - base.OnLayout(changed, left, top, right, bottom); - } - } - - protected void OnResized() - { - if (Size.Width == 0 || Size.Height == 0) - return; - - _topLevelImpl?.Resized?.Invoke(_topLevelImpl.ClientSize, WindowResizeReason.Layout); - } - - #endregion - - #region Event handlers - - private bool OnTouchEvent(object source, TouchEventArgs e) - { - _touchHandler.Handle(e); - return true; - } - - private bool OnWheelEvent(object source, WheelEventArgs e) - { - _touchHandler.Handle(e); - return true; - } - - public void SetClient(TextInputMethodClient? client) - { - _textEditor.SetClient(client); - } - - public void SetCursorRect(Rect rect) - { - } - - public void SetOptions(TextInputOptions options) => - _textEditor.SetOptions(options); - - #endregion - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _topLevel?.StopRendering(); - _topLevel?.Dispose(); - _topLevelImpl?.Dispose(); - _device.Dispose(); - } - base.Dispose(disposing); - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs b/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs deleted file mode 100644 index c7e05afc52..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs +++ /dev/null @@ -1,211 +0,0 @@ -using Avalonia.Input.TextInput; -using Tizen.NUI; -using Tizen.NUI.BaseComponents; -using Window = Tizen.NUI.Window; - -namespace Avalonia.Tizen; - -internal class NuiAvaloniaViewTextEditable -{ - private readonly NuiAvaloniaView _avaloniaView; - - private INuiTextInput TextInput => _multiline ? _multiLineTextInput : _singleLineTextInput; - private readonly NuiSingleLineTextInput _singleLineTextInput; - private readonly NuiMultiLineTextInput _multiLineTextInput; - private bool _updating; - private bool _keyboardPresented; - private bool _multiline; - - private TextInputMethodClient? _client; - - public bool IsActive => _client != null && _keyboardPresented; - - public NuiAvaloniaViewTextEditable(NuiAvaloniaView avaloniaView) - { - _avaloniaView = avaloniaView; - _singleLineTextInput = new NuiSingleLineTextInput - { - HeightResizePolicy = ResizePolicyType.Fixed, - WidthResizePolicy = ResizePolicyType.Fixed, - Size = new(1, 1), - Position = new Position(-1000, -1000), - FontSizeScale = 0.1f, - }; - - _multiLineTextInput = new NuiMultiLineTextInput - { - HeightResizePolicy = ResizePolicyType.Fixed, - WidthResizePolicy = ResizePolicyType.Fixed, - Size = new(1, 1), - Position = new Position(-1000, -1000), - FontSizeScale = 0.1f, - }; - - SetupTextInput(_singleLineTextInput); - SetupTextInput(_multiLineTextInput); - } - - private void SetupTextInput(INuiTextInput input) - { - input.Hide(); - - input.GetInputMethodContext().StatusChanged += OnStatusChanged; - input.GetInputMethodContext().EventReceived += OnEventReceived; - } - - private InputMethodContext.CallbackData OnEventReceived(object source, InputMethodContext.EventReceivedEventArgs e) - { - switch (e.EventData.EventName) - { - case InputMethodContext.EventType.Preedit: - _client?.SetPreeditText(e.EventData.PredictiveString); - break; - case InputMethodContext.EventType.Commit: - _client?.SetPreeditText(null); - _avaloniaView.TopLevelImpl.TextInput(e.EventData.PredictiveString); - break; - } - - return new InputMethodContext.CallbackData(); - } - - private void OnStatusChanged(object? sender, InputMethodContext.StatusChangedEventArgs e) - { - _keyboardPresented = e.StatusChanged; - if (!_keyboardPresented) - DettachAndHide(); - } - - internal void SetClient(TextInputMethodClient? client) - { - if (client == null || !_keyboardPresented) - DettachAndHide(); - - if (client != null) - AttachAndShow(client); - } - - internal void SetOptions(TextInputOptions options) - { - //TODO: This should be revert when Avalonia used Multiline property - _multiline = true; - //if (_multiline != options.Multiline) - //{ - // DettachAndHide(); - // _multiline = options.Multiline; - //} - - TextInput.Sensitive = options.IsSensitive; - } - - private void AttachAndShow(TextInputMethodClient client) - { - _updating = true; - try - { - TextInput.Text = client.SurroundingText; - TextInput.PrimaryCursorPosition = client.Selection.Start; - Window.Instance.GetDefaultLayer().Add((View)TextInput); - TextInput.Show(); - TextInput.EnableSelection = true; - - var inputContext = TextInput.GetInputMethodContext(); - inputContext.Activate(); - inputContext.ShowInputPanel(); - inputContext.RestoreAfterFocusLost(); - - _client = client; - client.TextViewVisualChanged += OnTextViewVisualChanged; - client.SurroundingTextChanged += OnSurroundingTextChanged; - client.SelectionChanged += OnClientSelectionChanged; - client.InputPaneActivationRequested += OnInputPaneActivationRequested; - - TextInput.SelectWholeText(); - OnClientSelectionChanged(this, EventArgs.Empty); - } - finally { _updating = false; } - } - - private void OnInputPaneActivationRequested(object? sender, EventArgs e) - { - var inputContext = TextInput.GetInputMethodContext(); - inputContext.ShowInputPanel(); - } - - private void OnClientSelectionChanged(object? sender, EventArgs e) => InvokeUpdate(client => - { - if (client.Selection.End == 0 || client.Selection.Start == client.Selection.End) - TextInput.PrimaryCursorPosition = client.Selection.Start; - else - TextInput.SelectText(client.Selection.Start, client.Selection.End); - }); - - private void OnSurroundingTextChanged(object? sender, EventArgs e) => InvokeUpdate(client => - { - TextInput.Text = client.SurroundingText; - TextInput.GetInputMethodContext().SetSurroundingText(client.SurroundingText); - OnClientSelectionChanged(sender, e); - }); - - private void OnTextViewVisualChanged(object? sender, EventArgs e) => InvokeUpdate(client => - { - TextInput.Text = client.SurroundingText; - }); - - private void DettachAndHide() - { - if (IsActive) - { - _client!.TextViewVisualChanged -= OnTextViewVisualChanged; - _client!.SurroundingTextChanged -= OnSurroundingTextChanged; - _client!.SelectionChanged -= OnClientSelectionChanged; - _client!.InputPaneActivationRequested -= OnInputPaneActivationRequested; - } - - if (Window.Instance.GetDefaultLayer().Children.Contains((View)TextInput)) - Window.Instance.GetDefaultLayer().Remove((View)TextInput); - - TextInput.Hide(); - - var inputContext = TextInput.GetInputMethodContext(); - inputContext.Deactivate(); - inputContext.HideInputPanel(); - } - - private void InvokeUpdate(Action action) - { - if (_updating || !IsActive) - return; - - _updating = true; - try - { - action(_client!); - } - finally { _updating = false; } - } -} - -internal interface INuiTextInput -{ - string Text { get; set; } - int PrimaryCursorPosition { get; set; } - bool EnableSelection { get; set; } - bool Sensitive { get; set; } - int SelectedTextStart { get; } - int SelectedTextEnd { get; } - - void Show(); - InputMethodContext GetInputMethodContext(); - void Hide(); - void SelectText(int selectedTextStart, int value); - void SelectWholeText(); -} - -public class NuiMultiLineTextInput : TextEditor, INuiTextInput -{ -} - -public class NuiSingleLineTextInput : TextField, INuiTextInput -{ -} diff --git a/src/Tizen/Avalonia.Tizen/NuiClipboardImpl.cs b/src/Tizen/Avalonia.Tizen/NuiClipboardImpl.cs deleted file mode 100644 index f13134d668..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiClipboardImpl.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Avalonia.Input; -using Avalonia.Input.Platform; -using Avalonia.Threading; -using Tizen.NUI; -using Tizen.NUI.BaseComponents; - -namespace Avalonia.Tizen; - -internal class NuiClipboardImpl : IClipboardImpl, IAsyncDataTransfer, IAsyncDataTransferItem -{ - private readonly DataFormat[] _formats; - private readonly IAsyncDataTransferItem[] _items; - private readonly TextEditor _textEditor; - - public NuiClipboardImpl() - { - _formats = [DataFormat.Text]; - _items = [this]; - - _textEditor = new TextEditor() - { - HeightResizePolicy = ResizePolicyType.Fixed, - WidthResizePolicy = ResizePolicyType.Fixed, - Position = new Position(-1000, -1000), - Size = new(1, 1) - }; - - Window.Instance.GetDefaultLayer().Add(_textEditor); - _textEditor.LowerToBottom(); - } - - IReadOnlyList IAsyncDataTransfer.Formats - => _formats; - - IReadOnlyList IAsyncDataTransferItem.Formats - => _formats; - - IReadOnlyList IAsyncDataTransfer.Items - => _items; - - public Task ClearAsync() - => SetTextAsync(string.Empty); - - public Task TryGetDataAsync() - => Task.FromResult(this); - - public async Task SetDataAsync(IAsyncDataTransfer dataTransfer) - { - var text = await dataTransfer.TryGetTextAsync(); - await SetTextAsync(text ?? string.Empty); - } - - public Task TryGetRawAsync(DataFormat format) - => DataFormat.Text.Equals(format) ? GetTextAsync() : Task.FromResult(null); - - private Task GetTextAsync() - { - _textEditor.Show(); - _textEditor.Text = ""; - - //The solution suggested by Samsung, The method PasteTo will execute async and need delay - TextUtils.PasteTo(_textEditor); - - return Task.Run(async () => - { - await Task.Delay(10); - - return await Dispatcher.UIThread.InvokeAsync(() => - { - _textEditor.Hide(); - return _textEditor.Text; - }); - }); - } - - private Task SetTextAsync(string text) - { - _textEditor.Show(); - _textEditor.Text = text; - - //The solution suggested by Samsung, The method SelectWholeText will execute async and need delay - _textEditor.SelectWholeText(); - - return Task.Run(async () => - { - await Task.Delay(10); - await Dispatcher.UIThread.InvokeAsync(() => - { - TextUtils.CopyToClipboard(_textEditor); - _textEditor.Hide(); - }); - }); - } - - void IDisposable.Dispose() - { - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiGlLayerSurface.cs b/src/Tizen/Avalonia.Tizen/NuiGlLayerSurface.cs deleted file mode 100644 index 5f4a222e3d..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiGlLayerSurface.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Avalonia.OpenGL; -using Avalonia.OpenGL.Surfaces; - -namespace Avalonia.Tizen; -internal class NuiGlLayerSurface : IGlPlatformSurface -{ - private readonly NuiAvaloniaView _nuiAvaloniaView; - - public NuiGlLayerSurface(NuiAvaloniaView nuiAvaloniaView) - { - _nuiAvaloniaView = nuiAvaloniaView; - } - - public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context) - { - var ctx = TizenPlatform.GlPlatform.Context; - if (ctx != context) - throw new InvalidOperationException("Platform surface is only usable with tha main context"); - using (ctx.MakeCurrent()) - { - return new RenderTarget(ctx, _nuiAvaloniaView); - } - } - - class RenderTarget : IGlPlatformSurfaceRenderTarget - { - private readonly GlContext _ctx; - private readonly NuiAvaloniaView _nuiAvaloniaView; - - public RenderTarget(GlContext ctx, NuiAvaloniaView nuiAvaloniaView) - { - _ctx = ctx; - _nuiAvaloniaView = nuiAvaloniaView; - } - - public void Dispose() - { - - } - - public IGlPlatformSurfaceRenderingSession BeginDraw() - { - var restoreContext = _ctx.MakeCurrent(); - return new RenderSession(_ctx, restoreContext, _nuiAvaloniaView); - } - } - - class RenderSession : IGlPlatformSurfaceRenderingSession - { - private readonly GlContext _ctx; - private readonly IDisposable _restoreContext; - - public RenderSession(GlContext ctx, IDisposable restoreContext, NuiAvaloniaView nuiAvaloniaView) - { - _ctx = ctx; - _restoreContext = restoreContext; - Size = new PixelSize((int)nuiAvaloniaView.Size.Width, (int)nuiAvaloniaView.Size.Height); - Scaling = nuiAvaloniaView.Scaling; - Context = ctx; - } - - public void Dispose() - { - _ctx.GlInterface.Finish(); - _restoreContext.Dispose(); - } - - public IGlContext Context { get; } - public PixelSize Size { get; } - public double Scaling { get; } - public bool IsYFlipped { get; } - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiGlPlatform.cs b/src/Tizen/Avalonia.Tizen/NuiGlPlatform.cs deleted file mode 100644 index d101079de5..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiGlPlatform.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Avalonia.Compatibility; -using Avalonia.OpenGL; -using Avalonia.Platform; - -namespace Avalonia.Tizen; -internal class NuiGlPlatform : IPlatformGraphics -{ - - public IPlatformGraphicsContext GetSharedContext() => Context; - - public bool UsesSharedContext => true; - public IPlatformGraphicsContext CreateContext() => throw new NotSupportedException(); - public GlContext Context { get; } - public static GlVersion GlVersion { get; } = new(GlProfileType.OpenGLES, 3, 0); - - public NuiGlPlatform() - { - const string library = "/usr/lib/driver/libGLESv2.so"; - var libGl = NativeLibraryEx.Load(library); - if (libGl == IntPtr.Zero) - throw new OpenGlException("Unable to load " + library); - var iface = new GlInterface(GlVersion, proc => - { - if (NativeLibraryEx.TryGetExport(libGl, proc, out var address)) - return address; - return default; - }); - Context = new(iface); - } -} - -class GlContext : IGlContext -{ - public GlContext(GlInterface glInterface) - { - GlInterface = glInterface; - } - - public void Dispose() - { - } - - public IDisposable MakeCurrent() - { - return this; - } - - public bool IsLost => false; - - public IDisposable EnsureCurrent() - { - return MakeCurrent(); - } - - public bool IsSharedWith(IGlContext context) => true; - public bool CanCreateSharedContext => true; - public IGlContext CreateSharedContext(IEnumerable? preferredVersions = null) - { - return this; - } - - public GlVersion Version => new GlVersion(GlProfileType.OpenGLES, 3, 0); - public GlInterface GlInterface { get; } - public int SampleCount - { - get - { - GlInterface.GetIntegerv(GlConsts.GL_SAMPLES, out var samples); - return samples; - } - } - public int StencilSize - { - get - { - GlInterface.GetIntegerv(GlConsts.GL_STENCIL_BITS, out var stencil); - return stencil; - } - } - - public object? TryGetFeature(Type featureType) => null; - - public IntPtr GetProcAddress(string procName) - { - return GlInterface.GetProcAddress(procName); - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiKeyboardHandler.cs b/src/Tizen/Avalonia.Tizen/NuiKeyboardHandler.cs deleted file mode 100644 index 52e062f6d8..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiKeyboardHandler.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Diagnostics; -using Avalonia.Input; -using Avalonia.Input.Raw; -using Avalonia.Logging; -using Avalonia.Tizen.Platform.Input; -using Tizen.NUI; -using Key = Tizen.NUI.Key; - -namespace Avalonia.Tizen; -internal class NuiKeyboardHandler -{ - private const string LogKey = "TIZENHKEY"; - - private readonly NuiAvaloniaView _view; - - public NuiKeyboardHandler(NuiAvaloniaView view) - { - _view = view; - } - - public void Handle(Window.KeyEventArgs e) - { - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Key fired {text}", e.Key.KeyPressedName); - - if (_view.TextEditor.IsActive) - return; - - if (ShouldSendKeyEvent(e, out var keyCode)) - { - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Triggering key event {text}", e.Key.KeyString); - SendKeyEvent(e, keyCode); - } - else if (e.Key.State == Key.StateType.Up && !string.IsNullOrEmpty(e.Key.KeyString)) - { - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Triggering text input {text}", e.Key.KeyString); - _view.TopLevelImpl.TextInput(e.Key.KeyString); - } - } - - private void SendKeyEvent(Window.KeyEventArgs e, Input.Key mapped) - { - var type = GetKeyEventType(e); - var modifiers = GetModifierKey(e); - var deviceType = GetDeviceType(e); - - _view.TopLevelImpl.Input?.Invoke( - new RawKeyEventArgs( - KeyboardDevice.Instance!, - e.Key.Time, - _view.InputRoot, - type, - mapped, - modifiers, - PhysicalKey.None, - deviceType, - e.Key.KeyString - )); - } - - private bool ShouldSendKeyEvent(Window.KeyEventArgs e, out Input.Key keyCode) - { - keyCode = TizenKeyboardDevice.GetSpecialKey(e.Key.KeyPressedName); - if (keyCode != Input.Key.None) - return true; - - if ((e.Key.IsCtrlModifier() || e.Key.IsAltModifier()) && !string.IsNullOrEmpty(e.Key.KeyString)) - { - var c = e.Key.KeyPressedName.Length == 1 ? e.Key.KeyPressedName[0] : (char)e.Key.KeyCode; - return (keyCode = TizenKeyboardDevice.GetAsciiKey(c)) != Input.Key.None; - } - - return false; - } - - private RawKeyEventType GetKeyEventType(Window.KeyEventArgs ev) - { - switch (ev.Key.State) - { - case Key.StateType.Down: - return RawKeyEventType.KeyDown; - case Key.StateType.Up: - return RawKeyEventType.KeyUp; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private RawInputModifiers GetModifierKey(Window.KeyEventArgs ev) - { - var modifiers = RawInputModifiers.None; - - if (ev.Key.IsShiftModifier()) - modifiers |= RawInputModifiers.Shift; - - if (ev.Key.IsAltModifier()) - modifiers |= RawInputModifiers.Alt; - - if (ev.Key.IsCtrlModifier()) - modifiers |= RawInputModifiers.Control; - - return modifiers; - } - - private KeyDeviceType GetDeviceType(Window.KeyEventArgs ev) - { - if (ev.Key.DeviceClass == DeviceClassType.Gamepad) - return KeyDeviceType.Gamepad; - - if (ev.Key.DeviceSubClass == DeviceSubClassType.Remocon) - return KeyDeviceType.Remote; - - return KeyDeviceType.Keyboard; - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiNativeControlHostImpl.cs b/src/Tizen/Avalonia.Tizen/NuiNativeControlHostImpl.cs deleted file mode 100644 index ac94dc14d7..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiNativeControlHostImpl.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using Avalonia.Controls.Platform; -using Avalonia.Platform; -using Tizen.NUI.BaseComponents; - -namespace Avalonia.Tizen; - -internal class NuiNativeControlHostImpl : INativeControlHostImpl -{ - private readonly NuiAvaloniaView _avaloniaView; - - public NuiNativeControlHostImpl(NuiAvaloniaView avaloniaView) - { - _avaloniaView = avaloniaView; - } - - public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent) => - new NuiViewControlHandle(new View()); - - public INativeControlHostControlTopLevelAttachment CreateNewAttachment(Func create) - { - var parent = new NuiViewControlHandle(_avaloniaView); - NativeControlAttachment? attachment = null; - try - { - var child = create(parent); - // It has to be assigned to the variable before property setter is called so we dispose it on exception -#pragma warning disable IDE0017 // Simplify object initialization - attachment = new NativeControlAttachment(child); -#pragma warning restore IDE0017 // Simplify object initialization - attachment.AttachedTo = this; - return attachment; - } - catch - { - attachment?.Dispose(); - throw; - } - } - - public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle) => - new NativeControlAttachment(handle); - - public bool IsCompatibleWith(IPlatformHandle handle) => - handle.HandleDescriptor == NuiViewControlHandle.ViewDescriptor; - - private class NativeControlAttachment : INativeControlHostControlTopLevelAttachment - { - private IPlatformHandle? _child; - private View? _view; - private NuiNativeControlHostImpl? _attachedTo; - - public NativeControlAttachment(IPlatformHandle child) - { - _child = child; - _view = (child as NuiViewControlHandle)?.View; - } - - [MemberNotNull(nameof(_view))] - private void CheckDisposed() - { - if (_view == null) - throw new ObjectDisposedException(nameof(NativeControlAttachment)); - } - - public void Dispose() - { - _view?.Unparent(); - _child = null; - _attachedTo = null; - _view?.Dispose(); - _view = null; - } - - public INativeControlHostImpl? AttachedTo - { - get => _attachedTo; - set - { - CheckDisposed(); - - _attachedTo = (NuiNativeControlHostImpl?)value; - if (_attachedTo == null) - { - _view.Unparent(); - } - else - { - _attachedTo._avaloniaView.Add(_view); - } - } - } - - public bool IsCompatibleWith(INativeControlHostImpl host) => host is NuiNativeControlHostImpl; - - public void HideWithSize(Size size) - { - CheckDisposed(); - if (_attachedTo == null) - return; - - _view.Hide(); - _view.Size = new global::Tizen.NUI.Size(MathF.Max(1f, (float)size.Width), Math.Max(1f, (float)size.Height)); - } - - public void ShowInBounds(Rect bounds) - { - CheckDisposed(); - if (_attachedTo == null) - throw new InvalidOperationException("The control isn't currently attached to a toplevel"); - - _view.Size = new global::Tizen.NUI.Size(MathF.Max(1f, (float)bounds.Width), Math.Max(1f, (float)bounds.Height)); - _view.Position = new global::Tizen.NUI.Position((float)bounds.X, (float)bounds.Y); - _view.Show(); - } - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiScreens.cs b/src/Tizen/Avalonia.Tizen/NuiScreens.cs deleted file mode 100644 index 0c52ffbcf9..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiScreens.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Avalonia.Platform; -using Tizen.Applications; -using Tizen.Multimedia; -using Tizen.NUI; -using Tizen.System; - -namespace Avalonia.Tizen; - -internal class NuiScreens : ScreensBase -{ - // See https://github.com/dotnet/maui/blob/8.0.70/src/Essentials/src/DeviceDisplay/DeviceDisplay.tizen.cs - internal const float BaseLogicalDpi = 160.0f; - - internal static DeviceOrientation LastDeviceOrientation { get; private set; } - - internal static int DisplayWidth => - Information.TryGetValue("http://tizen.org/feature/screen.width", out var value) ? value : 0; - - internal static int DisplayHeight => - Information.TryGetValue("http://tizen.org/feature/screen.height", out var value) ? value : 0; - - internal static int DisplayDpi => TizenRuntimePlatform.Info.Value.IsTV ? 72 : - Information.TryGetValue("http://tizen.org/feature/screen.dpi", out var value) ? value : 72; - - public NuiScreens() - { - ((CoreApplication)global::Tizen.Applications.Application.Current).DeviceOrientationChanged += (sender, args) => - { - LastDeviceOrientation = args.DeviceOrientation; - OnChanged(); - }; - } - - protected override int GetScreenCount() => 1; - - protected override IReadOnlyList GetAllScreenKeys() => [1]; - - protected override SingleTizenScreen CreateScreenFromKey(int key) - { - var screen = new SingleTizenScreen(key); - screen.Refresh(); - return screen; - } - - protected override void ScreenChanged(SingleTizenScreen screen) => screen.Refresh(); -} - -internal class SingleTizenScreen(int index) : PlatformScreen(new PlatformHandle(new IntPtr(index), nameof(SingleTizenScreen))) -{ - public void Refresh() - { - IsPrimary = index == 1; - if (IsPrimary) - { - Bounds = WorkingArea = new PixelRect(0, 0, NuiScreens.DisplayWidth, NuiScreens.DisplayHeight); - Scaling = NuiScreens.DisplayDpi / NuiScreens.BaseLogicalDpi; - - var isNaturalLandscape = Bounds.Width > Bounds.Height; - CurrentOrientation = (isNaturalLandscape, NuiScreens.LastDeviceOrientation) switch - { - (true, DeviceOrientation.Orientation_0) => ScreenOrientation.Landscape, - (true, DeviceOrientation.Orientation_90) => ScreenOrientation.Portrait, - (true, DeviceOrientation.Orientation_180) => ScreenOrientation.LandscapeFlipped, - (true, DeviceOrientation.Orientation_270) => ScreenOrientation.PortraitFlipped, - (false, DeviceOrientation.Orientation_0) => ScreenOrientation.Portrait, - (false, DeviceOrientation.Orientation_90) => ScreenOrientation.Landscape, - (false, DeviceOrientation.Orientation_180) => ScreenOrientation.PortraitFlipped, - (false, DeviceOrientation.Orientation_270) => ScreenOrientation.LandscapeFlipped, - _ => ScreenOrientation.None - }; - } - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiTizenApplication.cs b/src/Tizen/Avalonia.Tizen/NuiTizenApplication.cs deleted file mode 100644 index 2f99f2d6cd..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiTizenApplication.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; -using Tizen.NUI; -using Window = Tizen.NUI.Window; -using Avalonia.Logging; - -namespace Avalonia.Tizen; - -public class NuiTizenApplication : NUIApplication - where TApp : Application, new() -{ - private const string LogKey = "TIZENAPP"; - - private SingleViewLifetime? _lifetime; - - private class SingleViewLifetime : ISingleViewApplicationLifetime, ISingleTopLevelApplicationLifetime - { - public NuiAvaloniaView View { get; } - - public SingleViewLifetime(NuiAvaloniaView view) - { - View = view; - } - - public Control? MainView - { - get => View.Content; - set => View.Content = value; - } - - public TopLevel? TopLevel => View.TopLevel; - } - - protected virtual AppBuilder CreateAppBuilder() => AppBuilder.Configure().UseTizen(); - protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder; - - protected override void OnCreate() - { - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Creating application"); - - base.OnCreate(); - TizenThreadingInterface.MainloopContext = SynchronizationContext.Current!; - - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Setup view"); - _lifetime = new SingleViewLifetime(new NuiAvaloniaView()); - - _lifetime.View.HeightResizePolicy = ResizePolicyType.FillToParent; - _lifetime.View.WidthResizePolicy = ResizePolicyType.FillToParent; - _lifetime.View.OnSurfaceInit += ContinueSetupApplication; - - Window.Instance.RenderingBehavior = RenderingBehaviorType.Continuously; - Window.Instance.GetDefaultLayer().Add(_lifetime.View); - Window.Instance.KeyEvent += (_, e) => _lifetime?.View.KeyboardHandler.Handle(e); - } - - private void ContinueSetupApplication() - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "App builder"); - var builder = CreateAppBuilder(); - - TizenThreadingInterface.MainloopContext.Post(_ => - { - builder = CustomizeAppBuilder(builder); - builder.AfterApplicationSetup(_ => _lifetime!.View.Initialise()); - - Logger.TryGet(LogEventLevel.Debug, LogKey)?.Log(null, "Setup lifetime"); - builder.SetupWithLifetime(_lifetime!); - }, null); - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiTouchHandler.cs b/src/Tizen/Avalonia.Tizen/NuiTouchHandler.cs deleted file mode 100644 index bf3156b2f0..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiTouchHandler.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Avalonia.Input; -using Avalonia.Input.Raw; -using Tizen.NUI; -using static Tizen.NUI.BaseComponents.View; - -namespace Avalonia.Tizen; -internal class NuiTouchHandler -{ - private readonly NuiAvaloniaView _view; - public TouchDevice _device = new TouchDevice(); - - public NuiTouchHandler(NuiAvaloniaView view) - { - _view = view; - } - - private IInputRoot InputRoot => _view.InputRoot; - private static uint _nextTouchPointId = 1; - private List _knownTouches = new(); - - public void Handle(TouchEventArgs e) - { - var count = e.Touch.GetPointCount(); - for (var i = 0u; i < count; i++) - { - uint id; - if (_knownTouches.Count > i) - { - id = _knownTouches[(int)i]; - } - else - { - unchecked - { - id = _nextTouchPointId++; - } - _knownTouches.Add(id); - } - - var point = e.Touch.GetLocalPosition(i); - var state = e.Touch.GetState(i); - var timestamp = e.Touch.GetTime(); - var avaloniaState = state switch - { - PointStateType.Down => RawPointerEventType.TouchBegin, - PointStateType.Up => RawPointerEventType.TouchEnd, - PointStateType.Motion => RawPointerEventType.TouchUpdate, - PointStateType.Interrupted => RawPointerEventType.TouchCancel, - _ => RawPointerEventType.TouchUpdate - }; - - var touchEvent = new RawTouchEventArgs( - _device, - timestamp, - InputRoot, - avaloniaState, - new Point(point.X, point.Y), - RawInputModifiers.None, - id); - _view.TopLevelImpl.Input?.Invoke(touchEvent); - - if (state is PointStateType.Up or PointStateType.Interrupted) - { - _knownTouches.Remove(id); - } - } - } - - public void Handle(WheelEventArgs e) - { - var mouseWheelEvent = new RawMouseWheelEventArgs( - _device, - e.Wheel.TimeStamp, - InputRoot, - new Point(e.Wheel.Point.X, e.Wheel.Point.Y), - new Vector( - e.Wheel.Direction == 1 ? e.Wheel.Z : 0, - e.Wheel.Direction == 0 ? e.Wheel.Z : 0), - GetModifierKey(e)); - - _view.TopLevelImpl.Input?.Invoke(mouseWheelEvent); - } - - private RawInputModifiers GetModifierKey(WheelEventArgs ev) - { - var modifiers = RawInputModifiers.None; - - if (ev.Wheel.IsShiftModifier()) - modifiers |= RawInputModifiers.Shift; - - if (ev.Wheel.IsAltModifier()) - modifiers |= RawInputModifiers.Alt; - - if (ev.Wheel.IsCtrlModifier()) - modifiers |= RawInputModifiers.Control; - - return modifiers; - } -} diff --git a/src/Tizen/Avalonia.Tizen/NuiViewControlHandle.cs b/src/Tizen/Avalonia.Tizen/NuiViewControlHandle.cs deleted file mode 100644 index 66aa70ec87..0000000000 --- a/src/Tizen/Avalonia.Tizen/NuiViewControlHandle.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Avalonia.Controls.Platform; -using Tizen.NUI.BaseComponents; - -namespace Avalonia.Tizen; - -/// -/// Tizen Nui native view handle for native view attachment -/// -public class NuiViewControlHandle : INativeControlHostDestroyableControlHandle -{ - internal const string ViewDescriptor = "NuiView"; - - /// - /// Create handle with native view - /// - /// NUI Tizen native view to attach - public NuiViewControlHandle(View view) - { - View = view; - } - - /// - /// NUI Tizen View - /// - public View View { get; set; } - /// - /// NUI Tizen not supporting handle - /// - /// - public IntPtr Handle => throw new NotSupportedException(); - /// - /// Return `ViewDescriptor` all the time - /// - public string? HandleDescriptor => ViewDescriptor; - /// - /// Dispose Tizen View when it call - /// - public void Destroy() => View.Dispose(); -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/Consts.cs b/src/Tizen/Avalonia.Tizen/Platform/Consts.cs deleted file mode 100644 index 3cc6205fcc..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/Consts.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Avalonia.Tizen.Platform; -internal static class Consts -{ - public const int DpiX = 96; - public const int DpiY = 96; - public static readonly Vector Dpi = new Vector(DpiX, DpiY); - - public const string VertexShader = - "attribute mediump vec2 aPosition;\n" + - "varying mediump vec2 vTexCoord;\n" + - "uniform highp mat4 uMvpMatrix;\n" + - "uniform mediump vec3 uSize;\n" + - "varying mediump vec2 sTexCoordRect;\n" + - "void main()\n" + - "{\n" + - " gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n" + - " vTexCoord = aPosition + vec2(0.5);\n" + - "}\n"; - - public const string FragmentShader = - "#extension GL_OES_EGL_image_external:require\n" + - "uniform lowp vec4 uColor;\n" + - "varying mediump vec2 vTexCoord;\n" + - "uniform samplerExternalOES sTexture;\n" + - "void main()\n" + - "{\n" + - " gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;\n" + - "}\n"; -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/Input/TizenKeyboardDevice.cs b/src/Tizen/Avalonia.Tizen/Platform/Input/TizenKeyboardDevice.cs deleted file mode 100644 index 126c4e11e2..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/Input/TizenKeyboardDevice.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia.Input; -using Tizen.NUI.Components; -using Tizen.Uix.InputMethod; -using static System.Net.Mime.MediaTypeNames; - -namespace Avalonia.Tizen.Platform.Input; -internal class TizenKeyboardDevice : KeyboardDevice, IKeyboardDevice -{ - private static readonly Dictionary SpecialKeys = new Dictionary - { - // Media keys - { "XF86Red", Key.MediaRed }, - { "XF86Green", Key.MediaGreen }, - { "XF86Yellow", Key.MediaYellow }, - { "XF86Blue", Key.MediaBlue }, - { "XF86Info", Key.MediaInfo }, - { "XF86SimpleMenu", Key.MediaMenu }, - { "XF86Caption", Key.MediaSubtitle }, - { "XF86MTS", Key.None }, - { "XF86PictureSize", Key.None }, - { "XF86More", Key.MediaMore }, - { "XF86Search", Key.MediaSearch }, - { "XF863D", Key.None }, - { "XF86AudioRewind", Key.MediaPreviousTrack }, - { "XF86AudioPause", Key.MediaPlayPause }, - { "XF86AudioNext", Key.MediaNextTrack }, - { "XF86AudioRecord", Key.MediaRecord }, - { "XF86AudioPlay", Key.MediaPlayPause }, - { "XF86AudioStop", Key.MediaStop }, - { "XF86ChannelGuide", Key.MediaTvGuide }, - { "XF86SysMenu", Key.Apps }, - { "minus", Key.OemMinus }, - { "XF86PreviousChannel", Key.MediaPreviousChannel }, - { "XF86AudioMute", Key.VolumeMute }, - { "XF86ChannelList", Key.MediaChannelList }, - { "XF86RaiseChannel", Key.MediaChannelRaise }, - { "XF86LowerChannel", Key.MediaChannelLower }, - { "XF86AudioRaiseVolume", Key.VolumeUp }, - { "XF86AudioLowerVolume", Key.VolumeDown }, - { "XF86Display", Key.None }, - { "XF86PowerOff", Key.Sleep }, - { "XF86PlayBack", Key.MediaPlayPause }, - { "XF86Home", Key.MediaHome }, - { "XF86Back", Key.Escape }, // Back button should be mapped as Esc - { "XF86Exit", Key.Cancel }, - - { "Shift_L", Key.LeftShift }, - { "Control_L", Key.LeftCtrl }, - { "Alt_L", Key.LeftAlt }, - { "Super_L", Key.LWin }, - { "Alt_R", Key.RightAlt }, - { "Control_R", Key.RightCtrl }, - { "Shift_R", Key.RightShift }, - { "Super_R", Key.RWin }, - { "Menu", Key.Apps }, - { "Tab", Key.Tab }, - { "BackSpace", Key.Back }, - { "Return", Key.Return }, - { "Delete", Key.Delete }, - { "End", Key.End }, - { "Next", Key.Next }, - { "Prior", Key.Prior }, - { "Home", Key.Home }, - { "Insert", Key.Insert }, - { "Num_Lock", Key.NumLock }, - { "Left", Key.Left }, - { "Up", Key.Up }, - { "Right", Key.Right }, - { "Down", Key.Down }, - { "Escape", Key.Escape }, - { "Caps_Lock", Key.CapsLock }, - { "Pause", Key.Pause }, - { "Scroll_Lock", Key.Scroll }, - { "Scroll", Key.Scroll }, - - }; - - internal static Key GetSpecialKey(string key) - { - return SpecialKeys.TryGetValue(key, out var result) ? result : Key.None; - } - - internal static Key GetAsciiKey(char keyCode) => keyCode switch - { - '`' or '~' => Key.Oem7, - '0' or ')' => Key.D0, - '1' or '!' => Key.D1, - '2' or '@' => Key.D2, - '3' or '#' => Key.D3, - '4' or '$' => Key.D4, - '5' or '%' => Key.D5, - '6' or '^' => Key.D6, - '7' or '&' => Key.D7, - '8' or '*' => Key.D8, - '9' or '(' => Key.D9, - '\'' or '"' => Key.OemQuotes, - '-' or '_' => Key.OemMinus, - '=' or '+' => Key.OemPlus, - '<' or ',' => Key.OemComma, - '>' or '.' => Key.OemPeriod, - ';' or ':' => Key.OemSemicolon, - '/' or '?' => Key.OemQuestion, - '[' or '{' => Key.OemOpenBrackets, - ']' or '}' => Key.OemCloseBrackets, - '\\' or '|' => Key.OemPipe, - 'a' or 'A' => Key.A, - 'b' or 'B' => Key.B, - 'c' or 'C' => Key.C, - 'd' or 'D' => Key.D, - 'e' or 'E' => Key.E, - 'f' or 'F' => Key.F, - 'g' or 'G' => Key.G, - 'h' or 'H' => Key.H, - 'i' or 'I' => Key.I, - 'j' or 'J' => Key.J, - 'k' or 'K' => Key.K, - 'l' or 'L' => Key.L, - 'm' or 'M' => Key.M, - 'n' or 'N' => Key.N, - 'o' or 'O' => Key.O, - 'p' or 'P' => Key.P, - 'q' or 'Q' => Key.Q, - 'r' or 'R' => Key.R, - 's' or 'S' => Key.S, - 't' or 'T' => Key.T, - 'u' or 'U' => Key.U, - 'v' or 'V' => Key.V, - 'w' or 'W' => Key.W, - 'x' or 'X' => Key.X, - 'y' or 'Y' => Key.Y, - 'z' or 'Z' => Key.Z, - _ => Key.None - }; -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/Interop/Strucs.cs b/src/Tizen/Avalonia.Tizen/Platform/Interop/Strucs.cs deleted file mode 100644 index 0d02360f08..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/Interop/Strucs.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Avalonia.Tizen.Platform.Interop; - -struct TexturedQuadVertex -{ - public Vec2 position; -}; - -[StructLayout(LayoutKind.Sequential)] -struct Vec2 -{ - float x; - float y; - public Vec2(float xIn, float yIn) - { - x = xIn; - y = yIn; - } -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/Permissions.cs b/src/Tizen/Avalonia.Tizen/Platform/Permissions.cs deleted file mode 100644 index 190cfa18e7..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/Permissions.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Security; -using Tizen.Applications; -using Tizen.Security; - -namespace Avalonia.Tizen.Platform; -internal class Permissions -{ - public record Privilege (string Path, bool IsRuntime); - - public static readonly Privilege InternetPrivilege = new("http://tizen.org/privilege/internet", false); - public static readonly Privilege NetworkPrivilege = new("http://tizen.org/privilege/network.get", false); - public static readonly Privilege CameraPrivilege = new("http://tizen.org/privilege/camera", false); - public static readonly Privilege ContactReadPrivilege = new("http://tizen.org/privilege/contact.read", true); - public static readonly Privilege ContactWritePrivilege = new("http://tizen.org/privilege/contact.write", true); - public static readonly Privilege LedPrivilege = new("http://tizen.org/privilege/led", false); - public static readonly Privilege AppManagerLaunchPrivilege = new("http://tizen.org/privilege/appmanager.launch", false); - public static readonly Privilege LocationPrivilege = new("http://tizen.org/privilege/location", true); - public static readonly Privilege MapServicePrivilege = new("http://tizen.org/privilege/mapservice", false); - public static readonly Privilege MediaStoragePrivilege = new("http://tizen.org/privilege/mediastorage", true); - public static readonly Privilege RecorderPrivilege = new("http://tizen.org/privilege/recorder", false); - public static readonly Privilege HapticPrivilege = new("http://tizen.org/privilege/haptic", false); - public static readonly Privilege LaunchPrivilege = new("http://tizen.org/privilege/appmanager.launch", false); - - public static readonly Privilege[] NetworkPrivileges = { InternetPrivilege, NetworkPrivilege }; - public static readonly Privilege[] MapsPrivileges = { InternetPrivilege, MapServicePrivilege, NetworkPrivilege }; - - public static Package CurrentPackage - { - get - { - var packageId = global::Tizen.Applications.Application.Current.ApplicationInfo.PackageId; - return PackageManager.GetPackage(packageId); - } - } - - public static bool IsPrivilegeDeclared(string? tizenPrivilege) - { - var tizenPrivileges = tizenPrivilege; - - if (tizenPrivileges == null || !tizenPrivileges.Any()) - return false; - - var package = CurrentPackage; - - if (!package.Privileges.Contains(tizenPrivilege)) - return false; - - return true; - } - - public static void EnsureDeclared(params Privilege[]? requiredPrivileges) - { - if (requiredPrivileges?.Any() != true) - return; - - foreach (var (tizenPrivilege, _) in requiredPrivileges) - { - if (!IsPrivilegeDeclared(tizenPrivilege)) - throw new SecurityException($"You need to declare the privilege: `{tizenPrivilege}` in your tizen-manifest.xml"); - } - } - - public static Task CheckPrivilegeAsync(params Privilege[]? requiredPrivileges) => CheckPrivilegeAsync(requiredPrivileges, false); - public static Task RequestPrivilegeAsync(params Privilege[]? requiredPrivileges) => CheckPrivilegeAsync(requiredPrivileges, true); - private static async Task CheckPrivilegeAsync(Privilege[]? requiredPrivileges, bool ask) - { - var ret = global::Tizen.System.Information.TryGetValue("http://tizen.org/feature/profile", out string profile); - if (!ret || (ret && (!profile.Equals("mobile") || !profile.Equals("wearable")))) - { - return true; - } - - if (requiredPrivileges == null || !requiredPrivileges.Any()) - return true; - - EnsureDeclared(); - - var tizenPrivileges = requiredPrivileges.Where(p => p.IsRuntime); - - foreach (var (tizenPrivilege, _) in tizenPrivileges) - { - var checkResult = PrivacyPrivilegeManager.CheckPermission(tizenPrivilege); - if (checkResult == CheckResult.Ask) - { - if (ask) - { - var tcs = new TaskCompletionSource(); - PrivacyPrivilegeManager.GetResponseContext(tizenPrivilege) - .TryGetTarget(out var context); - - void OnResponseFetched(object? sender, RequestResponseEventArgs e) - { - tcs.TrySetResult(e.result == RequestResult.AllowForever); - } - - if (context != null) - { - context.ResponseFetched += OnResponseFetched; - PrivacyPrivilegeManager.RequestPermission(tizenPrivilege); - var result = await tcs.Task; - context.ResponseFetched -= OnResponseFetched; - if (result) - continue; - } - } - return false; - } - else if (checkResult == CheckResult.Deny) - { - return false; - } - } - return true; - } -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/TizenLauncher.cs b/src/Tizen/Avalonia.Tizen/Platform/TizenLauncher.cs deleted file mode 100644 index 075e977ec2..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/TizenLauncher.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Avalonia.Platform.Storage; -using Avalonia.Tizen.Platform; -using Tizen.Applications; - -namespace Avalonia.Tizen; - -internal class TizenLauncher : ILauncher -{ - public async Task LaunchUriAsync(Uri uri) - { - if (uri is null) - { - throw new ArgumentNullException(nameof(uri)); - } - - if (!uri.IsAbsoluteUri) - { - return false; - } - - if (!await Permissions.RequestPrivilegeAsync(Permissions.LaunchPrivilege)) - { - return false; - } - - var appControl = new AppControl - { - Operation = AppControlOperations.ShareText, - Uri = uri.AbsoluteUri - }; - - if (uri.AbsoluteUri.StartsWith("geo:")) - appControl.Operation = AppControlOperations.Pick; - else if (uri.AbsoluteUri.StartsWith("http")) - appControl.Operation = AppControlOperations.View; - else if (uri.AbsoluteUri.StartsWith("mailto:")) - appControl.Operation = AppControlOperations.Compose; - else if (uri.AbsoluteUri.StartsWith("sms:")) - appControl.Operation = AppControlOperations.Compose; - else if (uri.AbsoluteUri.StartsWith("tel:")) - appControl.Operation = AppControlOperations.Dial; - - AppControl.SendLaunchRequest(appControl); - - return true; - } - - public async Task LaunchFileAsync(IStorageItem storageItem) - { - if (storageItem is null) - { - throw new ArgumentNullException(nameof(storageItem)); - } - - if (!await Permissions.RequestPrivilegeAsync(Permissions.LaunchPrivilege)) - { - return false; - } - - var appControl = new AppControl - { - Operation = AppControlOperations.View, - Mime = "*/*", - Uri = "file://" + storageItem.Path, - }; - - AppControl.SendLaunchRequest(appControl); - - return true; - } -} diff --git a/src/Tizen/Avalonia.Tizen/Platform/TizenPlatformSettings.cs b/src/Tizen/Avalonia.Tizen/Platform/TizenPlatformSettings.cs deleted file mode 100644 index 066f4ac5fe..0000000000 --- a/src/Tizen/Avalonia.Tizen/Platform/TizenPlatformSettings.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using Avalonia.Platform; -using Tizen.NUI; - -namespace Avalonia.Tizen.Platform; - -internal class TizenPlatformSettings : DefaultPlatformSettings -{ - -} diff --git a/src/Tizen/Avalonia.Tizen/Stubs.cs b/src/Tizen/Avalonia.Tizen/Stubs.cs deleted file mode 100644 index 70bc8f4953..0000000000 --- a/src/Tizen/Avalonia.Tizen/Stubs.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Avalonia.Input; -using Avalonia.Platform; - -namespace Avalonia.Tizen; - -internal class WindowingPlatformStub : IWindowingPlatform -{ - public IWindowImpl CreateWindow() => throw new NotSupportedException(); - - public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException(); - - public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow(); - - public ITrayIconImpl? CreateTrayIcon() => null; -} - -internal class PlatformIconLoaderStub : IPlatformIconLoader -{ - public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) - { - using (var stream = new MemoryStream()) - { - bitmap.Save(stream); - return LoadIcon(stream); - } - } - - public IWindowIconImpl LoadIcon(Stream stream) - { - var ms = new MemoryStream(); - stream.CopyTo(ms); - return new IconStub(ms); - } - - public IWindowIconImpl LoadIcon(string fileName) - { - using (var file = File.Open(fileName, FileMode.Open)) - return LoadIcon(file); - } -} - -internal class IconStub : IWindowIconImpl -{ - private readonly MemoryStream _ms; - - public IconStub(MemoryStream stream) - { - _ms = stream; - } - - public void Save(Stream outputStream) - { - _ms.Position = 0; - _ms.CopyTo(outputStream); - } -} - -internal class CursorFactoryStub : ICursorFactory -{ - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorImplStub(); - ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType) => new CursorImplStub(); - - private class CursorImplStub : ICursorImpl - { - public void Dispose() { } - } -} diff --git a/src/Tizen/Avalonia.Tizen/TizenApplicationExtensions.cs b/src/Tizen/Avalonia.Tizen/TizenApplicationExtensions.cs deleted file mode 100644 index f1ee66a494..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenApplicationExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Reflection; -using Avalonia.Platform; - -namespace Avalonia.Tizen; - -/// -/// Extension to setup app builder with tizen backend -/// -public static class TizenApplicationExtensions -{ - /// - /// Use tizen builder to setup tizen sub system - /// - /// Avalonia App Builder - /// Return same builder - public static AppBuilder UseTizen(this AppBuilder builder) - { - return builder - .UseTizenRuntimePlatformSubsystem() - .UseWindowingSubsystem(TizenPlatform.Initialize, "Tizen") - .UseSkia(); - } -} diff --git a/src/Tizen/Avalonia.Tizen/TizenPlatform.cs b/src/Tizen/Avalonia.Tizen/TizenPlatform.cs deleted file mode 100644 index ff083389e3..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenPlatform.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Avalonia.Input; -using Avalonia.Input.Platform; -using Avalonia.Platform; -using Avalonia.Rendering; -using Avalonia.Rendering.Composition; -using Avalonia.Tizen.Platform.Input; -using Avalonia.Tizen.Platform; - -namespace Avalonia.Tizen; - -internal class TizenPlatform -{ - public static readonly TizenPlatform Instance = new(); - - private static NuiGlPlatform? s_glPlatform; - private static Compositor? s_compositor; - - internal static NuiGlPlatform GlPlatform - { - get => s_glPlatform ?? throw new InvalidOperationException($"{nameof(TizenPlatform)} hasn't been initialized"); - private set => s_glPlatform = value; - } - - internal static Compositor Compositor - { - get => s_compositor ?? throw new InvalidOperationException($"{nameof(TizenPlatform)} hasn't been initialized"); - private set => s_compositor = value; - } - - internal static TizenThreadingInterface ThreadingInterface { get; } = new(); - - public static void Initialize() - { - AvaloniaLocator.CurrentMutable - .Bind().ToTransient() - .Bind().ToConstant(new WindowingPlatformStub()) - .Bind().ToSingleton() - .Bind().ToSingleton() - .Bind().ToConstant(ThreadingInterface) - .Bind().ToSingleton() - .Bind().ToConstant(new TizenRenderTimer()) - .Bind().ToSingleton() - .Bind().ToConstant(new KeyGestureFormatInfo(new Dictionary() { })) - .Bind().ToConstant(GlPlatform = new NuiGlPlatform()); - - Compositor = new Compositor(AvaloniaLocator.Current.GetService()); - } -} diff --git a/src/Tizen/Avalonia.Tizen/TizenRenderTimer.cs b/src/Tizen/Avalonia.Tizen/TizenRenderTimer.cs deleted file mode 100644 index 7f384dca0e..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenRenderTimer.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Diagnostics; -using Avalonia.Rendering; -using Tizen.Account.AccountManager; -using Tizen.System; - -namespace Avalonia.Tizen; -internal class TizenRenderTimer : IRenderTimer -{ - private readonly Stopwatch _st = Stopwatch.StartNew(); - private Timer _timer; - - public bool RunsInBackground => true; - - public event Action? Tick; - public event Action? RenderTick; - - public TizenRenderTimer() - { - _timer = new Timer(TimerTick, null, 16, 16); - Display.StateChanged += Display_StateChanged; - } - - private void TimerTick(object? state) - { - RenderTick?.Invoke(); - } - - private void Display_StateChanged(object? sender, DisplayStateChangedEventArgs e) - { - if (e.State == DisplayState.Off) - { - _timer.Change(Timeout.Infinite, Timeout.Infinite); - } - else - { - _timer.Change(16, 16); - } - } - - internal void ManualTick() - { - Tick?.Invoke(_st.Elapsed); - } -} diff --git a/src/Tizen/Avalonia.Tizen/TizenRuntimePlatform.cs b/src/Tizen/Avalonia.Tizen/TizenRuntimePlatform.cs deleted file mode 100644 index f806a03d95..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenRuntimePlatform.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Reflection; -using Avalonia.Platform; - -namespace Avalonia.Tizen; - -internal static class TizenRuntimePlatformServices -{ - public static AppBuilder UseTizenRuntimePlatformSubsystem(this AppBuilder builder) - { - builder.UseRuntimePlatformSubsystem(() => Register(builder.ApplicationType?.Assembly), nameof(TizenRuntimePlatform)); - return builder; - } - - public static void Register(Assembly? assembly = null) - { - AssetLoader.RegisterResUriParsers(); - AvaloniaLocator.CurrentMutable - .Bind().ToSingleton() - .Bind().ToConstant(new StandardAssetLoader(assembly)); - } -} - -internal class TizenRuntimePlatform : StandardRuntimePlatform -{ - public static readonly Lazy Info = new(() => - { - global::Tizen.System.Information.TryGetValue("http://tizen.org/feature/profile", out string profile); - - return new RuntimePlatformInfo - { - IsMobile = profile.Equals("mobile", StringComparison.OrdinalIgnoreCase), - IsTV = profile.Equals("tv", StringComparison.OrdinalIgnoreCase), - IsDesktop = false - }; - }); - - public override RuntimePlatformInfo GetRuntimeInfo() => Info.Value; -} diff --git a/src/Tizen/Avalonia.Tizen/TizenStorageProvider.cs b/src/Tizen/Avalonia.Tizen/TizenStorageProvider.cs deleted file mode 100644 index 444d896fc8..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenStorageProvider.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System.Security; -using Avalonia.Platform.Storage; -using Avalonia.Platform.Storage.FileIO; -using Avalonia.Tizen.Platform; -using Tizen.Applications; - -namespace Avalonia.Tizen; -internal class TizenStorageProvider : IStorageProvider -{ - public bool CanOpen => true; - - public bool CanSave => false; - - public bool CanPickFolder => false; - - public Task OpenFileBookmarkAsync(string bookmark) - { - return Task.FromException( - new PlatformNotSupportedException("Bookmark is not supported by Tizen")); - } - - private static async Task CheckPermission() - { - Permissions.EnsureDeclared(Permissions.AppManagerLaunchPrivilege); - if (await Permissions.RequestPrivilegeAsync(Permissions.MediaStoragePrivilege) == false) - { - throw new SecurityException("Application doesn't have storage permission."); - } - } - - public async Task> OpenFilePickerAsync(FilePickerOpenOptions options) - { - await CheckPermission(); - - var tcs = new TaskCompletionSource>(); - -#pragma warning disable CS8603 // Possible null reference return. - var fileType = options.FileTypeFilter? - .Where(w => w.MimeTypes != null) - .SelectMany(s => s.MimeTypes); -#pragma warning restore CS8603 // Possible null reference return. - - var appControl = new AppControl - { - Operation = AppControlOperations.Pick, - Mime = fileType?.Any() == true - ? fileType.Aggregate((o, n) => o + ";" + n) - : "*/*" - }; - appControl.ExtraData.Add(AppControlData.SectionMode, options.AllowMultiple ? "multiple" : "single"); - if (options.SuggestedStartLocation?.Path is { } startupPath) - appControl.ExtraData.Add(AppControlData.Path, startupPath.ToString()); - appControl.LaunchMode = AppControlLaunchMode.Single; - - var fileResults = new List(); - - AppControl.SendLaunchRequest(appControl, (_, reply, result) => - { - if (result == AppControlReplyResult.Succeeded) - { - if (reply.ExtraData.Count() > 0) - { - var selectedFiles = reply.ExtraData.Get>(AppControlData.Selected).ToList(); - fileResults.AddRange(selectedFiles.Select(f => new BclStorageFile(new(f)))); - } - } - - tcs.TrySetResult(fileResults); - }); - - return await tcs.Task; - } - - public Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) - { - return Task.FromException>( - new PlatformNotSupportedException("Open folder is not supported by Tizen")); - } - - public Task OpenFolderBookmarkAsync(string bookmark) - { - return Task.FromException( - new PlatformNotSupportedException("Open folder is not supported by Tize")); - } - - public Task SaveFilePickerAsync(FilePickerSaveOptions options) - { - return Task.FromException( - new PlatformNotSupportedException("Save file picker is not supported by Tizen")); - } - - public async Task TryGetFileFromPathAsync(Uri filePath) - { - await CheckPermission(); - - if (filePath is not { IsAbsoluteUri: true, Scheme: "file" }) - { - throw new ArgumentException("File path is expected to be an absolute link with \"file\" scheme."); - } - - var path = Path.Combine(global::Tizen.Applications.Application.Current.DirectoryInfo.Resource, filePath.AbsolutePath); - var file = new FileInfo(path); - if (!file.Exists) - { - return null; - } - - return new BclStorageFile(file); - } - - public async Task TryGetFolderFromPathAsync(Uri folderPath) - { - if (folderPath is null) - { - throw new ArgumentNullException(nameof(folderPath)); - } - - await CheckPermission(); - - if (folderPath is not { IsAbsoluteUri: true, Scheme: "file" }) - { - throw new ArgumentException("File path is expected to be an absolute link with \"file\" scheme."); - } - - var path = Path.Combine(global::Tizen.Applications.Application.Current.DirectoryInfo.Resource, folderPath.AbsolutePath); - var directory = new System.IO.DirectoryInfo(path); - if (!directory.Exists) - return null; - - return new BclStorageFolder(directory); - } - - public Task TryGetWellKnownFolderAsync(WellKnownFolder wellKnownFolder) - { - var folder = wellKnownFolder switch - { - WellKnownFolder.Desktop => null, - WellKnownFolder.Documents => global::Tizen.Applications.Application.Current.DirectoryInfo.Data, - WellKnownFolder.Downloads => global::Tizen.Applications.Application.Current.DirectoryInfo.SharedData, - WellKnownFolder.Music => null, - WellKnownFolder.Pictures => null, - WellKnownFolder.Videos => null, - _ => throw new ArgumentOutOfRangeException(nameof(wellKnownFolder), wellKnownFolder, null), - }; - - if (folder == null) - return Task.FromResult(null); - - var storageFolder = new BclStorageFolder(new System.IO.DirectoryInfo(folder)); - return Task.FromResult(storageFolder); - } -} diff --git a/src/Tizen/Avalonia.Tizen/TizenThreadingInterface.cs b/src/Tizen/Avalonia.Tizen/TizenThreadingInterface.cs deleted file mode 100644 index efd703c1aa..0000000000 --- a/src/Tizen/Avalonia.Tizen/TizenThreadingInterface.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Avalonia.Platform; -using Avalonia.Threading; - -namespace Avalonia.Tizen; -internal class TizenThreadingInterface : IPlatformThreadingInterface -{ - internal event Action? TickExecuted; - private bool _signaled; - - private static SynchronizationContext? s_mainloopContext; - - internal static SynchronizationContext MainloopContext - { - get => s_mainloopContext ?? throw new InvalidOperationException($"{nameof(MainloopContext)} hasn't been set"); - set => s_mainloopContext = value; - } - - public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) - { - return new Timer(_ => - { - EnsureInvokeOnMainThread(tick); - }, null, interval, interval); - } - - private void EnsureInvokeOnMainThread(Action action) - { - if (SynchronizationContext.Current != null) - action(); - else - MainloopContext.Post(static arg => ((Action)arg!).Invoke(), action); - } - - public void Signal(DispatcherPriority prio) - { - if (_signaled) - return; - - _signaled = true; - var interval = TimeSpan.FromMilliseconds(1); - - IDisposable? disp = null; - disp = new Timer(_ => - { - _signaled = false; - disp?.Dispose(); - - EnsureInvokeOnMainThread(() => Signaled?.Invoke(prio)); - }, null, interval, interval); - } - - public bool CurrentThreadIsLoopThread => SynchronizationContext.Current != null; - public event Action? Signaled; -} diff --git a/src/Tizen/Avalonia.Tizen/TopLevelImpl.cs b/src/Tizen/Avalonia.Tizen/TopLevelImpl.cs deleted file mode 100644 index 13bc86cb7e..0000000000 --- a/src/Tizen/Avalonia.Tizen/TopLevelImpl.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Controls.Platform; -using Avalonia.Input; -using Avalonia.Input.Platform; -using Avalonia.Input.Raw; -using Avalonia.Input.TextInput; -using Avalonia.Platform; -using Avalonia.Platform.Storage; -using Avalonia.Rendering.Composition; -using Avalonia.Tizen.Platform.Input; - -namespace Avalonia.Tizen; - -internal class TopLevelImpl : ITopLevelImpl -{ - private readonly ITizenView _view; - private readonly IClipboard _clipboard; - private readonly IStorageProvider _storageProvider; - private readonly NuiScreens _screen; - - public TopLevelImpl(ITizenView view, IEnumerable surfaces) - { - _view = view; - Surfaces = surfaces; - - _storageProvider = new TizenStorageProvider(); - _clipboard = new Clipboard(new NuiClipboardImpl()); - _screen = new NuiScreens(); - } - - public double DesktopScaling => RenderScaling; - public IPlatformHandle? Handle { get; } - - public Size ClientSize => _view.ClientSize; - - public Size? FrameSize => null; - - public double RenderScaling => 1; - - public IEnumerable Surfaces { get; set; } - - public Action? Input { get; set; } - public Action? Paint { get; set; } - public Action? Resized { get; set; } - public Action? ScalingChanged { get; set; } - public Action? TransparencyLevelChanged { get; set; } - - public Compositor Compositor => TizenPlatform.Compositor; - - public Action? Closed { get; set; } - public Action? LostFocus { get; set; } - - public WindowTransparencyLevel TransparencyLevel { get; set; } - - public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(); - public IPopupImpl? CreatePopup() - { - return null; - } - - public void Dispose() - { - // - } - - public Point PointToClient(PixelPoint point) => new Point(point.X, point.Y); - - public PixelPoint PointToScreen(Point point) => new PixelPoint((int)point.X, (int)point.Y); - - public void SetCursor(ICursorImpl? cursor) - { - // - } - - public void SetFrameThemeVariant(PlatformThemeVariant themeVariant) - { - // - } - - public void SetInputRoot(IInputRoot inputRoot) - { - _view.InputRoot = inputRoot; - } - - public void SetTransparencyLevelHint(IReadOnlyList transparencyLevels) - { - // - } - - public object? TryGetFeature(Type featureType) - { - if (featureType == typeof(IStorageProvider)) - { - return _storageProvider; - } - - if (featureType == typeof(ITextInputMethodImpl)) - { - return _view; - } - - if (featureType == typeof(INativeControlHostImpl)) - { - return _view.NativeControlHost; - } - - if (featureType == typeof(IClipboard)) - { - return _clipboard; - } - - if (featureType == typeof(ILauncher)) - { - return new TizenLauncher(); - } - - if (featureType == typeof(IScreenImpl)) - { - return _screen; - } - - return null; - } - - internal void TextInput(string text) - { - if (Input == null) return; - var args = new RawTextInputEventArgs(TizenKeyboardDevice.Instance!, (ulong)DateTime.Now.Ticks, _view.InputRoot, text); - - Input(args); - } -}