[NUI] Add PreLoad of Tizen.NUI.Components.Control
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Control.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
18 using System;
19 using System.Diagnostics;
20 using System.ComponentModel;
21 using Tizen.NUI.BaseComponents;
22 using Tizen.NUI.Binding;
23 using System.Windows.Input;
24 using Tizen.System;
25
26 namespace Tizen.NUI.Components
27 {
28     /// <summary>
29     /// The control component is base class of tv nui components. It's abstract class, so cann't instantiate and can only be inherited.
30     /// </summary>
31     /// <since_tizen> 6 </since_tizen>
32     /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
33     [EditorBrowsable(EditorBrowsableState.Never)]
34     public class Control : VisualView
35     {
36         /// Internal used.
37         [EditorBrowsable(EditorBrowsableState.Never)]
38         public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(Control), null, propertyChanged: (bo, o, n) => ((Control)bo).OnCommandChanged());
39
40         /// Internal used.
41         [EditorBrowsable(EditorBrowsableState.Never)]
42         public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(nameof(CommandParameter), typeof(object), typeof(Button), null,
43             propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
44
45         private bool onThemeChangedEventOverrideChecker;
46
47         private Feedback feedback = null;
48
49         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
50         [EditorBrowsable(EditorBrowsableState.Never)]
51         public ControlStyle Style => (ControlStyle)ViewStyle.Clone();
52
53         static Control()
54         {
55             ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
56         }
57
58         /// <summary>
59         /// This is used to improve theme performance.
60         /// </summary>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         static public void PreLoad()
63         {
64             ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
65         }
66
67         /// <summary>
68         /// Construct an empty Control.
69         /// </summary>
70         /// <since_tizen> 6 </since_tizen>
71         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
72         [EditorBrowsable(EditorBrowsableState.Never)]
73         public Control() : this((ControlStyle)null)
74         {
75         }
76
77         /// <summary>
78         /// Construct with style.
79         /// </summary>
80         /// <param name="style">Create control with style.</param>
81         /// <since_tizen> 6 </since_tizen>
82         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         public Control(ControlStyle style) : base(style)
85         {
86             Initialize();
87         }
88
89         /// <summary>
90         /// Construct with style name
91         /// </summary>
92         /// <param name="styleName">The name of style in the current theme to be applied</param>
93         /// <since_tizen> 6 </since_tizen>
94         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
95         [EditorBrowsable(EditorBrowsableState.Never)]
96         public Control(string styleName) : this(ThemeManager.GetStyle(styleName) as ControlStyle)
97         {
98             if (ThemeManager.GetStyle(styleName) == null)
99             {
100                 throw new InvalidOperationException($"There is no style {styleName}");
101             }
102
103             this.styleName = styleName;
104             ThemeChangeSensitive = true;
105         }
106
107         /// <summary>
108         /// Enable/Disable a sound feedback when tap gesture detected.
109         /// </summary>
110         [EditorBrowsable(EditorBrowsableState.Never)]
111         public bool Feedback
112         {
113             get => feedback != null;
114             set
115             {
116                 if (value == (feedback != null))
117                 {
118                     return;
119                 }
120
121                 if (value)
122                 {
123                     feedback = new Feedback();
124                     this.TouchEvent += OnTouchPlayFeedback;
125                 }
126                 else
127                 {
128                     this.TouchEvent -= OnTouchPlayFeedback;
129                     feedback = null;
130                 }
131             }
132         }
133
134         private bool OnTouchPlayFeedback(object source, TouchEventArgs e)
135         {
136             if (Feedback && e?.Touch.GetState(0) == PointStateType.Down)
137             {
138                 if (feedback != null && feedback.IsSupportedPattern(FeedbackType.Sound, "Tap"))
139                 {
140                     feedback.Play(FeedbackType.Sound, "Tap");
141                 }
142             }
143             return false;
144         }
145
146         /// Internal used.
147         [EditorBrowsable(EditorBrowsableState.Never)]
148         public ICommand Command
149         {
150             get { return (ICommand)GetValue(CommandProperty); }
151             set { SetValue(CommandProperty, value); }
152         }
153
154         /// Internal used.
155         [EditorBrowsable(EditorBrowsableState.Never)]
156         public object CommandParameter
157         {
158             get { return GetValue(CommandParameterProperty); }
159             set { SetValue(CommandParameterProperty, value); }
160         }
161
162         /// <summary>
163         /// Whether focusable when touch
164         /// </summary>
165         /// <since_tizen> 6 </since_tizen>
166         internal bool StateFocusableOnTouchMode { get; set; }
167
168         internal bool IsFocused { get; set; } = false;
169
170         internal void CommandCanExecuteChanged(object sender, EventArgs eventArgs)
171         {
172             ICommand cmd = Command;
173             if (cmd != null)
174                 cmd.CanExecute(CommandParameter);
175         }
176
177         internal void OnCommandChanged()
178         {
179             if (Command != null)
180             {
181                 Command.CanExecuteChanged += CommandCanExecuteChanged;
182                 CommandCanExecuteChanged(this, EventArgs.Empty);
183             }
184         }
185
186         /// <summary>
187         /// Dispose Control and all children on it.
188         /// </summary>
189         /// <param name="type">Dispose type.</param>
190         /// <since_tizen> 6 </since_tizen>
191         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
192         [EditorBrowsable(EditorBrowsableState.Never)]
193         protected override void Dispose(DisposeTypes type)
194         {
195             if (disposed)
196             {
197                 return;
198             }
199
200             feedback = null;
201             this.TouchEvent -= OnTouchPlayFeedback;
202
203             if (type == DisposeTypes.Explicit)
204             {
205             }
206
207             base.Dispose(type);
208         }
209
210         /// <summary>
211         /// Called after a key event is received by the view that has had its focus set.
212         /// </summary>
213         /// <param name="key">The key event.</param>
214         /// <returns>True if the key event should be consumed.</returns>
215         /// <since_tizen> 6 </since_tizen>
216         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
217         [EditorBrowsable(EditorBrowsableState.Never)]
218         public override bool OnKey(Key key)
219         {
220             return false;
221         }
222
223         /// <summary>
224         /// Called after the size negotiation has been finished for this control.<br />
225         /// The control is expected to assign this given size to itself or its children.<br />
226         /// Should be overridden by derived classes if they need to layout views differently after certain operations like add or remove views, resize, or after changing specific properties.<br />
227         /// As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).<br />
228         /// </summary>
229         /// <param name="size">The allocated size.</param>
230         /// <param name="container">The control should add views to this container that it is not able to allocate a size for.</param>
231         /// <since_tizen> 6 </since_tizen>
232         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
233         [EditorBrowsable(EditorBrowsableState.Never)]
234         public override void OnRelayout(Vector2 size, RelayoutContainer container)
235         {
236             base.OnRelayout(size, container);
237             OnUpdate();
238         }
239
240         /// <summary>
241         /// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is gained.
242         /// </summary>
243         /// <since_tizen> 6 </since_tizen>
244         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
245         [EditorBrowsable(EditorBrowsableState.Never)]
246         public override void OnFocusGained()
247         {
248             IsFocused = true;
249         }
250
251         /// <summary>
252         /// Called when the control loses key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is lost.
253         /// </summary>
254         /// <since_tizen> 6 </since_tizen>
255         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
256         [EditorBrowsable(EditorBrowsableState.Never)]
257         public override void OnFocusLost()
258         {
259             IsFocused = false;
260         }
261
262         /// <summary>
263         /// Update by style.
264         /// </summary>
265         /// <since_tizen> 6 </since_tizen>
266         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
267         [EditorBrowsable(EditorBrowsableState.Never)]
268         protected virtual void OnUpdate()
269         {
270         }
271
272         /// <summary>
273         /// Theme change callback when theme is changed, this callback will be trigger.
274         /// Note that it is deprecated API.Please use OnThemeChanged instead.
275         /// </summary>
276         /// <param name="sender">The sender</param>
277         /// <param name="e">The event data</param>
278         /// <since_tizen> 6 </since_tizen>
279         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
280         [EditorBrowsable(EditorBrowsableState.Never)]
281         protected virtual void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
282         {
283             onThemeChangedEventOverrideChecker = false;
284         }
285
286         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
287         [EditorBrowsable(EditorBrowsableState.Never)]
288         protected override ViewStyle CreateViewStyle()
289         {
290             return new ControlStyle();
291         }
292
293         /// <inheritdoc/>
294         [EditorBrowsable(EditorBrowsableState.Never)]
295         protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)
296         {
297             // TODO Remove checker after update Tizen.FH.NUI.
298             onThemeChangedEventOverrideChecker = true;
299
300             OnThemeChangedEvent(sender, new StyleManager.ThemeChangeEventArgs { CurrentTheme = e.ThemeId });
301
302             if (onThemeChangedEventOverrideChecker) return;
303
304             // If the OnThemeChangedEvent is not implemented, ApplyStyle()
305             base.OnThemeChanged(sender, e);
306         }
307
308         private void Initialize()
309         {
310             LeaveRequired = true;
311
312             StateFocusableOnTouchMode = false;
313
314             EnableControlState = true;
315         }
316     }
317 }