[NUI] Add default component styles (#1378)
[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 using System;
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Binding;
22
23 namespace Tizen.NUI.Components
24 {
25     /// <summary>
26     /// The control component is base class of tv nui components. It's abstract class, so cann't instantiate and can only be inherited.
27     /// </summary>
28     /// <since_tizen> 6 </since_tizen>
29     /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
30     [EditorBrowsable(EditorBrowsableState.Never)]
31     public class Control : VisualView
32     {
33         /// <summary> Control style. </summary>
34         /// <since_tizen> 6 </since_tizen>
35         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
36         [EditorBrowsable(EditorBrowsableState.Never)]
37         protected string style;
38
39         private TapGestureDetector tapGestureDetector = new TapGestureDetector();
40         private bool isFocused = false;
41
42         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
43         [EditorBrowsable(EditorBrowsableState.Never)]
44         public ControlStyle Style => ViewStyle as ControlStyle;
45
46         static Control() { }
47
48         /// <summary>
49         /// Construct an empty Control.
50         /// </summary>
51         /// <since_tizen> 6 </since_tizen>
52         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
53         [EditorBrowsable(EditorBrowsableState.Never)]
54         public Control() : base()
55         {
56             ViewStyle viewStyle = StyleManager.Instance.GetComponentStyle(this.GetType());
57
58             if (viewStyle != null)
59             {
60                 ApplyStyle(viewStyle);
61             }
62
63             Initialize(null);
64         }
65
66         /// <summary>
67         /// Construct with style.
68         /// </summary>
69         /// <param name="style">Create control with style.</param>
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(ControlStyle style) : base(style)
74         {
75             Initialize(null);
76         }
77
78         /// <summary>
79         /// Construct with styleSheet
80         /// </summary>
81         /// <param name="styleSheet">StyleSheet to be applied</param>
82         /// <since_tizen> 6 </since_tizen>
83         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
84         [EditorBrowsable(EditorBrowsableState.Never)]
85         public Control(string styleSheet) : base()
86         {
87             ViewStyle viewStyle = StyleManager.Instance.GetViewStyle(styleSheet);
88             if (viewStyle == null)
89             {
90                 throw new InvalidOperationException($"There is no style {styleSheet}");
91             }
92
93             ApplyStyle(viewStyle);
94             this.style = styleSheet;
95
96             Initialize(style);
97         }
98
99         internal void ApplyAttributes(View view, ViewStyle viewStyle)
100         {
101             view.CopyFrom(viewStyle);
102         }
103
104         /// <summary>
105         /// Whether focusable when touch
106         /// </summary>
107         /// <since_tizen> 6 </since_tizen>
108         internal bool StateFocusableOnTouchMode { get; set; }
109
110         internal bool IsFocused => (isFocused || HasFocus());
111
112         /// <summary>
113         /// Dispose Control and all children on it.
114         /// </summary>
115         /// <param name="type">Dispose type.</param>
116         /// <since_tizen> 6 </since_tizen>
117         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
118         [EditorBrowsable(EditorBrowsableState.Never)]
119         protected override void Dispose(DisposeTypes type)
120         {
121             if (disposed)
122             {
123                 return;
124             }
125
126             if (type == DisposeTypes.Explicit)
127             {
128                 StyleManager.Instance.ThemeChangedEvent -= OnThemeChangedEvent;
129                 tapGestureDetector.Detected -= OnTapGestureDetected;
130                 tapGestureDetector.Detach(this);
131             }
132
133             base.Dispose(type);
134         }
135
136         /// <summary>
137         /// Called after a key event is received by the view that has had its focus set.
138         /// </summary>
139         /// <param name="key">The key event.</param>
140         /// <returns>True if the key event should be consumed.</returns>
141         /// <since_tizen> 6 </since_tizen>
142         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
143         [EditorBrowsable(EditorBrowsableState.Never)]
144         public override bool OnKey(Key key)
145         {
146             return false;
147         }
148
149         /// <summary>
150         /// Called after the size negotiation has been finished for this control.<br />
151         /// The control is expected to assign this given size to itself or its children.<br />
152         /// 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 />
153         /// As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).<br />
154         /// </summary>
155         /// <param name="size">The allocated size.</param>
156         /// <param name="container">The control should add views to this container that it is not able to allocate a size for.</param>
157         /// <since_tizen> 6 </since_tizen>
158         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
159         [EditorBrowsable(EditorBrowsableState.Never)]
160         public override void OnRelayout(Vector2 size, RelayoutContainer container)
161         {
162             OnUpdate();
163         }
164
165         /// <summary>
166         /// 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.
167         /// </summary>
168         /// <since_tizen> 6 </since_tizen>
169         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
170         [EditorBrowsable(EditorBrowsableState.Never)]
171         public override void OnFocusGained()
172         {
173             isFocused = true;
174         }
175
176         /// <summary>
177         /// 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.
178         /// </summary>
179         /// <since_tizen> 6 </since_tizen>
180         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         public override void OnFocusLost()
183         {
184             isFocused = false;
185         }
186
187         /// <summary>
188         /// Tap gesture callback.
189         /// </summary>
190         /// <param name="source">The sender</param>
191         /// <param name="e">The tap gesture event data</param>
192         /// <since_tizen> 6 </since_tizen>
193         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
194         [EditorBrowsable(EditorBrowsableState.Never)]
195         protected virtual void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e) { }
196
197         /// <summary>
198         /// Called after a touch event is received by the owning view.<br />
199         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
200         /// </summary>
201         /// <param name="touch">The touch event.</param>
202         /// <returns>True if the event should be consumed.</returns>
203         /// <since_tizen> 6 </since_tizen>
204         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
205         [EditorBrowsable(EditorBrowsableState.Never)]
206         public override bool OnTouch(Touch touch)
207         {
208             // Handle Normal and Pressed states
209             PointStateType state = touch.GetState(0);
210             switch(state)
211             {
212                 case PointStateType.Down:
213                     ControlState = ControlStates.Pressed;
214                     return true;
215                 case PointStateType.Interrupted:
216                 case PointStateType.Up:
217                     if (ControlState == ControlStates.Pressed)
218                     {
219                         ControlState = ControlStates.Normal;
220                     }
221                     return true;
222                 default:
223                     break;
224             }
225             return false;
226         }
227
228         /// <summary>
229         /// Update by attributes.
230         /// </summary>
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         protected virtual void OnUpdate()
235         {
236         }
237
238         /// <summary>
239         /// Theme change callback when theme is changed, this callback will be trigger.
240         /// </summary>
241         /// <param name="sender">The sender</param>
242         /// <param name="e">The event data</param>
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         protected virtual void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e) { }
247
248         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
249         [EditorBrowsable(EditorBrowsableState.Never)]
250         protected virtual void RegisterDetectionOfSubstyleChanges() { }
251
252         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
253         [EditorBrowsable(EditorBrowsableState.Never)]
254         protected override ViewStyle GetViewStyle()
255         {
256             return new ControlStyle();
257         }
258
259         private void Initialize(string style)
260         {
261             ControlState = ControlStates.Normal;
262
263             RegisterDetectionOfSubstyleChanges();
264
265             LeaveRequired = true;
266
267             StateFocusableOnTouchMode = false;
268
269             tapGestureDetector.Attach(this);
270             tapGestureDetector.Detected += OnTapGestureDetected;
271
272             StyleManager.Instance.ThemeChangedEvent += OnThemeChangedEvent;
273         }
274     }
275 }