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;
51 private float? borderlineWidth;
52 private Color borderlineColor;
53 private float? borderlineOffset;
55 private Selector<ImageShadow> imageShadow;
56 private Selector<Shadow> boxShadow;
57 private Selector<string> backgroundImageSelector;
58 private Selector<float?> opacitySelector;
59 private Selector<Color> backgroundColorSelector;
60 private Selector<Rectangle> backgroundImageBorderSelector;
61 private Selector<Color> colorSelector;
62 private VisualTransformPolicyType? cornerRadiusPolicy;
64 static ViewStyle() { }
67 /// Create an empty style instance.
69 /// <since_tizen> 9 </since_tizen>
70 public ViewStyle() { }
72 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
73 [EditorBrowsable(EditorBrowsableState.Never)]
74 public ViewStyle(ViewStyle viewAttributes)
76 CopyFrom(viewAttributes);
80 /// The flag that is used when creating a component with this style.
81 /// If the value is true, it will include default component style defined in the default theme.
83 [EditorBrowsable(EditorBrowsableState.Never)]
84 public bool IncludeDefaultStyle { get; set; } = false;
87 /// Gets or sets the image resource url of the background of view.
88 /// The mutually exclusive with "BackgroundColor". Setting it overwrites existing "BackgroundColor".
90 /// <since_tizen> 9 </since_tizen>
91 public Selector<string> BackgroundImage
95 Selector<string> image = (Selector<string>)GetValue(BackgroundImageProperty);
96 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
98 set => SetValue(BackgroundImageProperty, value);
101 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
102 [EditorBrowsable(EditorBrowsableState.Never)]
103 public bool? Focusable
105 get => (bool?)GetValue(FocusableProperty);
106 set => SetValue(FocusableProperty, value);
109 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
110 [Obsolete("Deprecated. Please use Size instead.")]
111 [EditorBrowsable(EditorBrowsableState.Never)]
114 get => (Size2D)GetValue(Size2DProperty);
115 set => SetValue(Size2DProperty, value);
119 /// Defines view's opacity value.
121 /// <since_tizen> 9 </since_tizen>
122 public Selector<float?> Opacity
126 Selector<float?> opacity = (Selector<float?>)GetValue(OpacityProperty);
127 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
129 set => SetValue(OpacityProperty, value);
132 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
133 [Obsolete("Deprecated. Please use Position instead.")]
134 [EditorBrowsable(EditorBrowsableState.Never)]
135 public Position2D Position2D
137 get => (Position2D)GetValue(Position2DProperty);
138 set => SetValue(Position2DProperty, value);
142 /// Determines whether the pivot point should be used to determine the position of the view.
144 /// <since_tizen> 9 </since_tizen>
145 public bool? PositionUsesPivotPoint
147 get => (bool?)GetValue(PositionUsesPivotPointProperty);
148 set => SetValue(PositionUsesPivotPointProperty, value);
152 /// Gets or sets the origin of a view within its parent's area.<br />
153 /// 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 />
154 /// The default parent-origin is ParentOrigin.TopLeft (0.0, 0.0, 0.5).<br />
155 /// A view's position is the distance between this origin and the view's anchor-point.<br />
157 /// <since_tizen> 9 </since_tizen>
158 public Position ParentOrigin
160 get => (Position)GetValue(ParentOriginProperty);
161 set => SetValue(ParentOriginProperty, value);
165 /// Gets or sets the pivot point of a view.<br />
166 /// 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 />
167 /// The default pivot point is PivotPoint.Center (0.5, 0.5, 0.5).<br />
168 /// A view position is the distance between its parent origin and this pivot point.<br />
169 /// A view's orientation is the rotation from its default orientation, the rotation is centered around its pivot point.<br />
171 /// <since_tizen> 9 </since_tizen>
172 public Position PivotPoint
174 get => (Position)GetValue(PivotPointProperty);
175 set => SetValue(PivotPointProperty, value);
179 /// Gets or sets the width of the view.
181 /// <since_tizen> 9 </since_tizen>
182 public float? SizeWidth
184 get => (float?)GetValue(SizeWidthProperty);
185 set => SetValue(SizeWidthProperty, value);
189 /// Gets or sets the height of the view.
191 /// <since_tizen> 9 </since_tizen>
192 public float? SizeHeight
194 get => (float?)GetValue(SizeHeightProperty);
195 set => SetValue(SizeHeightProperty, value);
199 /// Gets or sets the position of the view.
201 /// <since_tizen> 9 </since_tizen>
202 public Position Position
204 get => (Position)GetValue(PositionProperty);
205 set => SetValue(PositionProperty, value);
208 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
209 [EditorBrowsable(EditorBrowsableState.Never)]
210 public float? PositionX
212 get => (float?)GetValue(PositionXProperty);
213 set => SetValue(PositionXProperty, value);
216 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
217 [EditorBrowsable(EditorBrowsableState.Never)]
218 public float? PositionY
220 get => (float?)GetValue(PositionYProperty);
221 set => SetValue(PositionYProperty, value);
224 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
225 [EditorBrowsable(EditorBrowsableState.Never)]
226 public Rotation Orientation
228 get => (Rotation)GetValue(OrientationProperty);
229 set => SetValue(OrientationProperty, value);
232 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
233 [EditorBrowsable(EditorBrowsableState.Never)]
234 public DrawModeType? DrawMode
236 get => (DrawModeType?)GetValue(DrawModeProperty);
237 set => SetValue(DrawModeProperty, value);
241 /// Gets or sets the relative to parent size factor of the view.<br />
242 /// This factor is only used when ResizePolicyType is set to either: ResizePolicyType.SizeRelativeToParent or ResizePolicyType.SizeFixedOffsetFromParent.<br />
243 /// This view's size is set to the view's size multiplied by or added to this factor, depending on ResizePolicyType.<br />
245 /// <since_tizen> 9 </since_tizen>
246 [Obsolete("Deprecated. Since Tizen.NUI.ResizePolicyType is deprecated, OnSetResizePolicy is no longer supported. Instead, please use parent view having Tizen.NUI.RelativeLayout as its Layout.")]
247 public Vector3 SizeModeFactor
249 get => (Vector3)GetValue(SizeModeFactorProperty);
250 set => SetValue(SizeModeFactorProperty, value);
254 /// Gets or sets the width resize policy to be used.
256 /// <since_tizen> 9 </since_tizen>
257 [Obsolete("Deprecated. Please set Tizen.NUI.View.Layout and use Tizen.NUI.View.WidthSpecification instead.")]
258 public ResizePolicyType? WidthResizePolicy
260 get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
261 set => SetValue(WidthResizePolicyProperty, value);
265 /// Gets or sets the height resize policy to be used.
267 /// <since_tizen> 9 </since_tizen>
268 [Obsolete("Deprecated. Please set Tizen.NUI.View.Layout and use Tizen.NUI.View.HeightSpecification instead.")]
269 public ResizePolicyType? HeightResizePolicy
271 get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
272 set => SetValue(HeightResizePolicyProperty, value);
275 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
276 [EditorBrowsable(EditorBrowsableState.Never)]
277 public bool? WidthForHeight
279 get => (bool?)GetValue(WidthForHeightProperty);
280 set => SetValue(WidthForHeightProperty, value);
283 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
284 [EditorBrowsable(EditorBrowsableState.Never)]
285 public bool? HeightForWidth
287 get => (bool?)GetValue(HeightForWidthProperty);
288 set => SetValue(HeightForWidthProperty, value);
292 /// Gets or sets the padding for use in layout.
294 /// <since_tizen> 9 </since_tizen>
295 public Extents Padding
297 get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
298 set => SetValue(PaddingProperty, value);
302 /// Gets or sets the minimum size the view can be assigned in size negotiation.
304 /// <since_tizen> 9 </since_tizen>
305 public Size2D MinimumSize
307 get => (Size2D)GetValue(MinimumSizeProperty);
308 set => SetValue(MinimumSizeProperty, value);
312 /// Gets or sets the maximum size the view can be assigned in size negotiation.
314 /// <since_tizen> 9 </since_tizen>
315 public Size2D MaximumSize
317 get => (Size2D)GetValue(MaximumSizeProperty);
318 set => SetValue(MaximumSizeProperty, value);
321 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
322 [EditorBrowsable(EditorBrowsableState.Never)]
323 public ClippingModeType? ClippingMode
325 get => (ClippingModeType?)GetValue(ClippingModeProperty);
326 set => SetValue(ClippingModeProperty, value);
330 /// Sets the size of a view for the width, the height, and the depth.
332 /// <since_tizen> 9 </since_tizen>
335 get => (Size)GetValue(SizeProperty);
336 set => SetValue(SizeProperty, value);
340 /// Gets or sets the Margin for use in layout.
342 /// <since_tizen> 9 </since_tizen>
343 public Extents Margin
345 get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
346 set => SetValue(MarginProperty, value);
350 /// Gets or sets the color of the background of view.
351 /// The mutually exclusive with "BackgroundImage". Setting it overwrites existing "BackgroundImage".
353 /// <since_tizen> 9 </since_tizen>
354 public Selector<Color> BackgroundColor
358 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorProperty);
359 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
361 set => SetValue(BackgroundColorProperty, value);
367 [EditorBrowsable(EditorBrowsableState.Never)]
368 public Selector<Color> Color
370 get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
371 set => SetValue(ColorProperty, value);
374 /// <summary>View BackgroundBorder</summary>
375 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
376 [EditorBrowsable(EditorBrowsableState.Never)]
377 public Selector<Rectangle> BackgroundImageBorder
381 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
382 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
384 set => SetValue(BackgroundImageBorderProperty, value);
388 /// Describes a shadow as an image for a View.
389 /// It is null by default.
392 /// If BoxShadow is not null, the ImageShadow value will be ignored.
394 [EditorBrowsable(EditorBrowsableState.Never)]
395 public Selector<ImageShadow> ImageShadow
397 get => (Selector<ImageShadow>)GetValue(ImageShadowProperty);
398 set => SetValue(ImageShadowProperty, value);
402 /// Describes a box shaped shadow drawing for a View.
404 /// <since_tizen> 9 </since_tizen>
405 public Selector<Shadow> BoxShadow
407 get => (Selector<Shadow>)GetValue(BoxShadowProperty);
408 set => SetValue(BoxShadowProperty, value);
412 /// The radius for the rounded corners of the View.
413 /// 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).
415 /// <since_tizen> 9 </since_tizen>
416 public Vector4 CornerRadius
418 get => (Vector4)GetValue(CornerRadiusProperty);
419 set => SetValue(CornerRadiusProperty, value);
423 /// Whether the CornerRadius property value is relative (percentage [0.0f to 1.0f] of the view size) or absolute (in world units).
424 /// It is absolute by default.
425 /// When the policy is relative, the corner radius is relative to the smaller of the view's width and height.
427 /// <since_tizen> 9 </since_tizen>
428 public VisualTransformPolicyType? CornerRadiusPolicy
430 get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
431 set => SetValue(CornerRadiusPolicyProperty, value);
435 /// The width for the borderline of the View.
437 [EditorBrowsable(EditorBrowsableState.Never)]
438 public float? BorderlineWidth
440 get => (float?)GetValue(BorderlineWidthProperty);
441 set => SetValue(BorderlineWidthProperty, value);
445 /// The color for the borderline of the View.
447 [EditorBrowsable(EditorBrowsableState.Never)]
448 public Color BorderlineColor
450 get => (Color)GetValue(BorderlineColorProperty);
451 set => SetValue(BorderlineColorProperty, value);
455 /// The Relative offset for the borderline of the View.
456 /// recommand [-1.0f to 1.0f] range.
457 /// If -1.0f, borderline draw inside of View.
458 /// If 1.0f, borderline draw outside of View.
459 /// If 0.0f, borderline draw half at inside and half at outside.
461 [EditorBrowsable(EditorBrowsableState.Never)]
462 public float? BorderlineOffset
464 get => (float?)GetValue(BorderlineOffsetProperty);
465 set => SetValue(BorderlineOffsetProperty, value);
469 /// The ThemeChangeSensitive value of the View.
471 [EditorBrowsable(EditorBrowsableState.Never)]
472 public bool? ThemeChangeSensitive
474 get => (bool?)GetValue(ThemeChangeSensitiveProperty);
475 set => SetValue(ThemeChangeSensitiveProperty, value);
480 /// Allow null properties when merging it into other Theme.
481 /// If the value is true, the null properties reset target properties of the other ViewStyle with same key when merge.
482 /// It is used in <seealso cref="Theme.Merge(string)"/>, <seealso cref="Theme.Merge(Theme)"/>.
483 /// It is also used in <seealso cref="Theme.GetStyle(string)"/> when the Theme has a parent and needs to merge.
484 /// Please note that it is false by default.
486 [EditorBrowsable(EditorBrowsableState.Never)]
487 public bool SolidNull { get; set; } = false;
490 /// HashSet of dirty properties. Internal use only.
492 internal HashSet<BindableProperty> DirtyProperties { get; private set; }
494 /// <summary>Create a cloned ViewStyle.</summary>
495 [EditorBrowsable(EditorBrowsableState.Never)]
496 public ViewStyle Clone()
498 var cloned = CreateInstance();
499 cloned.CopyFrom(this);
505 /// Release instance.
507 /// <since_tizen> 9 </since_tizen>
508 public void Dispose()
511 global::System.GC.SuppressFinalize(this);
515 [EditorBrowsable(EditorBrowsableState.Never)]
516 public override void CopyFrom(BindableObject other)
518 var source = other as ViewStyle;
520 if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
525 BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
527 if (thisBindableProperties == null)
532 foreach (var sourceProperty in source.DirtyProperties)
534 var sourceValue = source.GetValue(sourceProperty);
536 if (sourceValue == null)
541 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
543 if (destinationProperty != null)
545 SetValue(destinationProperty, sourceValue);
549 IncludeDefaultStyle = source.IncludeDefaultStyle;
553 /// Release instance.
555 /// <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>
556 /// <since_tizen> 9 </since_tizen>
557 protected virtual void Dispose(bool disposing)
566 // Dispose managed state (managed objects).
568 maximumSize?.Dispose();
569 minimumSize?.Dispose();
570 orientation?.Dispose();
572 parentOrigin?.Dispose();
573 pivotPoint?.Dispose();
576 sizeModeFactor?.Dispose();
577 cornerRadius?.Dispose();
578 borderlineColor?.Dispose();
585 /// Method that is called when a bound property is changed.
587 [EditorBrowsable(EditorBrowsableState.Never)]
588 protected override void OnPropertyChangedWithData(BindableProperty property)
590 base.OnPropertyChangedWithData(property);
592 if (property != null)
594 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
598 internal ViewStyle CreateInstance()
600 return (ViewStyle)Activator.CreateInstance(GetType());
603 /// <summary>Merge other style into the current style without creating new one.</summary>
604 [EditorBrowsable(EditorBrowsableState.Never)]
605 internal void MergeDirectly(ViewStyle other)
611 /// <summary> Extension methods for ViewStyle class.</summary>
612 [EditorBrowsable(EditorBrowsableState.Never)]
613 public static class ViewStyleExtension
615 /// <summary>Merge two styles into the new one.</summary>
616 /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
617 [EditorBrowsable(EditorBrowsableState.Never)]
618 public static TOut Merge<TOut>(this TOut value, TOut other) where TOut : Tizen.NUI.BaseComponents.ViewStyle
620 var newStyle = value.Clone() as TOut;
622 newStyle?.CopyFrom(other);