2 * Copyright(c) 2021 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.ComponentModel;
19 using System.Collections.Generic;
20 using Tizen.NUI.Binding;
22 namespace Tizen.NUI.BaseComponents
25 /// The base class of style attributes for a view.
27 /// <since_tizen> 9 </since_tizen>
28 public partial class ViewStyle : BindableObject, IDisposable
30 private bool disposed = false;
31 private bool? focusable;
32 private bool? positionUsesPivotPoint;
33 private Position parentOrigin;
34 private Position pivotPoint;
35 private Position position;
36 private Rotation orientation;
37 private DrawModeType? drawMode;
38 private Vector3 sizeModeFactor;
39 private ResizePolicyType? widthResizePolicy;
40 private ResizePolicyType? heightResizePolicy;
41 private bool? widthForHeight;
42 private bool? heightForWidth;
43 private Extents padding;
44 private Size2D minimumSize;
45 private Size2D maximumSize;
46 private ClippingModeType? clippingMode;
48 private Extents margin;
49 private bool? themeChangeSensitive;
50 private Vector4 cornerRadius;
52 private Selector<ImageShadow> imageShadow;
53 private Selector<Shadow> boxShadow;
54 private Selector<string> backgroundImageSelector;
55 private Selector<float?> opacitySelector;
56 private Selector<Color> backgroundColorSelector;
57 private Selector<Rectangle> backgroundImageBorderSelector;
58 private Selector<Color> colorSelector;
59 private VisualTransformPolicyType? cornerRadiusPolicy;
61 static ViewStyle() { }
64 /// Create an empty style instance.
66 /// <since_tizen> 9 </since_tizen>
67 public ViewStyle() { }
69 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
70 [EditorBrowsable(EditorBrowsableState.Never)]
71 public ViewStyle(ViewStyle viewAttributes)
73 CopyFrom(viewAttributes);
77 /// Gets or sets the image resource url of the background of view.
78 /// The mutually exclusive with "BackgroundColor". Setting it overwrites existing "BackgroundColor".
80 /// <since_tizen> 9 </since_tizen>
81 public Selector<string> BackgroundImage
85 Selector<string> image = (Selector<string>)GetValue(BackgroundImageProperty);
86 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
88 set => SetValue(BackgroundImageProperty, value);
91 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
92 [EditorBrowsable(EditorBrowsableState.Never)]
93 public bool? Focusable
95 get => (bool?)GetValue(FocusableProperty);
96 set => SetValue(FocusableProperty, value);
99 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
100 [Obsolete("Deprecated. Please use Size instead.")]
101 [EditorBrowsable(EditorBrowsableState.Never)]
104 get => (Size2D)GetValue(Size2DProperty);
105 set => SetValue(Size2DProperty, value);
109 /// Defines view's opacity value.
111 /// <since_tizen> 9 </since_tizen>
112 public Selector<float?> Opacity
116 Selector<float?> opacity = (Selector<float?>)GetValue(OpacityProperty);
117 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
119 set => SetValue(OpacityProperty, value);
122 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
123 [Obsolete("Deprecated. Please use Position instead.")]
124 [EditorBrowsable(EditorBrowsableState.Never)]
125 public Position2D Position2D
127 get => (Position2D)GetValue(Position2DProperty);
128 set => SetValue(Position2DProperty, value);
132 /// Determines whether the pivot point should be used to determine the position of the view.
134 /// <since_tizen> 9 </since_tizen>
135 public bool? PositionUsesPivotPoint
137 get => (bool?)GetValue(PositionUsesPivotPointProperty);
138 set => SetValue(PositionUsesPivotPointProperty, value);
142 /// Gets or sets the origin of a view within its parent's area.<br />
143 /// This is expressed in unit coordinates, such that (0.0, 0.0, 0.5) is the top-left corner of the parent, and (1.0, 1.0, 0.5) is the bottom-right corner.<br />
144 /// The default parent-origin is ParentOrigin.TopLeft (0.0, 0.0, 0.5).<br />
145 /// A view's position is the distance between this origin and the view's anchor-point.<br />
147 /// <since_tizen> 9 </since_tizen>
148 public Position ParentOrigin
150 get => (Position)GetValue(ParentOriginProperty);
151 set => SetValue(ParentOriginProperty, value);
155 /// Gets or sets the pivot point of a view.<br />
156 /// This is expressed in unit coordinates, such that (0.0, 0.0, 0.5) is the top-left corner of the view, and (1.0, 1.0, 0.5) is the bottom-right corner.<br />
157 /// The default pivot point is PivotPoint.Center (0.5, 0.5, 0.5).<br />
158 /// A view position is the distance between its parent origin and this pivot point.<br />
159 /// A view's orientation is the rotation from its default orientation, the rotation is centered around its pivot point.<br />
161 /// <since_tizen> 9 </since_tizen>
162 public Position PivotPoint
164 get => (Position)GetValue(PivotPointProperty);
165 set => SetValue(PivotPointProperty, value);
169 /// Gets or sets the width of the view.
171 /// <since_tizen> 9 </since_tizen>
172 public float? SizeWidth
174 get => (float?)GetValue(SizeWidthProperty);
175 set => SetValue(SizeWidthProperty, value);
179 /// Gets or sets the height of the view.
181 /// <since_tizen> 9 </since_tizen>
182 public float? SizeHeight
184 get => (float?)GetValue(SizeHeightProperty);
185 set => SetValue(SizeHeightProperty, value);
189 /// Gets or sets the position of the view.
191 /// <since_tizen> 9 </since_tizen>
192 public Position Position
194 get => (Position)GetValue(PositionProperty);
195 set => SetValue(PositionProperty, value);
198 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
199 [EditorBrowsable(EditorBrowsableState.Never)]
200 public float? PositionX
202 get => (float?)GetValue(PositionXProperty);
203 set => SetValue(PositionXProperty, value);
206 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
207 [EditorBrowsable(EditorBrowsableState.Never)]
208 public float? PositionY
210 get => (float?)GetValue(PositionYProperty);
211 set => SetValue(PositionYProperty, value);
214 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
215 [EditorBrowsable(EditorBrowsableState.Never)]
216 public Rotation Orientation
218 get => (Rotation)GetValue(OrientationProperty);
219 set => SetValue(OrientationProperty, value);
222 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
223 [EditorBrowsable(EditorBrowsableState.Never)]
224 public DrawModeType? DrawMode
226 get => (DrawModeType?)GetValue(DrawModeProperty);
227 set => SetValue(DrawModeProperty, value);
231 /// Gets or sets the relative to parent size factor of the view.<br />
232 /// This factor is only used when ResizePolicyType is set to either: ResizePolicyType.SizeRelativeToParent or ResizePolicyType.SizeFixedOffsetFromParent.<br />
233 /// This view's size is set to the view's size multiplied by or added to this factor, depending on ResizePolicyType.<br />
235 /// <since_tizen> 9 </since_tizen>
236 public Vector3 SizeModeFactor
238 get => (Vector3)GetValue(SizeModeFactorProperty);
239 set => SetValue(SizeModeFactorProperty, value);
243 /// Gets or sets the width resize policy to be used.
245 /// <since_tizen> 9 </since_tizen>
246 public ResizePolicyType? WidthResizePolicy
248 get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
249 set => SetValue(WidthResizePolicyProperty, value);
253 /// Gets or sets the height resize policy to be used.
255 /// <since_tizen> 9 </since_tizen>
256 public ResizePolicyType? HeightResizePolicy
258 get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
259 set => SetValue(HeightResizePolicyProperty, value);
262 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
263 [EditorBrowsable(EditorBrowsableState.Never)]
264 public bool? WidthForHeight
266 get => (bool?)GetValue(WidthForHeightProperty);
267 set => SetValue(WidthForHeightProperty, value);
270 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
271 [EditorBrowsable(EditorBrowsableState.Never)]
272 public bool? HeightForWidth
274 get => (bool?)GetValue(HeightForWidthProperty);
275 set => SetValue(HeightForWidthProperty, value);
279 /// Gets or sets the padding for use in layout.
281 /// <since_tizen> 9 </since_tizen>
282 public Extents Padding
284 get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
285 set => SetValue(PaddingProperty, value);
289 /// Gets or sets the minimum size the view can be assigned in size negotiation.
291 /// <since_tizen> 9 </since_tizen>
292 public Size2D MinimumSize
294 get => (Size2D)GetValue(MinimumSizeProperty);
295 set => SetValue(MinimumSizeProperty, value);
299 /// Gets or sets the maximum size the view can be assigned in size negotiation.
301 /// <since_tizen> 9 </since_tizen>
302 public Size2D MaximumSize
304 get => (Size2D)GetValue(MaximumSizeProperty);
305 set => SetValue(MaximumSizeProperty, value);
308 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
309 [EditorBrowsable(EditorBrowsableState.Never)]
310 public ClippingModeType? ClippingMode
312 get => (ClippingModeType?)GetValue(ClippingModeProperty);
313 set => SetValue(ClippingModeProperty, value);
317 /// Sets the size of a view for the width, the height, and the depth.
319 /// <since_tizen> 9 </since_tizen>
322 get => (Size)GetValue(SizeProperty);
323 set => SetValue(SizeProperty, value);
327 /// Gets or sets the Margin for use in layout.
329 /// <since_tizen> 9 </since_tizen>
330 public Extents Margin
332 get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
333 set => SetValue(MarginProperty, value);
337 /// Gets or sets the color of the background of view.
338 /// The mutually exclusive with "BackgroundImage". Setting it overwrites existing "BackgroundImage".
340 /// <since_tizen> 9 </since_tizen>
341 public Selector<Color> BackgroundColor
345 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorProperty);
346 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
348 set => SetValue(BackgroundColorProperty, value);
354 [EditorBrowsable(EditorBrowsableState.Never)]
355 public Selector<Color> Color
357 get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
358 set => SetValue(ColorProperty, value);
361 /// <summary>View BackgroundBorder</summary>
362 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
363 [EditorBrowsable(EditorBrowsableState.Never)]
364 public Selector<Rectangle> BackgroundImageBorder
368 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
369 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
371 set => SetValue(BackgroundImageBorderProperty, value);
375 /// Describes a shadow as an image for a View.
376 /// It is null by default.
379 /// If BoxShadow is not null, the ImageShadow value will be ignored.
381 [EditorBrowsable(EditorBrowsableState.Never)]
382 public Selector<ImageShadow> ImageShadow
384 get => (Selector<ImageShadow>)GetValue(ImageShadowProperty);
385 set => SetValue(ImageShadowProperty, value);
389 /// Describes a box shaped shadow drawing for a View.
391 /// <since_tizen> 9 </since_tizen>
392 public Selector<Shadow> BoxShadow
394 get => (Selector<Shadow>)GetValue(BoxShadowProperty);
395 set => SetValue(BoxShadowProperty, value);
399 /// The radius for the rounded corners of the View.
400 /// The values in Vector4 are used in clockwise order from top-left to bottom-left : Vector4(top-left-corner, top-right-corner, bottom-right-corner, bottom-left-corner).
402 /// <since_tizen> 9 </since_tizen>
403 public Vector4 CornerRadius
405 get => (Vector4)GetValue(CornerRadiusProperty);
406 set => SetValue(CornerRadiusProperty, value);
410 /// Whether the CornerRadius property value is relative (percentage [0.0f to 1.0f] of the view size) or absolute (in world units).
411 /// It is absolute by default.
412 /// When the policy is relative, the corner radius is relative to the smaller of the view's width and height.
414 /// <since_tizen> 9 </since_tizen>
415 public VisualTransformPolicyType? CornerRadiusPolicy
417 get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
418 set => SetValue(CornerRadiusPolicyProperty, value);
422 /// The ThemeChangeSensitive value of the View.
424 [EditorBrowsable(EditorBrowsableState.Never)]
425 public bool? ThemeChangeSensitive
427 get => (bool?)GetValue(ThemeChangeSensitiveProperty);
428 set => SetValue(ThemeChangeSensitiveProperty, value);
433 /// Allow null properties when merging it into other Theme.
434 /// If the value is true, the null properties reset target properties of the other ViewStyle with same key when merge.
435 /// It is used in <seealso cref="Theme.Merge(string)"/>, <seealso cref="Theme.Merge(Theme)"/>.
436 /// It is also used in <seealso cref="Theme.GetStyle(string)"/> when the Theme has a parent and needs to merge.
437 /// Please note that it is false by default.
439 [EditorBrowsable(EditorBrowsableState.Never)]
440 public bool SolidNull { get; set; } = false;
443 /// HashSet of dirty properties. Internal use only.
445 internal HashSet<BindableProperty> DirtyProperties { get; private set; }
447 /// <summary>Create a cloned ViewStyle.</summary>
448 [EditorBrowsable(EditorBrowsableState.Never)]
449 public ViewStyle Clone()
451 var cloned = CreateInstance();
452 cloned.CopyFrom(this);
458 /// Release instance.
460 /// <since_tizen> 9 </since_tizen>
461 public void Dispose()
464 global::System.GC.SuppressFinalize(this);
468 [EditorBrowsable(EditorBrowsableState.Never)]
469 public override void CopyFrom(BindableObject other)
471 var source = other as ViewStyle;
473 if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
478 BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
480 if (thisBindableProperties == null)
485 foreach (var sourceProperty in source.DirtyProperties)
487 var sourceValue = source.GetValue(sourceProperty);
489 if (sourceValue == null)
494 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
496 if (destinationProperty != null)
498 SetValue(destinationProperty, sourceValue);
504 /// Release instance.
506 /// <param name="disposing"> If it true, the method has been called by a user's code. Otherwise the method has been called by the finalizer. </param>
507 /// <since_tizen> 9 </since_tizen>
508 protected virtual void Dispose(bool disposing)
517 // Dispose managed state (managed objects).
519 maximumSize?.Dispose();
520 minimumSize?.Dispose();
521 orientation?.Dispose();
523 parentOrigin?.Dispose();
524 pivotPoint?.Dispose();
527 sizeModeFactor?.Dispose();
534 /// Method that is called when a bound property is changed.
536 [EditorBrowsable(EditorBrowsableState.Never)]
537 protected override void OnPropertyChangedWithData(BindableProperty property)
539 base.OnPropertyChangedWithData(property);
541 if (property != null)
543 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
547 internal ViewStyle CreateInstance()
549 return (ViewStyle)Activator.CreateInstance(GetType());
552 /// <summary>Merge other style into the current style without creating new one.</summary>
553 [EditorBrowsable(EditorBrowsableState.Never)]
554 internal void MergeDirectly(ViewStyle other)
560 /// <summary> Extension methods for ViewStyle class.</summary>
561 [EditorBrowsable(EditorBrowsableState.Never)]
562 public static class ViewStyleExtension
564 /// <summary>Merge two styles into the new one.</summary>
565 /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
566 [EditorBrowsable(EditorBrowsableState.Never)]
567 public static TOut Merge<TOut>(this TOut value, TOut other) where TOut : Tizen.NUI.BaseComponents.ViewStyle
569 var newStyle = value.Clone() as TOut;
571 newStyle.CopyFrom(other);