[NUI] Fix some typos. (#1807)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Utils / StyleManager.cs
1 /*
2  * Copyright(c) 2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 using System;
18 using System.ComponentModel;
19 using System.Collections.Generic;
20 using Tizen.NUI.BaseComponents;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// StyleManager is a class to manager all style.
26     /// </summary>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     public sealed class StyleManager
29     {
30         internal const float PointSizeNormal = 12;
31         internal const float PointSizeTitle = 16;
32
33         private const string defaultThemeName = "DEFAULT"; //"default";
34         private const string wearableThemeName = "WEARABLE"; //"wearable";
35         
36         private string currentThemeName = defaultThemeName;
37         private Dictionary<string, Dictionary<string, StyleBase>> themeStyleSet = new Dictionary<string, Dictionary<string, StyleBase>>();
38         private Dictionary<string, StyleBase> defaultStyleSet = new Dictionary<string, StyleBase>();
39
40         /// <summary>
41         /// (Theme name, Theme instance)
42         /// </summary>
43         private Dictionary<string, Dictionary<Type, StyleBase>> componentStyleByTheme = new Dictionary<string, Dictionary<Type, StyleBase>>();
44         
45         /// <summary>
46         /// (Theme name, Theme instance)
47         /// </summary>
48         private Dictionary<string, Theme> themeMap = new Dictionary<string, Theme>();
49
50         private EventHandler<ThemeChangeEventArgs> themeChangeHandler;
51
52         private Theme currentTheme;
53
54         /// <summary>
55         /// StyleManager construct.
56         /// </summary>
57         private StyleManager()
58         {
59             SetInitialThemeByDeviceProfile();
60         }
61
62         /// <summary>
63         /// An event for the theme changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
64         /// </summary>
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public event EventHandler<ThemeChangeEventArgs> ThemeChangedEvent
67         {
68             add
69             {
70                 themeChangeHandler += value;
71             }
72             remove
73             {
74                 themeChangeHandler -= value;
75             }
76         }
77
78         /// <summary>
79         /// StyleManager static instance.
80         /// </summary>
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         public static StyleManager Instance { get; } = new StyleManager();
83
84         /// <summary>
85         /// Style theme.
86         /// </summary>
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public string Theme
89         {
90             get
91             {
92                 return currentThemeName;
93             }
94
95             set
96             {
97                 if (value != null && currentThemeName != value)
98                 {
99                     currentThemeName = value.ToUpperInvariant();
100                     themeChangeHandler?.Invoke(null, new ThemeChangeEventArgs { CurrentTheme = currentThemeName });
101
102                     UpdateTheme();
103                 }
104             }
105         }
106
107         /// <summary>
108         /// Register style in StyleManager.
109         /// </summary>
110         /// <param name="style">Style name.</param>
111         /// <param name="theme">Theme.</param>
112         /// <param name="styleType">Style type.</param>
113         /// <param name="bDefault">Flag to decide if it is default style.</param>
114         [EditorBrowsable(EditorBrowsableState.Never)]
115         public void RegisterStyle(string style, string theme, Type styleType, bool bDefault = false)
116         {
117             if (style == null)
118             {
119                 throw new InvalidOperationException($"style can't be null");
120             }
121
122             if (theme == null || bDefault == true)
123             {
124                 if (defaultStyleSet.ContainsKey(style))
125                 {
126                     throw new InvalidOperationException($"{style}] already be used");
127                 }
128                 else
129                 {
130                     defaultStyleSet.Add(style, Activator.CreateInstance(styleType) as StyleBase);
131                 }
132                 return;
133             }
134
135             theme = theme.ToUpperInvariant();
136
137             if (themeStyleSet.ContainsKey(style) && themeStyleSet[style].ContainsKey(theme))
138             {
139                 throw new InvalidOperationException($"{style}] already be used");
140             }
141
142             if (!themeStyleSet.ContainsKey(style))
143             {
144                 themeStyleSet.Add(style, new Dictionary<string, StyleBase>());
145             }
146
147             themeStyleSet[style].Add(theme, Activator.CreateInstance(styleType) as StyleBase);
148         }
149
150         /// <summary>
151         /// Get style.
152         /// </summary>
153         /// <param name="style">Style name.</param>
154         /// <returns>The style corresponding to style name .</returns>
155         [EditorBrowsable(EditorBrowsableState.Never)]
156         public ViewStyle GetViewStyle(string style)
157         {
158             if (style == null)
159             {
160                 return null;
161             }
162
163             if (themeStyleSet.ContainsKey(style) && themeStyleSet[style].ContainsKey(Theme))
164             {
165                 return (themeStyleSet[style][Theme])?.GetViewStyle();
166             }
167             else if (defaultStyleSet.ContainsKey(style))
168             {
169                 return (defaultStyleSet[style])?.GetViewStyle();
170             }
171
172             return null;
173         }
174
175         /// <summary>
176         /// Register a style for a component to theme.
177         /// </summary>
178         /// <param name="targetTheme">The target theme name to register a component style. It theme should be a known one.</param>
179         /// <param name="component">The type of ComponentStyle</param>
180         /// <param name="style">The derived class of StyleBase</param>
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         public void RegisterComponentStyle(string targetTheme, Type component, Type style)
183         {
184             if (targetTheme == null || component == null || style == null)
185             {
186                 throw new ArgumentException("The argument targetTheme must be specified");
187             }
188
189             if (!themeMap.ContainsKey(targetTheme))
190             {
191                 Tizen.Log.Error("NUI", "The theme name should be a known one.");
192                 return;
193             }
194
195             if (!componentStyleByTheme.ContainsKey(targetTheme))
196             {
197                 componentStyleByTheme.Add(targetTheme, new Dictionary<Type, StyleBase>());
198             }
199
200             if (componentStyleByTheme[targetTheme].ContainsKey(component))
201             {
202                 componentStyleByTheme[targetTheme][component] = Activator.CreateInstance(style) as StyleBase;
203             }
204             else
205             {
206                 componentStyleByTheme[targetTheme].Add(component, Activator.CreateInstance(style) as StyleBase);
207             }
208         }
209
210         /// <summary>
211         /// Get components style in the current theme.
212         /// </summary>
213         /// <param name="component">The type of component</param>
214         /// <returns>The style of the component.</returns>
215         [EditorBrowsable(EditorBrowsableState.Never)]
216         public ViewStyle GetComponentStyle(Type component)
217         {
218             if (componentStyleByTheme.ContainsKey(currentThemeName) && componentStyleByTheme[currentThemeName].ContainsKey(component))
219             {
220                 return componentStyleByTheme[currentThemeName][component].GetViewStyle();
221             }
222
223             return currentTheme.GetComponentStyle(component);
224         }
225
226         /// <summary>
227         /// ThemeChangeEventArgs is a class to record theme change event arguments which will sent to user.
228         /// </summary>
229         [EditorBrowsable(EditorBrowsableState.Never)]
230         public class ThemeChangeEventArgs : EventArgs
231         {
232             /// <summary>
233             /// CurrentTheme
234             /// </summary>
235             [EditorBrowsable(EditorBrowsableState.Never)]
236             public string CurrentTheme;
237         }
238
239         internal static string GetFrameworkResourcePath(string resourceFileName)
240         {
241             return "/usr/share/dotnet.tizen/framework/res/" + resourceFileName;
242         }
243
244         private void SetInitialThemeByDeviceProfile()
245         {
246             Theme wearableTheme = WearableTheme.Instance;
247             Theme defaultTheme = DefaultTheme.Instance;
248             themeMap.Add(wearableThemeName, wearableTheme);
249             themeMap.Add(defaultThemeName, defaultTheme);
250
251             currentThemeName = defaultThemeName;
252             currentTheme = defaultTheme;
253
254             string currentProfile;
255
256             try
257             {
258                 System.Information.TryGetValue<string>("tizen.org/feature/profile", out currentProfile);
259                 Tizen.Log.Info("NUI", "Profile for initial theme found : " + currentProfile);
260             }
261             catch
262             {
263                 Tizen.Log.Error("NUI", "Unknown device profile\n");
264                 return;
265             }
266
267             if (string.Equals(currentProfile, wearableThemeName))
268             {
269                 currentThemeName = wearableThemeName;
270                 currentTheme = wearableTheme;
271             }
272         }
273
274         private void UpdateTheme()
275         {
276             if (themeMap.ContainsKey(currentThemeName))
277             {
278                 currentTheme = themeMap[currentThemeName];
279             }
280             else
281             {
282                 currentTheme = DefaultTheme.Instance;
283             }
284         }
285     }
286 }