From: Jiyun Yang Date: Wed, 15 Feb 2023 04:35:27 +0000 (+0900) Subject: [NUI] Improve behaviors of ThemeManager and add an event X-Git-Tag: submit/tizen/20230221.111427~1^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47ba9add6e909ad6da672d436033fe669aed767d;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Improve behaviors of ThemeManager and add an event * ThemeManager.AppendTheme: While ApplyTheme() clears previous applied user theme, AppendTheme() appends it to the previous one. * ThemeChanging event: An event called right after the theme changed and before applying it to the view. * Open Theme.indexer public: This is for C_XAML. * Theme implements IResourcesProvider: to support XAMLResources in xaml code Signed-off-by: Jiyun Yang --- diff --git a/src/Tizen.NUI/src/public/Theme/Theme.cs b/src/Tizen.NUI/src/public/Theme/Theme.cs index b0f1d4c18..b4379bc50 100755 --- a/src/Tizen.NUI/src/public/Theme/Theme.cs +++ b/src/Tizen.NUI/src/public/Theme/Theme.cs @@ -38,7 +38,7 @@ namespace Tizen.NUI /// /// /// 9 - public class Theme : BindableObject + public class Theme : BindableObject, IResourcesProvider { private readonly Dictionary map; private IEnumerable> changedResources = null; @@ -162,7 +162,7 @@ namespace Tizen.NUI /// [EditorBrowsable(EditorBrowsableState.Never)] - internal ResourceDictionary Resources + public ResourceDictionary XamlResources { get { @@ -195,7 +195,8 @@ namespace Tizen.NUI /// Note that it is not a normal indexer. /// Setter will merge the new value with existing item. /// - internal ViewStyle this[string styleName] + [EditorBrowsable(EditorBrowsableState.Never)] + public ViewStyle this[string styleName] { get => map[styleName]; set @@ -307,7 +308,7 @@ namespace Tizen.NUI var result = new Theme() { Id = this.Id, - Resources = Resources, + XamlResources = this.XamlResources, SmallBrokenImageUrl = this.SmallBrokenImageUrl, BrokenImageUrl = this.BrokenImageUrl, LargeBrokenImageUrl = this.LargeBrokenImageUrl @@ -364,6 +365,14 @@ namespace Tizen.NUI map[item.Key] = item.Value.Clone(); } } + + if (theme.resources != null) + { + foreach (var res in theme.resources) + { + XamlResources[res.Key] = res.Value; + } + } } internal void MergeWithoutClone(Theme theme) @@ -408,7 +417,7 @@ namespace Tizen.NUI { foreach (var res in theme.resources) { - Resources[res.Key] = res.Value; + XamlResources[res.Key] = res.Value; } } } diff --git a/src/Tizen.NUI/src/public/Theme/ThemeManager.cs b/src/Tizen.NUI/src/public/Theme/ThemeManager.cs index e3f37e2f8..2ff12cb01 100755 --- a/src/Tizen.NUI/src/public/Theme/ThemeManager.cs +++ b/src/Tizen.NUI/src/public/Theme/ThemeManager.cs @@ -38,14 +38,27 @@ namespace Tizen.NUI /// 9 public static class ThemeManager { + /// + /// The default light theme name preloaded in platform. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public const string DefaultLightThemeName = "org.tizen.default-light-theme"; + + /// + /// The default dark theme name preloaded in platform. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public const string DefaultDarkThemeName = "org.tizen.default-dark-theme"; + private static Theme baseTheme; // The base theme. It includes all styles including structures (Size, Position, Policy) of components. private static Theme platformTheme; // The platform theme. This may include color and image information without structure detail. private static Theme userTheme; // The user custom theme. private static Theme themeForUpdate; // platformTheme + userTheme. It is used when the component need to update according to theme change. private static Theme themeForInitialize; // baseTheme + platformTheme + userTheme. It is used when the component is created. private static readonly List cachedPlatformThemes = new List(); // Themes provided by framework. - private static readonly List packages = new List();// This is to store base theme creators by packages. + private static readonly List packages = new List();// This is to store base theme creators by packages. private static bool platformThemeEnabled = false; + private static bool isInEventProgress = false; static ThemeManager() { @@ -55,6 +68,12 @@ namespace Tizen.NUI AddPackageTheme(DefaultThemeCreator.Instance); } + /// + /// An event invoked when the theme is about to change (not applied to the views yet). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static event EventHandler ThemeChanging; + /// /// An event invoked after the theme has changed by . /// @@ -183,9 +202,43 @@ namespace Tizen.NUI NotifyThemeChanged(); } + /// + /// Append a theme to the current theme and apply it. + /// This will change the appearance of the existing components with property on. + /// This also affects all components created afterwards. + /// + /// The theme instance to be appended. + /// Thrown when the given theme is null. + [EditorBrowsable(EditorBrowsableState.Never)] + public static void AppendTheme(Theme theme) + { + var newTheme = (Theme)theme?.Clone() ?? throw new ArgumentNullException(nameof(theme)); + + if (string.IsNullOrEmpty(newTheme.Id)) + { + newTheme.Id = "NONAME"; + } + + StyleManager.Instance.SetBrokenImageUrl(StyleManager.BrokenImageType.Small, newTheme.SmallBrokenImageUrl ?? ""); + StyleManager.Instance.SetBrokenImageUrl(StyleManager.BrokenImageType.Normal, newTheme.BrokenImageUrl ?? ""); + StyleManager.Instance.SetBrokenImageUrl(StyleManager.BrokenImageType.Large, newTheme.LargeBrokenImageUrl ?? ""); + + if (userTheme == null) userTheme = theme; + else + { + userTheme = (Theme)userTheme.Clone(); + userTheme.MergeWithoutClone(theme); + } + + UpdateThemeForInitialize(); + UpdateThemeForUpdate(); + NotifyThemeChanged(); + } + /// /// Change tizen theme. /// User may change this to one of platform installed one. + /// Note that this is global theme changing which effects all applications. /// /// The installed theme Id. /// true on success, false when it failed to find installed theme with given themeId. @@ -360,13 +413,14 @@ namespace Tizen.NUI internal static void AddPackageTheme(IThemeCreator themeCreator) { - if (InitialThemeDisabled || packages.Contains(themeCreator)) + string packageName; + if (InitialThemeDisabled || packages.Contains(packageName = themeCreator.GetType().Assembly.GetName().Name)) { return; } Tizen.Log.Debug("NUI", $"AddPackageTheme({themeCreator.GetType().Assembly.GetName().Name})"); - packages.Add(themeCreator); + packages.Add(packageName); // Base theme var packageBaseTheme = themeCreator.Create(); @@ -463,7 +517,7 @@ namespace Tizen.NUI for (var i = theme.PackageCount; i < packages.Count; i++) { - theme.MergeWithoutClone(CreatePlatformTheme(sharedResourcePath, packages[i].GetType().Assembly.GetName().Name)); + theme.MergeWithoutClone(CreatePlatformTheme(sharedResourcePath, packages[i])); } theme.PackageCount = packages.Count; } @@ -482,9 +536,9 @@ namespace Tizen.NUI Id = id }; - foreach (var packageCreator in packages) + foreach (var packageName in packages) { - newTheme.MergeWithoutClone(CreatePlatformTheme(sharedResourcePath, packageCreator.GetType().Assembly.GetName().Name)); + newTheme.MergeWithoutClone(CreatePlatformTheme(sharedResourcePath, packageName)); } newTheme.PackageCount = packages.Count; @@ -528,10 +582,16 @@ namespace Tizen.NUI private static void NotifyThemeChanged(bool platformThemeUpdated = false) { + if (isInEventProgress) return; + isInEventProgress = true; + var platformThemeId = PlatformThemeId; var userThemeId = userTheme?.Id; + ThemeChanging?.Invoke(null, new ThemeChangedEventArgs(userThemeId, platformThemeId, platformThemeUpdated)); ThemeChangedInternal.Invoke(null, new ThemeChangedEventArgs(userThemeId, platformThemeId, platformThemeUpdated)); ThemeChanged?.Invoke(null, new ThemeChangedEventArgs(userThemeId, platformThemeId, platformThemeUpdated)); + + isInEventProgress = false; } } }