2 * Copyright(c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 extern alias TizenSystemInformation;
18 using TizenSystemInformation.Tizen.System;
20 using System.Collections.Generic;
21 using System.ComponentModel;
23 using Tizen.NUI.BaseComponents;
27 /// <summary></summary>
28 [EditorBrowsable(EditorBrowsableState.Never)]
29 public static class ThemeManager
39 private static readonly string[] nuiThemeProjects =
42 "Tizen.NUI.Components",
47 /// Table that indicates deefault theme id by device profile.
48 /// Note that, the fallback of null value is Common value.
50 private static readonly string[] profileDefaultTheme =
52 /* Common */ "Tizen.NUI.Theme.Common",
55 /* Wearable */ "Tizen.NUI.Theme.Wearable",
58 private static Theme currentTheme;
59 private static List<Theme> builtinThemes; // First item is default theme of the current profile.
60 private static bool isLoadingDefault = false;
61 private static Profile? currentProfile;
65 [EditorBrowsable(EditorBrowsableState.Never)]
66 public static event EventHandler<ThemeChangedEventArgs> ThemeChanged;
68 internal static Theme CurrentTheme
72 if (currentTheme == null)
74 currentTheme = DefaultTheme;
85 internal static Theme DefaultTheme
87 get => BuiltinThemes?[0];
90 private static List<Theme> BuiltinThemes
94 if (builtinThemes == null && !isLoadingDefault)
96 isLoadingDefault = true;
98 // Set the default theme as first item.
99 builtinThemes = new List<Theme>
101 LoadBuiltinTheme(profileDefaultTheme[(int)CurrentProfile])
104 isLoadingDefault = false;
106 return builtinThemes;
110 private static Profile CurrentProfile
114 if (currentProfile == null)
116 currentProfile = Profile.Common;
117 string profileString = "";
121 Information.TryGetValue<string>("tizen.org/feature/profile", out profileString);
122 Tizen.Log.Info("NUI", "Profile for initial theme found : " + profileString);
126 Tizen.Log.Info("NUI", "Unknown device profile\n");
130 if (string.Equals(profileString, "mobile"))
132 currentProfile = Profile.Mobile;
134 else if (string.Equals(profileString, "tv"))
136 currentProfile = Profile.TV;
138 else if (string.Equals(profileString, "wearable"))
140 currentProfile = Profile.Wearable;
144 return (Profile)currentProfile;
149 /// Apply them to the NUI.
150 /// This changes look of the existing components with property <seealso cref="View.ThemeChangeSensitive"/> on.
151 /// This also affects all components created afterwards.
153 /// <param name="theme">The theme instance to be applied.</param>
154 /// <exception cref="ArgumentNullException">The given theme is null.</exception>
155 [EditorBrowsable(EditorBrowsableState.Never)]
156 public static void ApplyTheme(Theme theme)
158 var newTheme = (Theme)theme?.Clone() ?? throw new ArgumentNullException($"Invalid theme.");
160 if (string.IsNullOrEmpty(newTheme.Id))
162 newTheme.Id = "NONAME";
165 CurrentTheme = newTheme;
169 /// Load a style with style name in the current theme.
170 /// For components, the style name is a component name (e.g. Button) in normal case.
172 /// <param name="styleName">The style name</param>
173 [EditorBrowsable(EditorBrowsableState.Never)]
174 public static ViewStyle GetStyle(string styleName)
176 if (styleName == null)
178 throw new ArgumentNullException(nameof(styleName));
181 return CurrentTheme.GetStyle(styleName)?.Clone();
185 /// Load a style for a View in the current theme.
187 /// <param name="viewType">The type of View</param>
188 [EditorBrowsable(EditorBrowsableState.Never)]
189 public static ViewStyle GetStyle(Type viewType)
191 if (viewType == null)
193 throw new ArgumentNullException(nameof(viewType));
196 var currentType = viewType;
197 ViewStyle resultStyle = null;
201 if (currentType.Equals(typeof(Tizen.NUI.BaseComponents.View))) break;
202 resultStyle = GetStyle(currentType.Name)?.Clone();
203 currentType = currentType.BaseType;
205 while (resultStyle == null);
211 /// Get a cloned built-in theme.
213 /// <param name="themeId">The built-in theme id.</param>
214 [EditorBrowsable(EditorBrowsableState.Never)]
215 public static Theme GetBuiltinTheme(string themeId)
218 int index = BuiltinThemes.FindIndex(x => string.IsNullOrEmpty(x?.Id) && x.Id.Equals(themeId, StringComparison.OrdinalIgnoreCase));
221 result = (Theme)BuiltinThemes[index];
225 var theme = LoadBuiltinTheme(themeId);
226 BuiltinThemes.Add(theme);
229 return (Theme)result?.Clone();
232 private static Theme LoadBuiltinTheme(string id)
234 if (string.IsNullOrEmpty(id)) return null;
236 var loaded = new Theme()
241 foreach (var project in nuiThemeProjects)
243 string path = StyleManager.FrameworkResourcePath + "/Theme/" + project + "_" + id + ".xaml";
250 catch (XamlParseException)
252 Tizen.Log.Info("NUI", $"Could not find \"{path}\".\n");
253 Tizen.Log.Info("NUI", $"The assemblies used in the file may not be included in the project.\n");
257 Tizen.Log.Info("NUI", $"Could not load \"{path}\"\n");
264 private static void NotifyThemeChanged()
266 ThemeChanged?.Invoke(null, new ThemeChangedEventArgs(CurrentTheme.Id));