/* * Copyright (c) 2017 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. * */ namespace Tizen.NUI.BaseComponents { /// /// CustomView provides some common functionality required by all views. /// public class CustomView : ViewWrapper { public CustomView(string typeName, CustomViewBehaviour behaviour) : base(typeName, new ViewWrapperImpl(behaviour)) { // Registering CustomView virtual functions to viewWrapperImpl delegates. viewWrapperImpl.OnStageConnection = new ViewWrapperImpl.OnStageConnectionDelegate(OnStageConnection); viewWrapperImpl.OnStageDisconnection = new ViewWrapperImpl.OnStageDisconnectionDelegate(OnStageDisconnection); viewWrapperImpl.OnChildAdd = new ViewWrapperImpl.OnChildAddDelegate(OnChildAdd); viewWrapperImpl.OnChildRemove = new ViewWrapperImpl.OnChildRemoveDelegate(OnChildRemove); viewWrapperImpl.OnPropertySet = new ViewWrapperImpl.OnPropertySetDelegate(OnPropertySet); viewWrapperImpl.OnSizeSet = new ViewWrapperImpl.OnSizeSetDelegate(OnSizeSet); viewWrapperImpl.OnSizeAnimation = new ViewWrapperImpl.OnSizeAnimationDelegate(OnSizeAnimation); viewWrapperImpl.OnTouch = new ViewWrapperImpl.OnTouchDelegate(OnTouch); viewWrapperImpl.OnHover = new ViewWrapperImpl.OnHoverDelegate(OnHover); viewWrapperImpl.OnKey = new ViewWrapperImpl.OnKeyDelegate(OnKey); viewWrapperImpl.OnWheel = new ViewWrapperImpl.OnWheelDelegate(OnWheel); viewWrapperImpl.OnRelayout = new ViewWrapperImpl.OnRelayoutDelegate(OnRelayout); viewWrapperImpl.OnSetResizePolicy = new ViewWrapperImpl.OnSetResizePolicyDelegate(OnSetResizePolicy); viewWrapperImpl.GetNaturalSize = new ViewWrapperImpl.GetNaturalSizeDelegate(GetNaturalSize); viewWrapperImpl.CalculateChildSize = new ViewWrapperImpl.CalculateChildSizeDelegate(CalculateChildSize); viewWrapperImpl.GetHeightForWidth = new ViewWrapperImpl.GetHeightForWidthDelegate(GetHeightForWidth); viewWrapperImpl.GetWidthForHeight = new ViewWrapperImpl.GetWidthForHeightDelegate(GetWidthForHeight); viewWrapperImpl.RelayoutDependentOnChildrenDimension = new ViewWrapperImpl.RelayoutDependentOnChildrenDimensionDelegate(RelayoutDependentOnChildren); viewWrapperImpl.RelayoutDependentOnChildren = new ViewWrapperImpl.RelayoutDependentOnChildrenDelegate(RelayoutDependentOnChildren); viewWrapperImpl.OnCalculateRelayoutSize = new ViewWrapperImpl.OnCalculateRelayoutSizeDelegate(OnCalculateRelayoutSize); viewWrapperImpl.OnLayoutNegotiated = new ViewWrapperImpl.OnLayoutNegotiatedDelegate(OnLayoutNegotiated); viewWrapperImpl.OnControlChildAdd = new ViewWrapperImpl.OnControlChildAddDelegate(OnControlChildAdd); viewWrapperImpl.OnControlChildRemove = new ViewWrapperImpl.OnControlChildRemoveDelegate(OnControlChildRemove); viewWrapperImpl.OnStyleChange = new ViewWrapperImpl.OnStyleChangeDelegate(OnStyleChange); viewWrapperImpl.OnAccessibilityActivated = new ViewWrapperImpl.OnAccessibilityActivatedDelegate(OnAccessibilityActivated); viewWrapperImpl.OnAccessibilityPan = new ViewWrapperImpl.OnAccessibilityPanDelegate(OnAccessibilityPan); viewWrapperImpl.OnAccessibilityTouch = new ViewWrapperImpl.OnAccessibilityTouchDelegate(OnAccessibilityTouch); viewWrapperImpl.OnAccessibilityValueChange = new ViewWrapperImpl.OnAccessibilityValueChangeDelegate(OnAccessibilityValueChange); viewWrapperImpl.OnAccessibilityZoom = new ViewWrapperImpl.OnAccessibilityZoomDelegate(OnAccessibilityZoom); viewWrapperImpl.OnFocusGained = new ViewWrapperImpl.OnFocusGainedDelegate(OnFocusGained); viewWrapperImpl.OnFocusLost = new ViewWrapperImpl.OnFocusLostDelegate(OnFocusLost); viewWrapperImpl.GetNextFocusableView = new ViewWrapperImpl.GetNextFocusableViewDelegate(GetNextFocusableView); viewWrapperImpl.OnFocusChangeCommitted = new ViewWrapperImpl.OnFocusChangeCommittedDelegate(OnFocusChangeCommitted); viewWrapperImpl.OnKeyboardEnter = new ViewWrapperImpl.OnKeyboardEnterDelegate(OnKeyboardEnter); viewWrapperImpl.OnPinch = new ViewWrapperImpl.OnPinchDelegate(OnPinch); viewWrapperImpl.OnPan = new ViewWrapperImpl.OnPanDelegate(OnPan); viewWrapperImpl.OnTap = new ViewWrapperImpl.OnTapDelegate(OnTap); viewWrapperImpl.OnLongPress = new ViewWrapperImpl.OnLongPressDelegate(OnLongPress); // Make sure CustomView is initialized. OnInitialize(); // Set the StyleName the name of the View // We have to do this because the StyleManager on Native side can't workout it out // This will also ensure that the style of views/visuals initialized above are applied by the style manager. SetStyleName(this.GetType().Name); } /// /// Set the background with a property map. /// /// The background property map public void SetBackground(Tizen.NUI.PropertyMap map) { viewWrapperImpl.SetBackground(map); } /// /// Allows deriving classes to enable any of the gesture detectors that are available.
/// Gesture detection can be enabled one at a time or in bitwise format.
///
/// The gesture type(s) to enable public void EnableGestureDetection(Gesture.GestureType type) { viewWrapperImpl.EnableGestureDetection(type); } /// /// Allows deriving classes to disable any of the gesture detectors.
/// Like EnableGestureDetection, this can also be called using bitwise or one at a time.
///
/// The gesture type(s) to disable internal void DisableGestureDetection(Gesture.GestureType type) { viewWrapperImpl.DisableGestureDetection(type); } /// /// Sets whether this control supports two dimensional keyboard navigation /// (i.e. whether it knows how to handle the keyboard focus movement between its child views).
/// The control doesn't support it by default.
///
/// Whether this control supports two dimensional keyboard navigation. public bool FocusNavigationSupport { get { return IsKeyboardNavigationSupported(); } set { SetKeyboardNavigationSupport(value); } } internal void SetKeyboardNavigationSupport(bool isSupported) { viewWrapperImpl.SetKeyboardNavigationSupport(isSupported); } /// /// Gets whether this control supports two dimensional keyboard navigation. /// /// true if this control supports two dimensional keyboard navigation internal bool IsKeyboardNavigationSupported() { return viewWrapperImpl.IsKeyboardNavigationSupported(); } /// /// Sets or Gets whether this control is a focus group for keyboard navigation. /// /// true if this control is set as a focus group for keyboard navigation public bool FocusGroup { get { return IsKeyboardFocusGroup(); } set { SetAsKeyboardFocusGroup(value); } } /// /// Sets whether this control is a focus group for keyboard navigation. /// (i.e. the scope of keyboard focus movement can be limitied to its child views). The control is not a focus group by default. /// /// Whether this control is set as a focus group for keyboard navigation internal void SetAsKeyboardFocusGroup(bool isFocusGroup) { viewWrapperImpl.SetAsFocusGroup(isFocusGroup); } /// /// Gets whether this control is a focus group for keyboard navigation. /// internal bool IsKeyboardFocusGroup() { return viewWrapperImpl.IsFocusGroup(); } /// /// Called by the AccessibilityManager to activate the Control. /// internal void AccessibilityActivate() { viewWrapperImpl.AccessibilityActivate(); } /// /// Called by the KeyboardFocusManager. /// internal void KeyboardEnter() { viewWrapperImpl.KeyboardEnter(); } /// /// Called by the KeyInputFocusManager to emit key event signals. /// /// The key event /// True if the event was consumed internal bool EmitKeyEventSignal(Key key) { return viewWrapperImpl.EmitKeyEventSignal(key); } /// /// Request a relayout, which means performing a size negotiation on this view, its parent and children (and potentially whole scene).
/// This method can also be called from a derived class every time it needs a different size.
/// At the end of event processing, the relayout process starts and all controls which requested Relayout will have their sizes (re)negotiated.
/// It can be called multiple times; the size negotiation is still only performed once, i.e. there is no need to keep track of this in the calling side.
/// protected void RelayoutRequest() { viewWrapperImpl.RelayoutRequest(); } /// /// Provides the View implementation of GetHeightForWidth. /// /// Width to use /// The height based on the width protected float GetHeightForWidthBase(float width) { return viewWrapperImpl.GetHeightForWidthBase(width); } /// /// Provides the View implementation of GetWidthForHeight. /// /// Height to use /// The width based on the height protected float GetWidthForHeightBase(float height) { return viewWrapperImpl.GetWidthForHeightBase(height); } /// /// Calculate the size for a child using the base view object. /// /// The child view to calculate the size for /// The dimension to calculate the size for. E.g. width or height /// Return the calculated size for the given dimension. If more than one dimension is requested, just return the first one found protected float CalculateChildSizeBase(View child, DimensionType dimension) { return viewWrapperImpl.CalculateChildSizeBase(child, dimension); } /// /// Determine if this view is dependent on it's children for relayout from the base class. /// /// The dimension(s) to check for /// Return if the view is dependent on it's children protected bool RelayoutDependentOnChildrenBase(DimensionType dimension) { return viewWrapperImpl.RelayoutDependentOnChildrenBase(dimension); } /// /// Determine if this view is dependent on it's children for relayout from the base class. /// /// Return if the view is dependent on it's children protected bool RelayoutDependentOnChildrenBase() { return viewWrapperImpl.RelayoutDependentOnChildrenBase(); } /// /// Register a visual by Property Index, linking an View to visual when required.
/// In the case of the visual being an view or control deeming visual not required then visual should be an empty handle.
/// No parenting is done during registration, this should be done by derived class.
///
/// The Property index of the visual, used to reference visual /// The visual to register protected void RegisterVisual(int index, VisualBase visual) { viewWrapperImpl.RegisterVisual(index, visual); } /// /// Register a visual by Property Index, linking an View to visual when required.
/// In the case of the visual being an view or control deeming visual not required then visual should be an empty handle.
/// If enabled is false then the visual is not set on stage until enabled by the derived class.
///
/// The Property index of the visual, used to reference visual /// The visual to register /// false if derived class wants to control when visual is set on stage protected void RegisterVisual(int index, VisualBase visual, bool enabled) { viewWrapperImpl.RegisterVisual(index, visual, enabled); } /// /// Erase the entry matching the given index from the list of registered visuals. /// /// The Property index of the visual, used to reference visual protected void UnregisterVisual(int index) { viewWrapperImpl.UnregisterVisual(index); } /// /// Retrieve the visual associated with the given property index.
/// For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
///
/// The Property index of the visual, used to reference visual /// The registered visual if exist, otherwise empty handle protected VisualBase GetVisual(int index) { return viewWrapperImpl.GetVisual(index); } /// /// Sets the given visual to be displayed or not when parent staged.
/// For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
///
/// The Property index of the visual, used to reference visual /// flag to set enabled or disabled protected void EnableVisual(int index, bool enable) { viewWrapperImpl.EnableVisual(index, enable); } /// /// Queries if the given visual is to be displayed when parent staged.
/// For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
///
/// The Property index of the visual /// Whether visual is enabled or not protected bool IsVisualEnabled(int index) { return viewWrapperImpl.IsVisualEnabled(index); } /// /// Create a transition effect on the control. /// /// transitionData The transition data describing the effect to create /// A handle to an animation defined with the given effect, or an empty handle if no properties match protected Animation CreateTransition(TransitionData transitionData) { return viewWrapperImpl.CreateTransition(transitionData); } /// /// Emits KeyInputFocusGained signal if true else emits KeyInputFocusLost signal.
/// Should be called last by the control after it acts on the Input Focus change.
///
/// focusGained True if gained, False if lost protected void EmitFocusSignal(bool focusGained) { viewWrapperImpl.EmitFocusSignal(focusGained); } /// /// This method is called after the Control has been initialized.
/// Derived classes should do any second phase initialization by overriding this method.
///
public virtual void OnInitialize() { } /// /// Called after the view has been connected to the stage.
/// When an view is connected, it will be directly or indirectly parented to the root View.
/// The root View is provided automatically by Tizen.NUI.Stage, and is always considered to be connected.
/// When the parent of a set of views is connected to the stage, then all of the children will received this callback.
///
/// The depth in the hierarchy for the view public virtual void OnStageConnection(int depth) { } /// /// Called after the view has been disconnected from Stage.
/// If an view is disconnected it either has no parent, or is parented to a disconnected view.
/// When the parent of a set of views is disconnected to the stage, then all of the children will received this callback, starting with the leaf views.
///
public virtual void OnStageDisconnection() { } /// /// Called after a child has been added to the owning view. /// /// The child which has been added public virtual void OnChildAdd(View view) { } /// /// Called after the owning view has attempted to remove a child( regardless of whether it succeeded or not ). /// /// The child being removed public virtual void OnChildRemove(View view) { } /// /// Called when the owning view property is set. /// /// The Property index that was set /// The value to set public virtual void OnPropertySet(int index, Tizen.NUI.PropertyValue propertyValue) { } /// /// Called when the owning view's size is set e.g. using View.SetSize(). /// /// The target size public virtual void OnSizeSet(Vector3 targetSize) { } /// /// Called when the owning view's size is animated e.g. using Animation::AnimateTo( Property( view, View::Property::SIZE ), ... ). /// /// The object which is animating the owning view /// The target size public virtual void OnSizeAnimation(Animation animation, Vector3 targetSize) { } /// /// 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 public virtual bool OnTouch(Touch touch) { return false; // Do not consume } /// /// Called after a hover-event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_HOVER_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The hover event /// True if the hover event should be consumed public virtual bool OnHover(Hover hover) { return false; // Do not consume } /// /// 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 public virtual bool OnKey(Key key) { return false; // Do not consume } /// /// Called after a wheel-event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_WHEEL_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The wheel event /// True if the wheel event should be consumed public virtual bool OnWheel(Wheel wheel) { return false; // Do not consume } /// /// Called after the size negotiation has been finished for this control.
/// The control is expected to assign this given size to itself/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 public virtual void OnRelayout(Vector2 size, RelayoutContainer container) { } /// /// Notification for deriving classes. /// /// policy The policy being set /// dimension The dimension the policy is being set for public virtual void OnSetResizePolicy(ResizePolicyType policy, DimensionType dimension) { } /// /// Return the natural size of the view. /// /// The view's natural size public new virtual Size2D GetNaturalSize() { return new Size2D(0, 0); } /// /// Calculate the size for a child. /// /// The child view to calculate the size for /// The dimension to calculate the size for. E.g. width or height /// Return the calculated size for the given dimension. If more than one dimension is requested, just return the first one found. public virtual float CalculateChildSize(View child, DimensionType dimension) { return viewWrapperImpl.CalculateChildSizeBase(child, dimension); } /// /// This method is called during size negotiation when a height is required for a given width.
/// Derived classes should override this if they wish to customize the height returned.
///
/// Width to use /// The height based on the width public new virtual float GetHeightForWidth(float width) { return viewWrapperImpl.GetHeightForWidthBase(width); } /// /// This method is called during size negotiation when a width is required for a given height.
/// Derived classes should override this if they wish to customize the width returned.
///
/// Height to use /// The width based on the width public new virtual float GetWidthForHeight(float height) { return viewWrapperImpl.GetWidthForHeightBase(height); } /// /// Determine if this view is dependent on it's children for relayout. /// /// The dimension(s) to check for /// Return if the view is dependent on it's children public virtual bool RelayoutDependentOnChildren(DimensionType dimension) { return viewWrapperImpl.RelayoutDependentOnChildrenBase(dimension); } /// /// Determine if this view is dependent on it's children for relayout from the base class. /// /// Return true if the view is dependent on it's children public virtual bool RelayoutDependentOnChildren() { return viewWrapperImpl.RelayoutDependentOnChildrenBase(); } /// /// Virtual method to notify deriving classes that relayout dependencies have been /// met and the size for this object is about to be calculated for the given dimension. /// /// The dimension that is about to be calculated public virtual void OnCalculateRelayoutSize(DimensionType dimension) { } /// /// Virtual method to notify deriving classes that the size for a dimension has just been negotiated. /// /// The new size for the given dimension /// The dimension that was just negotiated public virtual void OnLayoutNegotiated(float size, DimensionType dimension) { } /// /// This method should be overridden by deriving classes requiring notifications when the style changes. /// /// The StyleManager object /// Information denoting what has changed public virtual void OnStyleChange(StyleManager styleManager, StyleChangeType change) { } /// /// This method is called when the control is accessibility activated.
/// Derived classes should override this to perform custom accessibility activation.
///
/// true if this control can perform accessibility activation internal virtual bool OnAccessibilityActivated() { return false; } /// /// This method should be overridden by deriving classes when they wish to respond the accessibility. /// /// The pan gesture /// true if the pan gesture has been consumed by this control internal virtual bool OnAccessibilityPan(PanGesture gestures) { return false; } /// /// This method should be overridden by deriving classes when they wish to respond the accessibility /// /// The touch gesture /// true if the touch event has been consumed by this control internal virtual bool OnAccessibilityTouch(Touch touch) { return false; } /// /// This method should be overridden by deriving classes when they wish to respond the accessibility up and down action (i.e. value change of slider control). /// /// isIncrease Whether the value should be increased or decreased /// true if the value changed action has been consumed by this control internal virtual bool OnAccessibilityValueChange(bool isIncrease) { return false; } /// /// This method should be overridden by deriving classes when they wish to respond the accessibility zoom action. /// /// true if the zoom action has been consumed by this control internal virtual bool OnAccessibilityZoom() { return false; } /// /// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when focus is gained. /// public virtual void OnFocusGained() { } /// /// Called when the control loses key input focus. Should be overridden by derived classes if they need to customize what happens when focus is lost. /// public virtual void OnFocusLost() { } /// /// Gets the next keyboard focusable view in this control towards the given direction.
/// A control needs to override this function in order to support two dimensional keyboard navigation.
///
/// The current focused view /// The direction to move the focus towards /// Whether the focus movement should be looped within the control /// the next keyboard focusable view in this control or an empty handle if no view can be focused public virtual View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled) { return new View(); } /// /// Informs this control that its chosen focusable view will be focused.
/// This allows the application to preform any actions if wishes before the focus is actually moved to the chosen view.
///
/// The commited focused view public virtual void OnFocusChangeCommitted(View commitedFocusableView) { } /// /// This method is called when the control has enter pressed on it.
/// Derived classes should override this to perform custom actions.
///
/// true if this control supported this action public virtual bool OnKeyboardEnter() { return false; } /// /// Called whenever a pinch gesture is detected on this control.
/// This can be overridden by deriving classes when pinch detection is enabled. The default behaviour is to scale the control by the pinch scale.
/// If overridden, then the default behaviour will not occur.
/// Pinch detection should be enabled via EnableGestureDetection().
///
/// pinch tap gesture internal virtual void OnPinch(PinchGesture pinch) { } /// /// Called whenever a pan gesture is detected on this control.
/// This should be overridden by deriving classes when pan detection is enabled.
/// There is no default behaviour with panning.
/// Pan detection should be enabled via EnableGestureDetection().
///
/// The pan gesture public virtual void OnPan(PanGesture pan) { } /// /// Called whenever a tap gesture is detected on this control.
/// This should be overridden by deriving classes when tap detection is enabled.
/// There is no default behaviour with a tap.
/// Tap detection should be enabled via EnableGestureDetection().
///
/// The tap gesture public virtual void OnTap(TapGesture tap) { } /// /// Called whenever a long press gesture is detected on this control.
/// This should be overridden by deriving classes when long press detection is enabled.
/// There is no default behaviour associated with a long press.
/// Long press detection should be enabled via EnableGestureDetection().
///
/// The long press gesture internal virtual void OnLongPress(LongPressGesture longPress) { } private void OnControlChildAdd(View child) { } private void OnControlChildRemove(View child) { } } }