2 * Copyright(c) 2019 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.
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Binding;
23 namespace Tizen.NUI.Components
26 /// The control component is base class of tv nui components. It's abstract class, so cann't instantiate and can only be inherited.
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
33 /// <summary> BackgroundImageProperty</summary>
34 [EditorBrowsable(EditorBrowsableState.Never)]
35 public new static readonly BindableProperty BackgroundImageProperty = BindableProperty.Create("ControlBackgroundImage", typeof(Selector<string>), typeof(Control), null, propertyChanged: (bindable, oldValue, newValue) =>
37 var control = (Control)bindable;
40 control.BackgroundImageSelector.Clone((Selector<string>)newValue);
43 defaultValueCreator: (bindable) =>
45 var control = (Control)bindable;
46 return control.BackgroundImageSelector;
48 /// <summary>BackgroundBorderProperty</summary>
49 [EditorBrowsable(EditorBrowsableState.Never)]
50 public new static readonly BindableProperty BackgroundImageBorderProperty = BindableProperty.Create("ControlBackgroundImageBorder", typeof(Selector<Rectangle>), typeof(Control), default(Rectangle), propertyChanged: (bindable, oldValue, newValue) =>
52 var control = (Control)bindable;
55 control.backgroundImageBorderSelector.Clone((Selector<Rectangle>)newValue);
58 defaultValueCreator: (bindable) =>
60 var control = (Control)bindable;
61 return control.backgroundImageBorderSelector;
63 /// <summary> BackgroundColorProperty </summary>
64 [EditorBrowsable(EditorBrowsableState.Never)]
65 public new static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create("ControlBackgroundColor", typeof(Selector<Color>), typeof(Control), null, propertyChanged: (bindable, oldValue, newValue) =>
67 var control = (Control)bindable;
70 control.BackgroundColorSelector.Clone((Selector<Color>)newValue);
73 defaultValueCreator: (bindable) =>
75 var control = (Control)bindable;
76 return control.BackgroundColorSelector;
78 /// <summary> Control style. </summary>
79 /// <since_tizen> 6 </since_tizen>
80 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
81 [EditorBrowsable(EditorBrowsableState.Never)]
82 protected string style;
84 private TapGestureDetector tapGestureDetector = new TapGestureDetector();
85 private bool isFocused = false;
87 internal ImageView backgroundImage = new ImageView();
88 internal ImageView shadowImage;
90 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
91 [EditorBrowsable(EditorBrowsableState.Never)]
92 public ControlStyle Style => ViewStyle as ControlStyle;
95 /// Construct an empty Control.
97 /// <since_tizen> 6 </since_tizen>
98 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
99 [EditorBrowsable(EditorBrowsableState.Never)]
100 public Control() : base()
106 /// Construct with attributes
108 /// <param name="attributes">Create attributes customized by user</param>
109 /// <since_tizen> 6 </since_tizen>
110 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
111 [EditorBrowsable(EditorBrowsableState.Never)]
112 public Control(ControlStyle controlStyle) : base(controlStyle)
118 /// Construct with styleSheet
120 /// <param name="styleSheet">StyleSheet to be applied</param>
121 /// <since_tizen> 6 </since_tizen>
122 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
123 [EditorBrowsable(EditorBrowsableState.Never)]
124 public Control(string styleSheet) : base()
126 ViewStyle viewStyle = StyleManager.Instance.GetAttributes(styleSheet);
127 if (viewStyle == null)
129 throw new InvalidOperationException($"There is no style {styleSheet}");
132 ApplyStyle(viewStyle);
133 this.style = styleSheet;
138 private TriggerableSelector<string> _backgroundImageSelector;
139 private TriggerableSelector<string> BackgroundImageSelector
143 if (null == _backgroundImageSelector)
145 _backgroundImageSelector = new TriggerableSelector<string>(backgroundImage, ImageView.ResourceUrlProperty);
147 return _backgroundImageSelector;
150 private TriggerableSelector<Rectangle> _backgroundImageBorderSelector;
151 private TriggerableSelector<Rectangle> backgroundImageBorderSelector
155 if (null == _backgroundImageBorderSelector)
157 _backgroundImageBorderSelector = new TriggerableSelector<Rectangle>(backgroundImage, ImageView.BorderProperty);
159 return _backgroundImageBorderSelector;
162 private TriggerableSelector<Color> _backgroundColorSelector;
163 private TriggerableSelector<Color> BackgroundColorSelector
167 if (null == _backgroundColorSelector)
169 _backgroundColorSelector = new TriggerableSelector<Color>(backgroundImage, View.BackgroundColorProperty);
171 return _backgroundColorSelector;
175 /// Override view's BackgroundImage.
177 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
178 [EditorBrowsable(EditorBrowsableState.Never)]
179 public new Selector<string> BackgroundImage
181 get => (Selector<string>)GetValue(BackgroundImageProperty);
182 set => SetValue(BackgroundImageProperty, value);
186 /// Override view's BackgroundImageBorder.
188 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
189 [EditorBrowsable(EditorBrowsableState.Never)]
190 public new Selector<Rectangle> BackgroundImageBorder
192 get => (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
193 set => SetValue(BackgroundImageBorderProperty, value);
196 /// Override view's BackgroundBorder.
198 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
199 [EditorBrowsable(EditorBrowsableState.Never)]
200 public new Selector<Color> BackgroundColor
202 get => (Selector<Color>)GetValue(BackgroundColorProperty);
203 set => SetValue(BackgroundColorProperty, value);
209 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
210 [EditorBrowsable(EditorBrowsableState.Never)]
211 public Selector<string> ShadowImage
215 return Style.Shadow.ResourceUrl;
219 Style.Shadow.ResourceUrl = value;
224 /// Shadow image border.
226 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
227 [EditorBrowsable(EditorBrowsableState.Never)]
228 public Selector<Rectangle> ShadowImageBorder
232 return Style.Shadow.Border;
236 Style.Shadow.Border = value;
240 internal void ApplyAttributes(View view, ViewStyle viewStyle)
242 view.CopyFrom(viewStyle);
246 /// Whether focusable when touch
248 /// <since_tizen> 6 </since_tizen>
249 internal bool StateFocusableOnTouchMode { get; set; }
251 internal bool IsFocused => (isFocused || HasFocus());
254 /// Dispose Control and all children on it.
256 /// <param name="type">Dispose type.</param>
257 /// <since_tizen> 6 </since_tizen>
258 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
259 [EditorBrowsable(EditorBrowsableState.Never)]
260 protected override void Dispose(DisposeTypes type)
267 if (type == DisposeTypes.Explicit)
269 StyleManager.Instance.ThemeChangedEvent -= OnThemeChangedEvent;
270 tapGestureDetector.Detected -= OnTapGestureDetected;
271 tapGestureDetector.Detach(this);
274 if (backgroundImage != null)
276 Utility.Dispose(backgroundImage);
278 if (shadowImage != null)
280 Utility.Dispose(shadowImage);
287 /// Called after a key event is received by the view that has had its focus set.
289 /// <param name="key">The key event.</param>
290 /// <returns>True if the key event should be consumed.</returns>
291 /// <since_tizen> 6 </since_tizen>
292 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
293 [EditorBrowsable(EditorBrowsableState.Never)]
294 public override bool OnKey(Key key)
300 /// Called after the size negotiation has been finished for this control.<br />
301 /// The control is expected to assign this given size to itself or its children.<br />
302 /// 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 />
303 /// As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).<br />
305 /// <param name="size">The allocated size.</param>
306 /// <param name="container">The control should add views to this container that it is not able to allocate a size for.</param>
307 /// <since_tizen> 6 </since_tizen>
308 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
309 [EditorBrowsable(EditorBrowsableState.Never)]
310 public override void OnRelayout(Vector2 size, RelayoutContainer container)
316 /// 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.
318 /// <since_tizen> 6 </since_tizen>
319 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
320 [EditorBrowsable(EditorBrowsableState.Never)]
321 public override void OnFocusGained()
327 /// 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.
329 /// <since_tizen> 6 </since_tizen>
330 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
331 [EditorBrowsable(EditorBrowsableState.Never)]
332 public override void OnFocusLost()
337 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
338 [EditorBrowsable(EditorBrowsableState.Never)]
339 public override void ApplyStyle(ViewStyle viewStyle)
341 base.ApplyStyle(viewStyle);
343 ControlStyle controlStyle = viewStyle as ControlStyle;
345 if (null != controlStyle?.Shadow)
347 if (null == shadowImage)
349 shadowImage = new ImageView()
351 WidthResizePolicy = ResizePolicyType.FillToParent,
352 HeightResizePolicy = ResizePolicyType.FillToParent,
354 this.Add(shadowImage);
355 shadowImage.LowerToBottom();
358 shadowImage.ApplyStyle(controlStyle.Shadow);
360 if (null != controlStyle.BackgroundImage)
362 backgroundImage.WidthResizePolicy = ResizePolicyType.FillToParent;
363 backgroundImage.HeightResizePolicy = ResizePolicyType.FillToParent;
364 this.Add(backgroundImage);
369 /// Tap gesture callback.
371 /// <param name="source">The sender</param>
372 /// <param name="e">The tap gesture event data</param>
373 /// <since_tizen> 6 </since_tizen>
374 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
375 [EditorBrowsable(EditorBrowsableState.Never)]
376 protected virtual void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e) { }
379 /// Called after a touch event is received by the owning view.<br />
380 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
382 /// <param name="touch">The touch event.</param>
383 /// <returns>True if the event should be consumed.</returns>
384 /// <since_tizen> 6 </since_tizen>
385 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
386 [EditorBrowsable(EditorBrowsableState.Never)]
387 public override bool OnTouch(Touch touch)
393 /// Update by attributes.
395 /// <since_tizen> 6 </since_tizen>
396 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
397 [EditorBrowsable(EditorBrowsableState.Never)]
398 protected virtual void OnUpdate()
403 /// Theme change callback when theme is changed, this callback will be trigger.
405 /// <param name="sender">The sender</param>
406 /// <param name="e">The event data</param>
407 /// <since_tizen> 6 </since_tizen>
408 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
409 [EditorBrowsable(EditorBrowsableState.Never)]
410 protected virtual void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e) { }
412 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
413 [EditorBrowsable(EditorBrowsableState.Never)]
414 protected virtual void RegisterDetectionOfSubstyleChanges() { }
416 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
417 [EditorBrowsable(EditorBrowsableState.Never)]
418 protected override ViewStyle GetViewStyle()
420 return new ControlStyle();
423 private void Initialize(string style)
425 ControlState = ControlStates.Normal;
427 RegisterDetectionOfSubstyleChanges();
429 LeaveRequired = true;
431 StateFocusableOnTouchMode = false;
433 tapGestureDetector.Attach(this);
434 tapGestureDetector.Detected += OnTapGestureDetected;
436 StyleManager.Instance.ThemeChangedEvent += OnThemeChangedEvent;
439 private ViewStyle GetAttributes(string style)
441 ViewStyle attributes = StyleManager.Instance.GetAttributes(style);
442 if(attributes == null)
444 throw new InvalidOperationException($"There is no style {style}");