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 ea0bb4986f..0000000000 Binary files a/samples/ControlCatalog.Tizen/shared/res/Avalonia.png and /dev/null differ 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 ea0bb4986f..0000000000 Binary files a/samples/SingleProjectSandbox/Platforms/Tizen/shared/res/Avalonia.png and /dev/null differ 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); - } -}