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? focusableInTouch;
33 private bool? positionUsesPivotPoint;
34 private Position parentOrigin;
35 private Position pivotPoint;
36 private Position position;
37 private Rotation orientation;
38 private DrawModeType? drawMode;
39 private Vector3 sizeModeFactor;
40 private ResizePolicyType? widthResizePolicy;
41 private ResizePolicyType? heightResizePolicy;
42 private bool? widthForHeight;
43 private bool? heightForWidth;
44 private Extents padding;
45 private Size2D minimumSize;
46 private Size2D maximumSize;
47 private ClippingModeType? clippingMode;
49 private Extents margin;
50 private bool? themeChangeSensitive;
51 private Vector4 cornerRadius;
52 private float? borderlineWidth;
53 private Color borderlineColor;
54 private float? borderlineOffset;
56 private Selector<ImageShadow> imageShadow;
57 private Selector<Shadow> boxShadow;
58 private Selector<string> backgroundImageSelector;
59 private Selector<float?> opacitySelector;
60 private Selector<Color> backgroundColorSelector;
61 private Selector<Rectangle> backgroundImageBorderSelector;
62 private Selector<Color> colorSelector;
63 private VisualTransformPolicyType? cornerRadiusPolicy;
65 static ViewStyle() { }
68 /// Create an empty style instance.
70 /// <since_tizen> 9 </since_tizen>
71 public ViewStyle() { }
73 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
74 [EditorBrowsable(EditorBrowsableState.Never)]
75 public ViewStyle(ViewStyle viewAttributes)
77 CopyFrom(viewAttributes);
81 /// The flag that is used when creating a component with this style.
82 /// If the value is true, it will include default component style defined in the default theme.
84 [EditorBrowsable(EditorBrowsableState.Never)]
85 public bool IncludeDefaultStyle { get; set; } = false;
88 /// Gets or sets the image resource url of the background of view.
89 /// The mutually exclusive with "BackgroundColor". Setting it overwrites existing "BackgroundColor".
91 /// <since_tizen> 9 </since_tizen>
92 public Selector<string> BackgroundImage
96 Selector<string> image = (Selector<string>)GetValue(BackgroundImageProperty);
97 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
99 set => SetValue(BackgroundImageProperty, value);
102 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
103 [EditorBrowsable(EditorBrowsableState.Never)]
104 public bool? Focusable
106 get => (bool?)GetValue(FocusableProperty);
107 set => SetValue(FocusableProperty, value);
111 /// Whether this view can focus by touch.
112 /// If Focusable is false, FocusableInTouch is disabled.
113 /// If you want to have focus on touch, you need to set both Focusable and FocusableInTouch settings to true.
115 [EditorBrowsable(EditorBrowsableState.Never)]
116 public bool? FocusableInTouch
118 get => (bool?)GetValue(FocusableInTouchProperty);
119 set => SetValue(FocusableInTouchProperty, 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 Size instead.")]
124 [EditorBrowsable(EditorBrowsableState.Never)]
127 get => (Size2D)GetValue(Size2DProperty);
128 set => SetValue(Size2DProperty, value);
132 /// Defines view's opacity value.
134 /// <since_tizen> 9 </since_tizen>
135 public Selector<float?> Opacity
139 Selector<float?> opacity = (Selector<float?>)GetValue(OpacityProperty);
140 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
142 set => SetValue(OpacityProperty, value);
145 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
146 [Obsolete("Deprecated. Please use Position instead.")]
147 [EditorBrowsable(EditorBrowsableState.Never)]
148 public Position2D Position2D
150 get => (Position2D)GetValue(Position2DProperty);
151 set => SetValue(Position2DProperty, value);
155 /// Determines whether the pivot point should be used to determine the position of the view.
157 /// <since_tizen> 9 </since_tizen>
158 public bool? PositionUsesPivotPoint
160 get => (bool?)GetValue(PositionUsesPivotPointProperty);
161 set => SetValue(PositionUsesPivotPointProperty, value);
165 /// Gets or sets the origin of a view within its parent's area.<br />
166 /// 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 />
167 /// The default parent-origin is ParentOrigin.TopLeft (0.0, 0.0, 0.5).<br />
168 /// A view's position is the distance between this origin and the view's anchor-point.<br />
170 /// <since_tizen> 9 </since_tizen>
171 public Position ParentOrigin
173 get => (Position)GetValue(ParentOriginProperty);
174 set => SetValue(ParentOriginProperty, value);
178 /// Gets or sets the pivot point of a view.<br />
179 /// 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 />
180 /// The default pivot point is PivotPoint.Center (0.5, 0.5, 0.5).<br />
181 /// A view position is the distance between its parent origin and this pivot point.<br />
182 /// A view's orientation is the rotation from its default orientation, the rotation is centered around its pivot point.<br />
184 /// <since_tizen> 9 </since_tizen>
185 public Position PivotPoint
187 get => (Position)GetValue(PivotPointProperty);
188 set => SetValue(PivotPointProperty, value);
192 /// Gets or sets the width of the view.
194 /// <since_tizen> 9 </since_tizen>
195 public float? SizeWidth
197 get => (float?)GetValue(SizeWidthProperty);
198 set => SetValue(SizeWidthProperty, value);
202 /// Gets or sets the height of the view.
204 /// <since_tizen> 9 </since_tizen>
205 public float? SizeHeight
207 get => (float?)GetValue(SizeHeightProperty);
208 set => SetValue(SizeHeightProperty, value);
212 /// Gets or sets the position of the view.
214 /// <since_tizen> 9 </since_tizen>
215 public Position Position
217 get => (Position)GetValue(PositionProperty);
218 set => SetValue(PositionProperty, value);
221 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
222 [EditorBrowsable(EditorBrowsableState.Never)]
223 public float? PositionX
225 get => (float?)GetValue(PositionXProperty);
226 set => SetValue(PositionXProperty, value);
229 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
230 [EditorBrowsable(EditorBrowsableState.Never)]
231 public float? PositionY
233 get => (float?)GetValue(PositionYProperty);
234 set => SetValue(PositionYProperty, value);
237 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
238 [EditorBrowsable(EditorBrowsableState.Never)]
239 public Rotation Orientation
241 get => (Rotation)GetValue(OrientationProperty);
242 set => SetValue(OrientationProperty, value);
245 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
246 [EditorBrowsable(EditorBrowsableState.Never)]
247 public DrawModeType? DrawMode
249 get => (DrawModeType?)GetValue(DrawModeProperty);
250 set => SetValue(DrawModeProperty, value);
254 /// Gets or sets the relative to parent size factor of the view.<br />
255 /// This factor is only used when ResizePolicyType is set to either: ResizePolicyType.SizeRelativeToParent or ResizePolicyType.SizeFixedOffsetFromParent.<br />
256 /// This view's size is set to the view's size multiplied by or added to this factor, depending on ResizePolicyType.<br />
258 /// <since_tizen> 9 </since_tizen>
259 [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.")]
260 public Vector3 SizeModeFactor
262 get => (Vector3)GetValue(SizeModeFactorProperty);
263 set => SetValue(SizeModeFactorProperty, value);
267 /// Gets or sets the width resize policy to be used.
269 /// <since_tizen> 9 </since_tizen>
270 [Obsolete("Deprecated. Please set Tizen.NUI.View.Layout and use Tizen.NUI.View.WidthSpecification instead.")]
271 public ResizePolicyType? WidthResizePolicy
273 get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
274 set => SetValue(WidthResizePolicyProperty, value);
278 /// Gets or sets the height resize policy to be used.
280 /// <since_tizen> 9 </since_tizen>
281 [Obsolete("Deprecated. Please set Tizen.NUI.View.Layout and use Tizen.NUI.View.HeightSpecification instead.")]
282 public ResizePolicyType? HeightResizePolicy
284 get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
285 set => SetValue(HeightResizePolicyProperty, value);
288 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
289 [EditorBrowsable(EditorBrowsableState.Never)]
290 public bool? WidthForHeight
292 get => (bool?)GetValue(WidthForHeightProperty);
293 set => SetValue(WidthForHeightProperty, value);
296 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
297 [EditorBrowsable(EditorBrowsableState.Never)]
298 public bool? HeightForWidth
300 get => (bool?)GetValue(HeightForWidthProperty);
301 set => SetValue(HeightForWidthProperty, value);
305 /// Gets or sets the padding for use in layout.
307 /// <since_tizen> 9 </since_tizen>
308 public Extents Padding
310 get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
311 set => SetValue(PaddingProperty, value);
315 /// Gets or sets the minimum size the view can be assigned in size negotiation.
317 /// <since_tizen> 9 </since_tizen>
318 public Size2D MinimumSize
320 get => (Size2D)GetValue(MinimumSizeProperty);
321 set => SetValue(MinimumSizeProperty, value);
325 /// Gets or sets the maximum size the view can be assigned in size negotiation.
327 /// <since_tizen> 9 </since_tizen>
328 public Size2D MaximumSize
330 get => (Size2D)GetValue(MaximumSizeProperty);
331 set => SetValue(MaximumSizeProperty, value);
334 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
335 [EditorBrowsable(EditorBrowsableState.Never)]
336 public ClippingModeType? ClippingMode
338 get => (ClippingModeType?)GetValue(ClippingModeProperty);
339 set => SetValue(ClippingModeProperty, value);
343 /// Sets the size of a view for the width, the height, and the depth.
345 /// <since_tizen> 9 </since_tizen>
348 get => (Size)GetValue(SizeProperty);
349 set => SetValue(SizeProperty, value);
353 /// Gets or sets the Margin for use in layout.
355 /// <since_tizen> 9 </since_tizen>
356 public Extents Margin
358 get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
359 set => SetValue(MarginProperty, value);
363 /// Gets or sets the color of the background of view.
364 /// The mutually exclusive with "BackgroundImage". Setting it overwrites existing "BackgroundImage".
366 /// <since_tizen> 9 </since_tizen>
367 public Selector<Color> BackgroundColor
371 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorProperty);
372 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
374 set => SetValue(BackgroundColorProperty, value);
380 [EditorBrowsable(EditorBrowsableState.Never)]
381 public Selector<Color> Color
383 get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
384 set => SetValue(ColorProperty, value);
387 /// <summary>View BackgroundBorder</summary>
388 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
389 [EditorBrowsable(EditorBrowsableState.Never)]
390 public Selector<Rectangle> BackgroundImageBorder
394 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
395 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
397 set => SetValue(BackgroundImageBorderProperty, value);
401 /// Describes a shadow as an image for a View.
402 /// It is null by default.
405 /// If BoxShadow is not null, the ImageShadow value will be ignored.
407 [EditorBrowsable(EditorBrowsableState.Never)]
408 public Selector<ImageShadow> ImageShadow
410 get => (Selector<ImageShadow>)GetValue(ImageShadowProperty);
411 set => SetValue(ImageShadowProperty, value);
415 /// Describes a box shaped shadow drawing for a View.
417 /// <since_tizen> 9 </since_tizen>
418 public Selector<Shadow> BoxShadow
420 get => (Selector<Shadow>)GetValue(BoxShadowProperty);
421 set => SetValue(BoxShadowProperty, value);
425 /// The radius for the rounded corners of the View.
426 /// 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).
428 /// <since_tizen> 9 </since_tizen>
429 public Vector4 CornerRadius
431 get => (Vector4)GetValue(CornerRadiusProperty);
432 set => SetValue(CornerRadiusProperty, value);
436 /// Whether the CornerRadius property value is relative (percentage [0.0f to 1.0f] of the view size) or absolute (in world units).
437 /// It is absolute by default.
438 /// When the policy is relative, the corner radius is relative to the smaller of the view's width and height.
440 /// <since_tizen> 9 </since_tizen>
441 public VisualTransformPolicyType? CornerRadiusPolicy
443 get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
444 set => SetValue(CornerRadiusPolicyProperty, value);
448 /// The width for the borderline of the View.
450 [EditorBrowsable(EditorBrowsableState.Never)]
451 public float? BorderlineWidth
453 get => (float?)GetValue(BorderlineWidthProperty);
454 set => SetValue(BorderlineWidthProperty, value);
458 /// The color for the borderline of the View.
460 [EditorBrowsable(EditorBrowsableState.Never)]
461 public Color BorderlineColor
463 get => (Color)GetValue(BorderlineColorProperty);
464 set => SetValue(BorderlineColorProperty, value);
468 /// The Relative offset for the borderline of the View.
469 /// recommand [-1.0f to 1.0f] range.
470 /// If -1.0f, borderline draw inside of View.
471 /// If 1.0f, borderline draw outside of View.
472 /// If 0.0f, borderline draw half at inside and half at outside.
474 [EditorBrowsable(EditorBrowsableState.Never)]
475 public float? BorderlineOffset
477 get => (float?)GetValue(BorderlineOffsetProperty);
478 set => SetValue(BorderlineOffsetProperty, value);
482 /// The ThemeChangeSensitive value of the View.
484 [EditorBrowsable(EditorBrowsableState.Never)]
485 public bool? ThemeChangeSensitive
487 get => (bool?)GetValue(ThemeChangeSensitiveProperty);
488 set => SetValue(ThemeChangeSensitiveProperty, value);
493 /// Allow null properties when merging it into other Theme.
494 /// If the value is true, the null properties reset target properties of the other ViewStyle with same key when merge.
495 /// It is used in <seealso cref="Theme.Merge(string)"/>, <seealso cref="Theme.Merge(Theme)"/>.
496 /// It is also used in <seealso cref="Theme.GetStyle(string)"/> when the Theme has a parent and needs to merge.
497 /// Please note that it is false by default.
499 [EditorBrowsable(EditorBrowsableState.Never)]
500 public bool SolidNull { get; set; } = false;
503 /// HashSet of dirty properties. Internal use only.
505 internal HashSet<BindableProperty> DirtyProperties { get; private set; }
507 /// <summary>Create a cloned ViewStyle.</summary>
508 [EditorBrowsable(EditorBrowsableState.Never)]
509 public ViewStyle Clone()
511 var cloned = CreateInstance();
512 cloned.CopyFrom(this);
518 /// Release instance.
520 /// <since_tizen> 9 </since_tizen>
521 public void Dispose()
524 global::System.GC.SuppressFinalize(this);
528 [EditorBrowsable(EditorBrowsableState.Never)]
529 public override void CopyFrom(BindableObject other)
531 var source = other as ViewStyle;
533 if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
538 BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
540 if (thisBindableProperties == null)
545 foreach (var sourceProperty in source.DirtyProperties)
547 var sourceValue = source.GetValue(sourceProperty);
549 if (sourceValue == null)
554 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
556 if (destinationProperty != null)
558 SetValue(destinationProperty, sourceValue);
562 IncludeDefaultStyle = source.IncludeDefaultStyle;
566 /// Release instance.
568 /// <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>
569 /// <since_tizen> 9 </since_tizen>
570 protected virtual void Dispose(bool disposing)
579 // Dispose managed state (managed objects).
581 maximumSize?.Dispose();
582 minimumSize?.Dispose();
583 orientation?.Dispose();
585 parentOrigin?.Dispose();
586 pivotPoint?.Dispose();
589 sizeModeFactor?.Dispose();
590 cornerRadius?.Dispose();
591 borderlineColor?.Dispose();
598 /// Method that is called when a bound property is changed.
600 [EditorBrowsable(EditorBrowsableState.Never)]
601 protected override void OnPropertyChangedWithData(BindableProperty property)
603 base.OnPropertyChangedWithData(property);
605 if (property != null)
607 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
611 internal ViewStyle CreateInstance()
613 return (ViewStyle)Activator.CreateInstance(GetType());
616 /// <summary>Merge other style into the current style without creating new one.</summary>
617 [EditorBrowsable(EditorBrowsableState.Never)]
618 internal void MergeDirectly(ViewStyle other)
624 /// <summary> Extension methods for ViewStyle class.</summary>
625 [EditorBrowsable(EditorBrowsableState.Never)]
626 public static class ViewStyleExtension
628 /// <summary>Merge two styles into the new one.</summary>
629 /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
630 [EditorBrowsable(EditorBrowsableState.Never)]
631 public static TOut Merge<TOut>(this TOut value, TOut other) where TOut : Tizen.NUI.BaseComponents.ViewStyle
633 var newStyle = value.Clone() as TOut;
635 newStyle?.CopyFrom(other);