Follow formatting NUI
[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         /// <summary>
31         /// StyleManager construct.
32         /// </summary>
33         private StyleManager()
34         {
35             ThemeManager.ThemeChanged += OnThemeChanged;
36         }
37
38         /// <summary>
39         /// An event for the theme changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
40         /// </summary>
41         [EditorBrowsable(EditorBrowsableState.Never)]
42         public event EventHandler<ThemeChangeEventArgs> ThemeChangedEvent;
43
44         /// <summary>
45         /// StyleManager static instance.
46         /// </summary>
47         [EditorBrowsable(EditorBrowsableState.Never)]
48         public static StyleManager Instance { get; } = new StyleManager();
49
50         /// <summary>
51         /// Style theme.
52         /// </summary>
53         [EditorBrowsable(EditorBrowsableState.Never)]
54         public string Theme
55         {
56             get
57             {
58                 return ThemeManager.CurrentTheme?.Id;
59             }
60             set
61             {
62                 if (value == null) return;
63
64                 var key = value.ToUpperInvariant();
65
66                 // Please note that it does not check "key == Theme" here,
67                 // because of the font size issue of the Tizen.NUI.StyleManager.
68                 // (There are applications to use NUI.Components.StyleManager.ThemeChangedEvent to fix Tizen.NUI.StyleManager font size issue.)
69                 // Please do not check equality until we fix that issue.
70
71                 if (!ThemeMap.ContainsKey(key) || ThemeMap[key] == null)
72                 {
73                     ThemeMap[key] = new Theme()
74                     {
75                         Id = value
76                     };
77                 }
78
79                 ThemeManager.CurrentTheme = ThemeMap[key];
80             }
81         }
82
83         /// <summary>
84         /// (Theme name, Theme instance)
85         /// </summary>
86         private Dictionary<string, Theme> ThemeMap { get; } = new Dictionary<string, Theme> { ["DEFAULT"] = ThemeManager.DefaultTheme };
87
88         /// <summary>
89         /// Register style in StyleManager.
90         /// </summary>
91         /// <param name="style">Style name.</param>
92         /// <param name="theme">Theme id.</param>
93         /// <param name="styleType">Style type.</param>
94         /// <param name="bDefault">Flag to decide if it is default style.</param>
95         [EditorBrowsable(EditorBrowsableState.Never)]
96         public void RegisterStyle(string style, string theme, Type styleType, bool bDefault = false)
97         {
98             if (style == null)
99             {
100                 throw new InvalidOperationException($"style can't be null");
101             }
102
103             if (Activator.CreateInstance(styleType) is StyleBase styleBase)
104             {
105                 var key = "DEFAULT";
106
107                 if (bDefault && theme != null)
108                 {
109                     ThemeMap[key].AddStyleWithoutClone(style, styleBase.GetViewStyle());
110                 }
111
112                 if (theme != null)
113                 {
114                     key = theme.ToUpperInvariant();
115                 }
116
117                 if (!ThemeMap.ContainsKey(key) || ThemeMap[key] == null)
118                 {
119                     ThemeMap[key] = new Theme()
120                     {
121                         Id = theme ?? key
122                     };
123                 }
124
125                 if (ThemeMap[key].HasStyle(style))
126                 {
127                     throw new InvalidOperationException($"{style} already be used");
128                 }
129
130                 ThemeMap[key].AddStyleWithoutClone(style, styleBase.GetViewStyle());
131             }
132         }
133
134         /// <summary>
135         /// Get style.
136         /// </summary>
137         /// <param name="style">Style name.</param>
138         /// <returns>The style corresponding to style name .</returns>
139         [EditorBrowsable(EditorBrowsableState.Never)]
140         public ViewStyle GetViewStyle(string style)
141         {
142             if (style == null)
143             {
144                 return null;
145             }
146
147             return ThemeManager.GetStyle(style);
148         }
149
150         /// <summary>
151         /// Register a style for a component to theme.
152         /// </summary>
153         /// <param name="targetTheme">The target theme name to register a component style. It theme should be a known one.</param>
154         /// <param name="component">The type of ComponentStyle</param>
155         /// <param name="style">The derived class of StyleBase</param>
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         public void RegisterComponentStyle(string targetTheme, Type component, Type style)
158         {
159             if (targetTheme == null || component == null || style == null)
160             {
161                 throw new ArgumentException("The argument targetTheme must be specified");
162             }
163
164             var key = targetTheme.ToUpperInvariant();
165
166             if (!ThemeMap.ContainsKey(key) || ThemeMap[key] == null)
167             {
168                 Tizen.Log.Error("NUI", "The theme name should be a known one.");
169                 return;
170             }
171
172             if (Activator.CreateInstance(style) as StyleBase != null)
173             {
174                 ThemeMap[key].AddStyleWithoutClone(component.FullName, (Activator.CreateInstance(style) as StyleBase).GetViewStyle());
175             }
176         }
177
178         /// <summary>
179         /// Get components style in the current theme.
180         /// </summary>
181         /// <param name="component">The type of component</param>
182         /// <returns>The style of the component.</returns>
183         [EditorBrowsable(EditorBrowsableState.Never)]
184         public ViewStyle GetComponentStyle(Type component)
185         {
186             return ThemeManager.GetStyle(component.FullName);
187         }
188
189         private void OnThemeChanged(object target, ThemeChangedEventArgs args)
190         {
191             ThemeChangedEvent?.Invoke(null, new ThemeChangeEventArgs { CurrentTheme = args.ThemeId });
192         }
193
194         /// <summary>
195         /// ThemeChangeEventArgs is a class to record theme change event arguments which will sent to user.
196         /// </summary>
197         [EditorBrowsable(EditorBrowsableState.Never)]
198         public class ThemeChangeEventArgs : EventArgs
199         {
200             /// <summary>
201             /// CurrentTheme
202             /// </summary>
203             [EditorBrowsable(EditorBrowsableState.Never)]
204             public string CurrentTheme;
205         }
206     }
207 }