using System.ComponentModel;
using System.Runtime.InteropServices;
using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
namespace Tizen.NUI.BaseComponents
{
private Dictionary<TransitionCondition, TransitionList> _layoutTransitions;
private int _widthPolicy = LayoutParamPolicies.WrapContent; // Layout width policy
private int _heightPolicy = LayoutParamPolicies.WrapContent; // Layout height policy
+ private int _oldWidthPolicy = LayoutParamPolicies.MatchParent; // // Store Layout width to compare against later
+ private int _oldHeightPolicy = LayoutParamPolicies.MatchParent; // Store Layout height to compare against later
private float _weight = 0.0f; // Weighting of child View in a Layout
private MeasureSpecification _measureSpecificationWidth; // Layout width and internal Mode
private MeasureSpecification _measureSpecificationHeight; // Layout height and internal Mode
private bool _backgroundImageSynchronosLoading = false;
private Dictionary<string, Transition> transDictionary = new Dictionary<string, Transition>();
private string[] transitionNames;
+ private bool controlStatePropagation = false;
+ private ViewStyle viewStyle;
+ private bool themeChangeSensitive = false;
internal Size2D sizeSetExplicitly = new Size2D(); // Store size set by API, will be used in place of NaturalSize if not set.
+ internal BackgroundExtraData backgroundExtraData;
+
+ // List of constraint
+ private Constraint widthConstraint = null;
+ private Constraint heightConstraint = null;
+
+ static View() {}
+
+ /// 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 ViewStyle ViewStyle
+ {
+ get
+ {
+ if (null == viewStyle)
+ {
+ ApplyStyle(GetViewStyle());
+ }
+
+ return viewStyle;
+ }
+ }
/// <summary>
/// Creates a new instance of a view.
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
+ /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public View(ViewStyle viewStyle) : this(Interop.View.View_New(), true, viewStyle)
+ {
+ }
+
/// <summary>
/// Create a new instance of a View with setting the status of shown or hidden.
/// </summary>
{
SetVisible(false);
}
+
+ backgroundExtraData = uiControl.backgroundExtraData == null ? null : new BackgroundExtraData(uiControl.backgroundExtraData);
+ }
+
+ internal View(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : this(cPtr, cMemoryOwn, shown)
+ {
+ if (!ThemeManager.ThemeApplied) return;
+
+ if (viewStyle == null) UpdateStyle(); // Use style in the current theme
+ else ApplyStyle(viewStyle.Clone()); // Use given style
}
internal View(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.View.View_SWIGUpcast(cPtr), cMemoryOwn)
}
}
+ /// <summary>
+ /// The event that is triggered when the View's ControlState is changed.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler<ControlStateChangedEventArgs> ControlStateChangedEvent;
+
+ internal event EventHandler<ControlStateChangedEventArgs> ControlStateChangeEventInternal;
+
+ private ControlState controlStates = ControlState.Normal;
+ /// <summary>
+ /// Get/Set the control state.
+ /// </summary>
+ /// 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 ControlState ControlState
+ {
+ get
+ {
+ return controlStates;
+ }
+ protected set
+ {
+ if (controlStates == value)
+ {
+ return;
+ }
+
+ var prevState = controlStates;
+
+ controlStates = value;
+
+ var changeInfo = new ControlStateChangedEventArgs(prevState, value);
+
+ ControlStateChangeEventInternal?.Invoke(this, changeInfo);
+
+ if (controlStatePropagation)
+ {
+ foreach (View child in Children)
+ {
+ child.ControlState = value;
+ }
+ }
+
+ OnControlStateChanged(changeInfo);
+
+ ControlStateChangedEvent?.Invoke(this, changeInfo);
+ }
+ }
+
/// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsResourcesCreated
/// <summary>
/// The StyleName, type string.
+ /// The value indicates DALi style name defined in json theme file.
/// </summary>
/// <since_tizen> 3 </since_tizen>
public string StyleName
}
/// <summary>
+ /// The KeyInputFocus, type bool.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool KeyInputFocus
+ {
+ get
+ {
+ return (bool)GetValue(KeyInputFocusProperty);
+ }
+ set
+ {
+ SetValue(KeyInputFocusProperty, value);
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
/// The mutually exclusive with "backgroundImage" and "background" type Vector4.
/// </summary>
/// <remarks>
set
{
SetValue(BackgroundColorProperty, value);
+ if (selectorData != null)
+ {
+ selectorData.BackgroundImage.Reset(this);
+ selectorData.BackgroundColor.UpdateIfNeeds(this, value);
+ }
NotifyPropertyChanged();
}
}
set
{
SetValue(BackgroundImageProperty, value);
+ if (selectorData != null)
+ {
+ selectorData.BackgroundColor.Reset(this);
+ selectorData.BackgroundImage.UpdateIfNeeds(this, value);
+ }
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
+ /// Get or set the border of background image.
+ /// </summary>
+ /// 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 Rectangle BackgroundImageBorder
+ {
+ get
+ {
+ return (Rectangle)GetValue(BackgroundImageBorderProperty);
+ }
+ set
+ {
+ SetValue(BackgroundImageBorderProperty, value);
+ selectorData?.BackgroundImageBorder.UpdateIfNeeds(this, value);
NotifyPropertyChanged();
}
}
}
/// <summary>
+ /// Describes a shadow as an image for a View.
+ /// It is null by default.
+ /// </summary>
+ /// <remarks>
+ /// Getter returns copied instance of current shadow.
+ /// </remarks>
+ /// <remarks>
+ /// The mutually exclusive with "BoxShadow".
+ /// </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ImageShadow ImageShadow
+ {
+ get
+ {
+ return (ImageShadow)GetValue(ImageShadowProperty);
+ }
+ set
+ {
+ SetValue(ImageShadowProperty, value);
+ if (selectorData != null)
+ {
+ selectorData.BoxShadow.Reset(this);
+ selectorData.ImageShadow.UpdateIfNeeds(this, value);
+ }
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
+ /// Describes a box shaped shadow drawing for a View.
+ /// It is null by default.
+ /// </summary>
+ /// <remarks>
+ /// Gettter returns copied instance of current shadow.
+ /// </remarks>
+ /// <remarks>
+ /// The mutually exclusive with "ImageShadow".
+ /// </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Shadow BoxShadow
+ {
+ get
+ {
+ return (Shadow)GetValue(BoxShadowProperty);
+ }
+ set
+ {
+ SetValue(BoxShadowProperty, value);
+ if (selectorData != null)
+ {
+ selectorData.ImageShadow.Reset(this);
+ selectorData.BoxShadow.UpdateIfNeeds(this, value);
+ }
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
+ /// The radius for the rounded corners of the View.
+ /// This will rounds background and shadow edges.
+ /// Note that, an image background (or shadow) may not have rounded corners if it uses a Border property.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public float CornerRadius
+ {
+ get
+ {
+ return (float)GetValue(CornerRadiusProperty);
+ }
+ set
+ {
+ SetValue(CornerRadiusProperty, value);
+ selectorData?.CornerRadius.UpdateIfNeeds(this, value);
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
/// The current state of the view.
/// </summary>
/// <since_tizen> 3 </since_tizen>
/// If all items in the container set this property, their sizes will be proportional to the specified flex factor.<br />
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Deprecated in API8, will be removed in API10.")]
public float Flex
{
get
/// The alignment of the flex item along the cross axis, which, if set, overides the default alignment for all items in the container.<br />
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Deprecated in API8, will be removed in API10.")]
public int AlignSelf
{
get
/// The property cascade chaining set is possible. For example, this (view.FlexMargin.X = 0.1f;) is possible.
/// </remarks>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Deprecated in API8, will be removed in API10.")]
public Vector4 FlexMargin
{
get
}
/// <summary>
+ /// Whether the children of this view can be focusable by keyboard navigation. If user sets this to false, the children of this actor view will not be focused.
+ /// Note : Default value is true.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool FocusableChildren
+ {
+ set
+ {
+ SetValue(FocusableChildrenProperty, value);
+ NotifyPropertyChanged();
+ }
+ get
+ {
+ return (bool)GetValue(FocusableChildrenProperty);
+ }
+ }
+
+ /// <summary>
+ /// Whether this view can focus by touch.
+ /// If Focusable is false, FocusableInTouch is disabled.
+ /// If you want to have focus on touch, you need to set both Focusable and FocusableInTouch settings to true.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool FocusableInTouch
+ {
+ set
+ {
+ SetValue(FocusableInTouchProperty, value);
+ NotifyPropertyChanged();
+ }
+ get
+ {
+ return (bool)GetValue(FocusableInTouchProperty);
+ }
+ }
+
+ /// <summary>
/// Retrieves the position of the view.<br />
/// The coordinates are relative to the view's parent.<br />
/// </summary>
get
{
Size2D temp = (Size2D)GetValue(Size2DProperty);
- return new Size2D(OnSize2DChanged, temp.Width, temp.Height);
+ int width = temp.Width;
+ int height = temp.Height;
+
+ if (this.Layout == null)
+ {
+ if (width < 0) { width = 0; }
+ if (height < 0) { height = 0; }
+ }
+
+ return new Size2D(OnSize2DChanged, width, height);
}
set
{
MeasureSpecificationHeight = new MeasureSpecification(new LayoutLength(value.Height), MeasureSpecification.ModeType.Exactly);
_widthPolicy = value.Width;
_heightPolicy = value.Height;
+
_layout?.RequestLayout();
NotifyPropertyChanged();
}
set
{
SetValue(OpacityProperty, value);
+ selectorData?.Opacity.UpdateIfNeeds(this, value);
NotifyPropertyChanged();
}
}
/// <summary>
/// Determines whether the pivot point should be used to determine the position of the view.
- /// This is true by default.
+ /// This is false by default.
/// </summary>
/// <remarks>If false, then the top-left of the view is used for the position.
/// Setting this to false will allow scaling or rotation around the pivot point without affecting the view's position.
set
{
SetValue(SiblingOrderProperty, value);
+
+ LayoutGroup layout = Layout as LayoutGroup;
+ layout?.ChangeLayoutSiblingOrder(value);
+
NotifyPropertyChanged();
}
}
set
{
SetValue(SizeWidthProperty, value);
- WidthSpecification = (int)Math.Ceiling(value);
NotifyPropertyChanged();
}
}
set
{
SetValue(SizeHeightProperty, value);
- HeightSpecification = (int)Math.Ceiling(value);
NotifyPropertyChanged();
}
}
set
{
SetValue(WidthResizePolicyProperty, value);
- // Match ResizePolicy to new Layouting.
- // Parent relative policies can not be mapped at this point as parent size unknown.
- switch (value)
- {
- case ResizePolicyType.UseNaturalSize:
- {
- WidthSpecification = LayoutParamPolicies.WrapContent;
- break;
- }
- case ResizePolicyType.FillToParent:
- {
- WidthSpecification = LayoutParamPolicies.MatchParent;
- break;
- }
- case ResizePolicyType.FitToChildren:
- {
- WidthSpecification = LayoutParamPolicies.WrapContent;
- break;
- }
- default:
- break;
- }
NotifyPropertyChanged();
}
}
set
{
SetValue(HeightResizePolicyProperty, value);
- // Match ResizePolicy to new Layouting.
- // Parent relative policies can not be mapped at this point as parent size unknown.
- switch (value)
- {
- case ResizePolicyType.UseNaturalSize:
- {
- HeightSpecification = LayoutParamPolicies.WrapContent;
- break;
- }
- case ResizePolicyType.FillToParent:
- {
- HeightSpecification = LayoutParamPolicies.MatchParent;
- break;
- }
- case ResizePolicyType.FitToChildren:
- {
- HeightSpecification = LayoutParamPolicies.WrapContent;
- break;
- }
- default:
- break;
- }
NotifyPropertyChanged();
}
}
get
{
// If View has a Layout then padding in stored in the base Layout class
- if (Layout !=null)
+ if (Layout != null)
{
return Layout.Padding;
}
set
{
Extents padding = value;
- if (Layout !=null)
+ if (Layout != null)
{
// Layout set so store Padding in LayoutItem instead of in View.
// If View stores the Padding value then Legacy Size Negotiation will overwrite
Layout.Padding = value;
// If Layout is a LayoutItem then it could be a View that handles it's own padding.
// Let the View keeps it's padding. Still store Padding in Layout to reduce code paths.
- if( Layout.GetType() != typeof(LayoutItem)) // If a Layout container of some kind.
+ if (typeof(LayoutGroup).IsAssignableFrom(Layout.GetType())) // If a Layout container of some kind.
{
- padding = new Extents(0,0,0,0); // Reset value stored in View.
+ padding = new Extents(0, 0, 0, 0); // Reset value stored in View.
}
- _layout?.RequestLayout();
}
+
SetValue(PaddingProperty, padding);
NotifyPropertyChanged();
- _layout?.RequestLayout();
}
}
// MATCH_PARENT spec + parent container size can be used to limit
if (_layout != null)
{
- // Note: it only works if minimum size is >= than natural size.
- // To force the size it should be done through the width&height spec or Size2D.
- _layout.MinimumHeight = new Tizen.NUI.LayoutLength(value.Width);
- _layout.MinimumWidth = new Tizen.NUI.LayoutLength(value.Height);
_layout.RequestLayout();
}
SetValue(MaximumSizeProperty, value);
set
{
SetValue(SizeProperty, value);
- // Set Specification so when layouts measure this View it matches the value set here.
- // All Views are currently Layouts.
- WidthSpecification = (int)Math.Ceiling(value.Width);
- HeightSpecification = (int)Math.Ceiling(value.Height);
NotifyPropertyChanged();
}
}
if (basehandle is Layer layer)
{
ret = new View(Layer.getCPtr(layer).Handle, false);
- NUILog.Error("This Parent property is deprecated, shoud do not be used");
+ NUILog.Error("This Parent property is deprecated, should do not be used");
}
else
{
set
{
_widthPolicy = value;
- if (_widthPolicy >= 0)
+ if( _oldWidthPolicy != _widthPolicy )
{
- _measureSpecificationWidth = new MeasureSpecification( new LayoutLength(value), MeasureSpecification.ModeType.Exactly );
-
- if(_heightPolicy>=0) // Policy an exact value
- {
- Size2D.Width = _widthPolicy;
- }
- else
+ if (_widthPolicy >= 0)
{
- // Store _heightPolicy in the Size2D memember as will be reset to 0 by a Size2D callback.
- // Size2D height will store the specification value (negative number) this will then be applied to the
- // HeightSpecification when the Size2D callback is invoked.
- Size2D = new Size2D(_widthPolicy,_heightPolicy);
+ _measureSpecificationWidth = new MeasureSpecification( new LayoutLength(value), MeasureSpecification.ModeType.Exactly );
+
+ if(_heightPolicy>=0) // Policy an exact value
+ {
+ // Create Size2D only both _widthPolicy and _heightPolicy are set.
+ Size2D = new Size2D(_widthPolicy,_heightPolicy);
+ }
}
+ _layout?.RequestLayout();
+ _oldWidthPolicy = _widthPolicy;
}
- _layout?.RequestLayout();
}
}
set
{
_heightPolicy = value;
- if (_heightPolicy >= 0)
+ if( _oldHeightPolicy != _heightPolicy )
{
- _measureSpecificationHeight = new MeasureSpecification( new LayoutLength(value), MeasureSpecification.ModeType.Exactly );
-
- if(_widthPolicy>=0) // Policy an exact value
- {
- Size2D.Height = _heightPolicy;
- }
- else
+ if (_heightPolicy >= 0)
{
- // Store widthPolicy in the Size2D memember as will be reset to 0 by a Size2D callback.
- // Size2D height will store the specification value (negative number) this will then be applied to the
- // HeightSpecification when the Size2D callback is invoked.
- Size2D = new Size2D(_widthPolicy,_heightPolicy);
- }
+ _measureSpecificationHeight = new MeasureSpecification( new LayoutLength(value), MeasureSpecification.ModeType.Exactly );
+
+ if(_widthPolicy>=0) // Policy an exact value
+ {
+ // Create Size2D only both _widthPolicy and _heightPolicy are set.
+ Size2D = new Size2D(_widthPolicy,_heightPolicy);
+ }
+ }
+ _layout?.RequestLayout();
+ _oldHeightPolicy = _heightPolicy;
}
- _layout?.RequestLayout();
}
}
{
get
{
- Vector4 temp = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
- GetProperty(Interop.ActorProperty.Actor_Property_COLOR_get()).Get(temp);
+ Color temp = (Color)GetValue(ColorProperty);
return new Color(OnColorChanged, temp.R, temp.G, temp.B, temp.A);
}
set
{
- SetColor(value);
+ SetValue(ColorProperty, value);
+ selectorData?.Color.UpdateIfNeeds(this, value);
+ NotifyPropertyChanged();
}
}
return;
}
- Log.Info("NUI", "Setting Layout on:" + Name + "\n");
layoutingDisabled = false;
layoutSet = true;
if (value?.Owner != null)
{
// Previous owner of the layout gets a default layout as a replacement.
- value.Owner.Layout = new LayoutGroup();
+ value.Owner.Layout = new AbsoluteLayout();
// Copy Margin and Padding to replacement LayoutGroup.
- value.Owner.Layout.Margin = value.Margin;
- value.Owner.Layout.Padding = value.Padding;
+ if (value.Owner.Layout != null)
+ {
+ value.Owner.Layout.Margin = value.Margin;
+ value.Owner.Layout.Padding = value.Padding;
+ }
}
// Copy Margin and Padding to new layout being set or restore padding and margin back to
else
{
// First Layout to be added to the View hence copy
-
// Do not try to set Margins or Padding on a null Layout (when a layout is being removed from a View)
- if (value !=null)
+ if (value != null)
{
- if (Margin.Top != 0 || Margin.Bottom !=0 || Margin.Start !=0 || Margin.End != 0)
+ if (Margin.Top != 0 || Margin.Bottom != 0 || Margin.Start != 0 || Margin.End != 0)
{
// If View already has a margin set then store it in Layout instead.
value.Margin = Margin;
- SetValue(MarginProperty, new Extents(0,0,0,0));
+ SetValue(MarginProperty, new Extents(0, 0, 0, 0));
NotifyPropertyChanged();
}
- if (Padding.Top != 0 || Padding.Bottom !=0 || Padding.Start !=0 || Padding.End != 0)
+ if (Padding.Top != 0 || Padding.Bottom != 0 || Padding.Start != 0 || Padding.End != 0)
{
// If View already has a padding set then store it in Layout instead.
value.Padding = Padding;
- SetValue(PaddingProperty, new Extents(0,0,0,0));
- NotifyPropertyChanged();
+ // If Layout is a LayoutItem then it could be a View that handles it's own padding.
+ // Let the View keeps it's padding. Still store Padding in Layout to reduce code paths.
+ if (typeof(LayoutGroup).IsAssignableFrom(value.GetType())) // If a Layout container of some kind.
+ {
+ SetValue(PaddingProperty, new Extents(0, 0, 0, 0));
+ NotifyPropertyChanged();
+ }
}
}
}
set
{
_backgroundImageSynchronosLoading = value;
- string bgUrl = "";
- int visualType = 0;
- Background.Find(Visual.Property.Type)?.Get(out visualType);
- if (visualType == (int)Visual.Type.Image)
- {
- Background.Find(ImageVisualProperty.URL)?.Get(out bgUrl);
- }
- if (bgUrl.Length != 0)
+ string bgUrl = null;
+ Background.Find(ImageVisualProperty.URL)?.Get(out bgUrl);
+
+ if (!string.IsNullOrEmpty(bgUrl))
{
PropertyMap bgMap = this.Background;
bgMap.Add("synchronousLoading", new PropertyValue(_backgroundImageSynchronosLoading));
LoadTransitions();
}
}
+
+ /// <summary>
+ /// Enable/Disable ControlState propagation for children.
+ /// It is false by default.
+ /// If the View needs to share ControlState with descendants, please set it true.
+ /// Please note that, changing the value will also changes children's EnableControlStatePropagation value recursively.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool EnableControlStatePropagation
+ {
+ get => controlStatePropagation;
+ set
+ {
+ controlStatePropagation = value;
+
+ foreach (View child in Children)
+ {
+ child.EnableControlStatePropagation = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// If this property is set to true, the View can have a touch related ControlState (such as Pressed) when touch.
+ /// By default, it is false in View, true in Control.
+ /// Note that if the value is true, the View will be a touch receptor.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool EnableControlState
+ {
+ get
+ {
+ return (bool)GetValue(EnableControlStateProperty);
+ }
+ set
+ {
+ SetValue(EnableControlStateProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Whether the actor grab all touches even if touch leaves its boundary.
+ /// </summary>
+ /// <returns>true, if it grab all touch after start</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool GrabTouchAfterLeave
+ {
+ get
+ {
+ bool temp = false;
+ GetProperty(View.Property.CaptureAllTouchAfterStart).Get(out temp);
+ return temp;
+ }
+ set
+ {
+ SetProperty(View.Property.CaptureAllTouchAfterStart, new Tizen.NUI.PropertyValue(value));
+ NotifyPropertyChanged();
+ }
+ }
+
+ /// <summary>
+ /// If the value is true, the View will change its style as the theme changes.
+ /// It is false by default, but turned to true when setting StyleName (by setting property or using specified constructor).
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool ThemeChangeSensitive
+ {
+ get => (bool)GetValue(ThemeChangeSensitiveProperty);
+ set => SetValue(ThemeChangeSensitiveProperty, value);
+ }
+
+ /// <summary>
+ /// Get Style, it is abstract function and must be override.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+ // TODO: It should be deprecated. please use CreateViewStyle instead.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual ViewStyle GetViewStyle()
+ {
+ return CreateViewStyle();
+ }
+
+ /// <summary>
+ /// Create Style, it is abstract function and must be override.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual ViewStyle CreateViewStyle()
+ {
+ return new ViewStyle();
+ }
+
+ /// <summary>
+ /// Called after the View's ControlStates changed.
+ /// </summary>
+ /// <param name="controlStateChangedInfo">The information including state changed variables.</param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
+ {
+ }
+
+ /// <summary>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual void OnThemeChanged(object sender, ThemeChangedEventArgs e)
+ {
+ UpdateStyle();
+ }
+
+ /// 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 virtual void ApplyStyle(ViewStyle viewStyle)
+ {
+ if (null == viewStyle || this.viewStyle == viewStyle) return;
+
+ this.viewStyle = viewStyle;
+
+ Dictionary<string, BindableProperty> bindablePropertyOfView;
+ Type viewType = GetType();
+
+ Dictionary<string, BindableProperty> bindablePropertyOfStyle;
+ Type styleType = viewStyle.GetType();
+
+ BindableProperty.GetBindablePropertysOfType(viewType, out bindablePropertyOfView);
+ BindableProperty.GetBindablePropertysOfType(styleType, out bindablePropertyOfStyle);
+
+ if (null != bindablePropertyOfView && null != bindablePropertyOfStyle)
+ {
+ foreach (KeyValuePair<string, BindableProperty> keyValuePair in bindablePropertyOfStyle)
+ {
+ BindableProperty viewProperty;
+ bindablePropertyOfView.TryGetValue(keyValuePair.Key, out viewProperty);
+
+ if (null != viewProperty && viewProperty != StyleNameProperty)
+ {
+ object value = viewStyle.GetValue(keyValuePair.Value);
+
+ if (null != value)
+ {
+ SetValue(viewProperty, value);
+ }
+ }
+ }
+ }
+ }
}
}