/* * Copyright(c) 2019 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Collections.Generic; using System.ComponentModel; using Tizen.NUI.BaseComponents; using Tizen.NUI.Binding; using System.Windows.Input; namespace Tizen.NUI.Components { /// /// The control component is base class of tv nui components. It's abstract class, so cann't instantiate and can only be inherited. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public class Control : VisualView { /// Internal used. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(Control), null, propertyChanged: (bo, o, n) => ((Control)bo).OnCommandChanged()); /// Internal used. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(Button), null, propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty)); /// Control style. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected string StyleName { get; set; } private TapGestureDetector tapGestureDetector = new TapGestureDetector(); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public ControlStyle Style => ViewStyle as ControlStyle; static Control() { } /// /// Construct an empty Control. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public Control() : base() { var cur_type = this.GetType(); ViewStyle viewStyle = null; do { if (cur_type.Equals(typeof(Tizen.NUI.Components.Control))) break; viewStyle = StyleManager.Instance.GetComponentStyle(cur_type); cur_type = cur_type.BaseType; } while (viewStyle == null); if (viewStyle != null) { ApplyStyle(viewStyle); } Initialize(null); } /// /// Construct with style. /// /// Create control with style. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public Control(ControlStyle style) : base(style) { Initialize(null); } /// /// Construct with styleSheet /// /// StyleSheet to be applied /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public Control(string styleSheet) : base() { ViewStyle viewStyle = StyleManager.Instance.GetViewStyle(styleSheet); if (viewStyle == null) { throw new InvalidOperationException($"There is no style {styleSheet}"); } ApplyStyle(viewStyle); this.StyleName = styleSheet; Initialize(StyleName); } /// Internal used. [EditorBrowsable(EditorBrowsableState.Never)] public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } /// Internal used. [EditorBrowsable(EditorBrowsableState.Never)] public object CommandParameter { get { return GetValue(CommandParameterProperty); } set { SetValue(CommandParameterProperty, value); } } /// /// Whether focusable when touch /// /// 6 internal bool StateFocusableOnTouchMode { get; set; } internal bool IsFocused { get; set; } = false; internal void CommandCanExecuteChanged(object sender, EventArgs eventArgs) { ICommand cmd = Command; if (cmd != null) cmd.CanExecute(CommandParameter); } internal void OnCommandChanged() { if (Command != null) { Command.CanExecuteChanged += CommandCanExecuteChanged; CommandCanExecuteChanged(this, EventArgs.Empty); } } /// /// Dispose Control and all children on it. /// /// Dispose type. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { if (disposed) { return; } if (type == DisposeTypes.Explicit) { StyleManager.Instance.ThemeChangedEvent -= OnThemeChangedEvent; tapGestureDetector.Detected -= OnTapGestureDetected; tapGestureDetector.Detach(this); } base.Dispose(type); } /// /// Called after a key event is received by the view that has had its focus set. /// /// The key event. /// True if the key event should be consumed. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public override bool OnKey(Key key) { return false; } /// /// Called after the size negotiation has been finished for this control.
/// The control is expected to assign this given size to itself or its children.
/// 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.
/// As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).
///
/// The allocated size. /// The control should add views to this container that it is not able to allocate a size for. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public override void OnRelayout(Vector2 size, RelayoutContainer container) { base.OnRelayout(size, container); OnUpdate(); } /// /// 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. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public override void OnFocusGained() { IsFocused = true; } /// /// 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. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public override void OnFocusLost() { IsFocused = false; } /// /// Tap gesture callback. /// /// The sender /// The tap gesture event data /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e) { } /// /// Called after a touch event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The touch event. /// True if the event should be consumed. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public override bool OnTouch(Touch touch) { // Handle Normal and Pressed states PointStateType state = touch.GetState(0); switch(state) { case PointStateType.Down: ControlState = ControlStates.Pressed; break; case PointStateType.Interrupted: case PointStateType.Up: if (ControlState == ControlStates.Pressed) { ControlState = ControlStates.Normal; } break; default: break; } return false; } /// /// Update by style. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void OnUpdate() { } /// /// Theme change callback when theme is changed, this callback will be trigger. /// /// The sender /// The event data /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e) { } /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void RegisterDetectionOfSubstyleChanges() { } /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected override ViewStyle CreateViewStyle() { return new ControlStyle(); } private void Initialize(string style) { ControlState = ControlStates.Normal; RegisterDetectionOfSubstyleChanges(); LeaveRequired = true; StateFocusableOnTouchMode = false; tapGestureDetector.Attach(this); tapGestureDetector.Detected += OnTapGestureDetected; StyleManager.Instance.ThemeChangedEvent += OnThemeChangedEvent; } } }