From 20a28a42215ecf15affa8836a892437f0c8f1675 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 27 Oct 2022 16:43:08 +0200 Subject: [PATCH 1/3] Dispose empty sets and try/catch exceptions (#10955) Workaround for https://github.com/xamarin/xamarin-macios/issues/13704 --- .../src/Platform/iOS/ApplicationExtensions.cs | 20 +++++++++---- .../src/Platform/WindowStateManager.ios.cs | 30 +++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/Core/src/Platform/iOS/ApplicationExtensions.cs b/src/Core/src/Platform/iOS/ApplicationExtensions.cs index cdaff59c07d6..41683e290f83 100644 --- a/src/Core/src/Platform/iOS/ApplicationExtensions.cs +++ b/src/Core/src/Platform/iOS/ApplicationExtensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Runtime.Versioning; using Foundation; using Microsoft.Extensions.Logging; @@ -57,14 +58,23 @@ public static void CreatePlatformWindow(this IUIWindowSceneDelegate sceneDelegat dicts.Add(session.UserInfo); if (session.StateRestorationActivity?.UserInfo is not null) dicts.Add(session.StateRestorationActivity.UserInfo); - if (connectionOptions.UserActivities is not null) + try { - foreach (var u in connectionOptions.UserActivities) + using var activities = connectionOptions.UserActivities; + if (activities is not null) { - if (u is NSUserActivity userActivity && userActivity.UserInfo is not null) - dicts.Add(userActivity.UserInfo); + foreach (var u in activities) + { + if (u is NSUserActivity userActivity && userActivity.UserInfo is not null) + dicts.Add(userActivity.UserInfo); + } } } + catch (InvalidCastException) + { + // HACK: Workaround for https://github.com/xamarin/xamarin-macios/issues/13704 + // This only throws if the collection is empty. + } var window = CreatePlatformWindow(application, scene as UIWindowScene, dicts.ToArray()); if (window is not null) diff --git a/src/Essentials/src/Platform/WindowStateManager.ios.cs b/src/Essentials/src/Platform/WindowStateManager.ios.cs index b03f794ac24c..16e64f18a1bf 100644 --- a/src/Essentials/src/Platform/WindowStateManager.ios.cs +++ b/src/Essentials/src/Platform/WindowStateManager.ios.cs @@ -101,9 +101,18 @@ public void Init(Func? getCurrentUIViewController) => // if we have scene support, use that if (OperatingSystem.IsIOSVersionAtLeast(13) || OperatingSystem.IsMacCatalystVersionAtLeast(13)) { - var scenes = UIApplication.SharedApplication.ConnectedScenes; - var windowScene = scenes.ToArray().FirstOrDefault(); - return windowScene?.Windows.FirstOrDefault(); + try + { + using var scenes = UIApplication.SharedApplication.ConnectedScenes; + var windowScene = scenes.ToArray().FirstOrDefault(); + return windowScene?.Windows.FirstOrDefault(); + } + catch (InvalidCastException) + { + // HACK: Workaround for https://github.com/xamarin/xamarin-macios/issues/13704 + // This only throws if the collection is empty. + return null; + } } // use the windows property (up to 13.0) @@ -115,9 +124,18 @@ public void Init(Func? getCurrentUIViewController) => // if we have scene support, use that if (OperatingSystem.IsIOSVersionAtLeast(13) || OperatingSystem.IsMacCatalystVersionAtLeast(13)) { - var scenes = UIApplication.SharedApplication.ConnectedScenes; - var windowScene = scenes.ToArray().FirstOrDefault(); - return windowScene?.Windows; + try + { + using var scenes = UIApplication.SharedApplication.ConnectedScenes; + var windowScene = scenes.ToArray().FirstOrDefault(); + return windowScene?.Windows; + } + catch (InvalidCastException) + { + // HACK: Workaround for https://github.com/xamarin/xamarin-macios/issues/13704 + // This only throws if the collection is empty. + return null; + } } // use the windows property (up to 15.0) From 7c62683c9790af5cbfba5e2d05fde64aa5cb7b35 Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Fri, 4 Nov 2022 01:15:01 +0900 Subject: [PATCH 2/3] [Tizen] Add Shell FlyoutBackDrop (#11027) --- .../Core/Handlers/Shell/Tizen/ShellView.cs | 22 ++++++++++++++++--- .../PublicAPI/net-tizen/PublicAPI.Shipped.txt | 3 ++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Controls/src/Core/Handlers/Shell/Tizen/ShellView.cs b/src/Controls/src/Core/Handlers/Shell/Tizen/ShellView.cs index 35c0464bff77..332e4c5e62f0 100644 --- a/src/Controls/src/Core/Handlers/Shell/Tizen/ShellView.cs +++ b/src/Controls/src/Core/Handlers/Shell/Tizen/ShellView.cs @@ -1,7 +1,6 @@ #nullable enable using System; -using System.Collections.Generic; using Microsoft.Maui.Controls.Handlers; using Microsoft.Maui.Controls.Handlers.Items; using Microsoft.Maui.Graphics; @@ -34,6 +33,8 @@ public class ShellView : ViewGroup, IAppearanceObserver, IFlyoutBehaviorObserver ShellItemHandler? _currentItemHandler; + WrapperView? _backdropView; + bool _isOpen; protected Shell? Element { get; set; } @@ -44,7 +45,9 @@ public class ShellView : ViewGroup, IAppearanceObserver, IFlyoutBehaviorObserver protected bool HeaderOnMenu => _headerBehavior == FlyoutHeaderBehavior.Scroll || _headerBehavior == FlyoutHeaderBehavior.CollapseOnScroll; - protected NColor DefaultBackgroundCorlor = NColor.White; + public readonly NColor DefaultBackgroundColor = NColor.White; + + public readonly NColor DefaultBackdropColor = new NColor(0.1f, 0.1f, 0.1f, 0.5f); public event EventHandler? Toggled; @@ -123,7 +126,7 @@ public void UpdateFlyout(IView? flyout) public void UpdateBackgroundColor(GColor? color) { - _navigationView.BackgroundColor = color?.ToNUIColor() ?? DefaultBackgroundCorlor; + _navigationView.BackgroundColor = color?.ToNUIColor() ?? DefaultBackgroundColor; } public void UpdateCurrentItem(ShellItem newItem, bool animate = true) @@ -200,6 +203,19 @@ public void UpdateItems() public void UpdateFlyoutBackDrop(Brush backdrop) { + if (_backdropView == null) + { + _backdropView = new WrapperView() + { + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + BackgroundColor = DefaultBackdropColor + }; + _navigationDrawer.Backdrop = _backdropView; + } + + if (!backdrop.IsEmpty) + _backdropView.UpdateBackground(backdrop); } public void SetToolbar(MauiToolbar toolbar) diff --git a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt index ac9b3afdb7ff..8e4ffa6e4d28 100644 --- a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt @@ -1695,7 +1695,6 @@ Microsoft.Maui.Controls.Platform.ShellSectionView.MauiContext.set -> void Microsoft.Maui.Controls.Platform.ShellSectionView.ShellSection.get -> Microsoft.Maui.Controls.ShellSection! Microsoft.Maui.Controls.Platform.ShellSectionView.ShellSectionView(Microsoft.Maui.Controls.ShellSection! section, Microsoft.Maui.IMauiContext! context) -> void Microsoft.Maui.Controls.Platform.ShellView -Microsoft.Maui.Controls.Platform.ShellView.DefaultBackgroundCorlor -> Tizen.NUI.Color! Microsoft.Maui.Controls.Platform.ShellView.Element.get -> Microsoft.Maui.Controls.Shell? Microsoft.Maui.Controls.Platform.ShellView.Element.set -> void Microsoft.Maui.Controls.Platform.ShellView.HeaderOnMenu.get -> bool @@ -3153,6 +3152,8 @@ override sealed Microsoft.Maui.Controls.PlatformBehavior.O override sealed Microsoft.Maui.Controls.PlatformBehavior.OnAttachedTo(TView! bindable) -> void override sealed Microsoft.Maui.Controls.PlatformBehavior.OnDetachingFrom(Microsoft.Maui.Controls.BindableObject! bindable) -> void override sealed Microsoft.Maui.Controls.PlatformBehavior.OnDetachingFrom(TView! bindable) -> void +readonly Microsoft.Maui.Controls.Platform.ShellView.DefaultBackdropColor -> Tizen.NUI.Color! +readonly Microsoft.Maui.Controls.Platform.ShellView.DefaultBackgroundColor -> Tizen.NUI.Color! static Microsoft.Maui.Controls.AbsoluteLayout.AutoSize -> double static Microsoft.Maui.Controls.Application.AccentColor.get -> Microsoft.Maui.Graphics.Color? static Microsoft.Maui.Controls.Application.AccentColor.set -> void From b99e121790e2d170dbbb1cc1b2f191210de5584d Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Fri, 4 Nov 2022 11:58:21 +0900 Subject: [PATCH 3/3] [Tizen] Add handing Label.TextType --- .../Extensions/FormattedStringExtensions.cs | 73 +++++++++++++++++++ .../Tizen/Extensions/TextExtensions.cs | 33 +++++++-- .../PublicAPI/net-tizen/PublicAPI.Shipped.txt | 2 + .../src/Fonts/EmbeddedFontLoader.Tizen.cs | 12 +++ src/Core/src/Fonts/FontManager.Tizen.cs | 8 +- .../src/Platform/Tizen/MauiApplication.cs | 7 ++ 6 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/FormattedStringExtensions.cs diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/FormattedStringExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/FormattedStringExtensions.cs new file mode 100644 index 000000000000..df002b71bab9 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/FormattedStringExtensions.cs @@ -0,0 +1,73 @@ +using Microsoft.Maui.Controls.Internals; +using TFormattedString = Tizen.UIExtensions.Common.FormattedString; +using TSpan = Tizen.UIExtensions.Common.Span; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class FormattedStringExtensions + { + public static TFormattedString ToFormattedString(this Label label) + => ToFormattedText( + label.FormattedText, + label.TextColor, + label.RequireFontManager(), + label.ToFont(), + label.TextTransform, + label.TextDecorations); + + internal static TFormattedString ToFormattedText( + this FormattedString formattedString, + Graphics.Color defaultColor, + IFontManager fontManager, + Font? defaultFont = null, + TextTransform defaultTextTransform = TextTransform.Default, + TextDecorations defaultTextDecorations = TextDecorations.None) + { + if (formattedString == null) + return new TFormattedString(); + + var defaultFontSize = defaultFont?.Size ?? fontManager.DefaultFontSize; + var formattedText = new TFormattedString(); + + for (int i = 0; i < formattedString.Spans.Count; i++) + { + Span span = formattedString.Spans[i]; + var transform = span.TextTransform != TextTransform.Default ? span.TextTransform : defaultTextTransform; + var text = TextTransformUtilites.GetTransformedText(span.Text, transform); + + if (text == null) + continue; + + var nativeSpan = new TSpan() { Text = text }; + var textColor = span.TextColor ?? defaultColor; + + if (textColor is not null) + nativeSpan.ForegroundColor = textColor.ToPlatform(); + + if (span.BackgroundColor is not null) + nativeSpan.BackgroundColor = span.BackgroundColor.ToPlatform(); + + var font = span.ToFont(defaultFontSize); + if (font.IsDefault && defaultFont.HasValue) + font = defaultFont.Value; + + if (!font.IsDefault) + { + nativeSpan.FontSize = font.Size.ToScaledPoint(); + nativeSpan.FontFamily = fontManager.GetFontFamily(span.FontFamily); + } + + nativeSpan.LineHeight = span.LineHeight; + + var textDecorations = span.IsSet(Span.TextDecorationsProperty) + ? span.TextDecorations + : defaultTextDecorations; + if (textDecorations.HasFlag(TextDecorations.Strikethrough) || textDecorations.HasFlag(TextDecorations.Underline)) + nativeSpan.TextDecorations = span.TextDecorations.ToPlatform(); + + formattedText.Spans.Add(nativeSpan); + } + return formattedText; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs index 535e2f971007..d11622758855 100644 --- a/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Maui.Platform; -using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Internals; +using Tizen.UIExtensions.NUI; using TEntry = Tizen.UIExtensions.NUI.Entry; using TEditor = Tizen.UIExtensions.NUI.Editor; using TLabel = Tizen.UIExtensions.NUI.Label; +using TFormattedString = Tizen.UIExtensions.Common.FormattedString; +using TSpan = Tizen.UIExtensions.Common.Span; namespace Microsoft.Maui.Controls.Platform { @@ -22,7 +21,7 @@ public static void UpdateLineBreakMode(this TLabel platformLabel, Label label) { platformLabel.LineBreakMode = label.LineBreakMode.ToPlatform(); } - + public static void UpdateText(this TEditor editor, InputView inputView) { var text = TextTransformUtilites.GetTransformedText(inputView.Text, inputView.TextTransform); @@ -32,7 +31,27 @@ public static void UpdateText(this TEditor editor, InputView inputView) public static void UpdateText(this TLabel platformLabel, Label label) { - platformLabel.Text = TextTransformUtilites.GetTransformedText(label.Text, label.TextTransform); + switch (label.TextType) + { + case TextType.Text: + if (label.FormattedText != null) + platformLabel.FormattedText = label.ToFormattedString(); + else + platformLabel.Text = TextTransformUtilites.GetTransformedText(label.Text, label.TextTransform); + break; + case TextType.Html: + platformLabel.UpdateTextHtml(label); + break; + } + } + + static void UpdateTextHtml(this TLabel platformLabel, Label label) + { + var formattedText = new TFormattedString(); + var htmlSpan = new TSpan() { Text = label.Text }; + formattedText.Spans.Add(htmlSpan); + platformLabel.EnableMarkup = true; + platformLabel.Text = formattedText.ToMarkupText(); } } } diff --git a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt index 8e4ffa6e4d28..cabbb73c199b 100644 --- a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt @@ -1619,6 +1619,7 @@ Microsoft.Maui.Controls.Platform.ElementChangedEventArgs.ElementChange Microsoft.Maui.Controls.Platform.ElementChangedEventArgs.NewElement.get -> TElement? Microsoft.Maui.Controls.Platform.ElementChangedEventArgs.OldElement.get -> TElement? Microsoft.Maui.Controls.Platform.FontExtensions +Microsoft.Maui.Controls.Platform.FormattedStringExtensions Microsoft.Maui.Controls.Platform.GestureHandler Microsoft.Maui.Controls.Platform.GestureHandler.Attach(Microsoft.Maui.IViewHandler! handler) -> void Microsoft.Maui.Controls.Platform.GestureHandler.Detach() -> void @@ -5776,6 +5777,7 @@ static Microsoft.Maui.Controls.Handlers.ShellHandler.MapItems(Microsoft.Maui.Con ~static Microsoft.Maui.Controls.Platform.ButtonExtensions.UpdateText(this Tizen.UIExtensions.NUI.Button platformButton, Microsoft.Maui.Controls.Button button) -> void ~static Microsoft.Maui.Controls.Platform.CollectionViewExtensions.ToLayoutManager(this Microsoft.Maui.Controls.IItemsLayout layout, Microsoft.Maui.Controls.ItemSizingStrategy sizing = Microsoft.Maui.Controls.ItemSizingStrategy.MeasureFirstItem) -> Tizen.UIExtensions.NUI.ICollectionViewLayoutManager ~static Microsoft.Maui.Controls.Platform.FontExtensions.ToNativeFontFamily(this string self, Microsoft.Maui.IFontManager fontManager) -> string +~static Microsoft.Maui.Controls.Platform.FormattedStringExtensions.ToFormattedString(this Microsoft.Maui.Controls.Label label) -> Tizen.UIExtensions.Common.FormattedString ~static Microsoft.Maui.Controls.Platform.ImageExtensions.LoadImage(this Tizen.NUI.BaseComponents.ImageView image, Microsoft.Maui.Controls.ImageSource source) -> System.Threading.Tasks.Task ~static Microsoft.Maui.Controls.Platform.ImageExtensions.LoadImageAsync(this Tizen.NUI.BaseComponents.ImageView image, Microsoft.Maui.Controls.FileImageSource imageSource) -> System.Threading.Tasks.Task ~static Microsoft.Maui.Controls.Platform.ImageExtensions.LoadImageAsync(this Tizen.NUI.BaseComponents.ImageView image, Microsoft.Maui.Controls.StreamImageSource imageSource) -> System.Threading.Tasks.Task diff --git a/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs b/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs index 1f86f029b76c..ea8b0cc65f14 100644 --- a/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs +++ b/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs @@ -19,6 +19,13 @@ public partial class EmbeddedFontLoader : IEmbeddedFontLoader /// public string? LoadFont(EmbeddedFont font) { + var fontResourcePath = IOPath.Combine(TApplication.Current.DirectoryInfo.Resource, _fontCacheFolderName); + var fontResourceFilePath = IOPath.Combine(fontResourcePath, font.FontName!); + if (File.Exists(fontResourceFilePath)) + { + return IOPath.GetFileNameWithoutExtension(fontResourceFilePath); + } + if (FontCacheDirectory == null) { FontCacheDirectory = Directory.CreateDirectory(IOPath.Combine(TApplication.Current.DirectoryInfo.Data, _fontCacheFolderName)); @@ -28,7 +35,10 @@ public partial class EmbeddedFontLoader : IEmbeddedFontLoader var filePath = IOPath.Combine(FontCacheDirectory.FullName, font.FontName!); var name = IOPath.GetFileNameWithoutExtension(filePath); if (File.Exists(filePath)) + { return name; + } + try { using (var fileStream = File.Create(filePath)) @@ -38,6 +48,8 @@ public partial class EmbeddedFontLoader : IEmbeddedFontLoader font.ResourceStream.CopyTo(fileStream); } + Tizen.NUI.FontClient.Instance.AddCustomFontDirectory(FontCacheDirectory.FullName); + return name; } catch (Exception ex) diff --git a/src/Core/src/Fonts/FontManager.Tizen.cs b/src/Core/src/Fonts/FontManager.Tizen.cs index e3a16b14db79..96baa470ef77 100644 --- a/src/Core/src/Fonts/FontManager.Tizen.cs +++ b/src/Core/src/Fonts/FontManager.Tizen.cs @@ -51,8 +51,7 @@ public string GetFontFamily(string? fontFamliy) if (index != -1) { string font = cleansedFont.Substring(0, index); - string style = cleansedFont.Substring(index + 1); - return $"{font}:style={style}"; + return $"{font}"; } else { @@ -79,8 +78,7 @@ string GetNativeFontFamily((string? family, float size, FontSlant slant) fontKey if (index != -1) { string font = cleansedFont.Substring(0, index); - string style = cleansedFont.Substring(index + 1); - return $"{font}:style={style}"; + return $"{font}"; } else { @@ -115,4 +113,4 @@ string GetNativeFontFamily((string? family, float size, FontSlant slant) fontKey return fontFile.PostScriptName; } } -} \ No newline at end of file +} diff --git a/src/Core/src/Platform/Tizen/MauiApplication.cs b/src/Core/src/Platform/Tizen/MauiApplication.cs index e1473d8492d9..84c5a0232a82 100644 --- a/src/Core/src/Platform/Tizen/MauiApplication.cs +++ b/src/Core/src/Platform/Tizen/MauiApplication.cs @@ -4,12 +4,16 @@ using Microsoft.Maui.LifecycleEvents; using Tizen.Applications; using Tizen.NUI; +using IOPath = System.IO.Path; +using TApplication = Tizen.Applications.Application; using NView = Tizen.NUI.BaseComponents.View; namespace Microsoft.Maui { public abstract class MauiApplication : NUIApplication, IPlatformApplication { + const string _fontCacheFolderName = "fonts"; + internal Func? _handleBackButtonPressed; IMauiContext _applicationContext = null!; @@ -28,6 +32,9 @@ protected override void OnPreCreate() FocusManager.Instance.EnableDefaultAlgorithm(true); NView.SetDefaultGrabTouchAfterLeave(true); + var fontResourcePath = IOPath.Combine(TApplication.Current.DirectoryInfo.Resource, _fontCacheFolderName); + FontClient.Instance.AddCustomFontDirectory(fontResourcePath); + var mauiApp = CreateMauiApp(); var rootContext = new MauiContext(mauiApp.Services);