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 public Vector3 SizeModeFactor
261 get => (Vector3)GetValue(SizeModeFactorProperty);
262 set => SetValue(SizeModeFactorProperty, value);
266 /// Gets or sets the width resize policy to be used.
268 /// <since_tizen> 9 </since_tizen>
269 public ResizePolicyType? WidthResizePolicy
271 get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
272 set => SetValue(WidthResizePolicyProperty, value);
276 /// Gets or sets the height resize policy to be used.
278 /// <since_tizen> 9 </since_tizen>
279 public ResizePolicyType? HeightResizePolicy
281 get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
282 set => SetValue(HeightResizePolicyProperty, value);
285 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
286 [EditorBrowsable(EditorBrowsableState.Never)]
287 public bool? WidthForHeight
289 get => (bool?)GetValue(WidthForHeightProperty);
290 set => SetValue(WidthForHeightProperty, value);
293 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
294 [EditorBrowsable(EditorBrowsableState.Never)]
295 public bool? HeightForWidth
297 get => (bool?)GetValue(HeightForWidthProperty);
298 set => SetValue(HeightForWidthProperty, value);
302 /// Gets or sets the padding for use in layout.
304 /// <since_tizen> 9 </since_tizen>
305 public Extents Padding
307 get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
308 set => SetValue(PaddingProperty, value);
312 /// Gets or sets the minimum size the view can be assigned in size negotiation.
314 /// <since_tizen> 9 </since_tizen>
315 public Size2D MinimumSize
317 get => (Size2D)GetValue(MinimumSizeProperty);
318 set => SetValue(MinimumSizeProperty, value);
322 /// Gets or sets the maximum size the view can be assigned in size negotiation.
324 /// <since_tizen> 9 </since_tizen>
325 public Size2D MaximumSize
327 get => (Size2D)GetValue(MaximumSizeProperty);
328 set => SetValue(MaximumSizeProperty, value);
331 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
332 [EditorBrowsable(EditorBrowsableState.Never)]
333 public ClippingModeType? ClippingMode
335 get => (ClippingModeType?)GetValue(ClippingModeProperty);
336 set => SetValue(ClippingModeProperty, value);
340 /// Sets the size of a view for the width, the height, and the depth.
342 /// <since_tizen> 9 </since_tizen>
345 get => (Size)GetValue(SizeProperty);
346 set => SetValue(SizeProperty, value);
350 /// Gets or sets the Margin for use in layout.
352 /// <since_tizen> 9 </since_tizen>
353 public Extents Margin
355 get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
356 set => SetValue(MarginProperty, value);
360 /// Gets or sets the color of the background of view.
361 /// The mutually exclusive with "BackgroundImage". Setting it overwrites existing "BackgroundImage".
363 /// <since_tizen> 9 </since_tizen>
364 public Selector<Color> BackgroundColor
368 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorProperty);
369 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
371 set => SetValue(BackgroundColorProperty, value);
377 [EditorBrowsable(EditorBrowsableState.Never)]
378 public Selector<Color> Color
380 get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
381 set => SetValue(ColorProperty, value);
384 /// <summary>View BackgroundBorder</summary>
385 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
386 [EditorBrowsable(EditorBrowsableState.Never)]
387 public Selector<Rectangle> BackgroundImageBorder
391 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
392 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
394 set => SetValue(BackgroundImageBorderProperty, value);
398 /// Describes a shadow as an image for a View.
399 /// It is null by default.
402 /// If BoxShadow is not null, the ImageShadow value will be ignored.
404 [EditorBrowsable(EditorBrowsableState.Never)]
405 public Selector<ImageShadow> ImageShadow
407 get => (Selector<ImageShadow>)GetValue(ImageShadowProperty);
408 set => SetValue(ImageShadowProperty, value);
412 /// Describes a box shaped shadow drawing for a View.
414 /// <since_tizen> 9 </since_tizen>
415 public Selector<Shadow> BoxShadow
417 get => (Selector<Shadow>)GetValue(BoxShadowProperty);
418 set => SetValue(BoxShadowProperty, value);
422 /// The radius for the rounded corners of the View.
423 /// 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).
424 /// Each radius will clamp internally to the half of smaller of the view's width or height.
426 /// <since_tizen> 9 </since_tizen>
427 public Vector4 CornerRadius
429 get => (Vector4)GetValue(CornerRadiusProperty);
430 set => SetValue(CornerRadiusProperty, value);
434 /// Whether the CornerRadius property value is relative (percentage [0.0f to 0.5f] of the view size) or absolute (in world units).
435 /// It is absolute by default.
436 /// When the policy is relative, the corner radius is relative to the smaller of the view's width and height.
438 /// <since_tizen> 9 </since_tizen>
439 public VisualTransformPolicyType? CornerRadiusPolicy
441 get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
442 set => SetValue(CornerRadiusPolicyProperty, value);
446 /// The width for the borderline of the View.
448 [EditorBrowsable(EditorBrowsableState.Never)]
449 public float? BorderlineWidth
451 get => (float?)GetValue(BorderlineWidthProperty);
452 set => SetValue(BorderlineWidthProperty, value);
456 /// The color for the borderline of the View.
457 /// This color is affected by View Opacity.
459 [EditorBrowsable(EditorBrowsableState.Never)]
460 public Color BorderlineColor
462 get => (Color)GetValue(BorderlineColorProperty);
463 set => SetValue(BorderlineColorProperty, value);
467 /// The Relative offset for the borderline of the View.
468 /// recommand [-1.0f to 1.0f] range.
469 /// If -1.0f, borderline draw inside of View.
470 /// If 1.0f, borderline draw outside of View.
471 /// If 0.0f, borderline draw half at inside and half at outside.
473 [EditorBrowsable(EditorBrowsableState.Never)]
474 public float? BorderlineOffset
476 get => (float?)GetValue(BorderlineOffsetProperty);
477 set => SetValue(BorderlineOffsetProperty, value);
481 /// The ThemeChangeSensitive value of the View.
483 [EditorBrowsable(EditorBrowsableState.Never)]
484 public bool? ThemeChangeSensitive
486 get => (bool?)GetValue(ThemeChangeSensitiveProperty);
487 set => SetValue(ThemeChangeSensitiveProperty, value);
492 /// Allow null properties when merging it into other Theme.
493 /// If the value is true, the null properties reset target properties of the other ViewStyle with same key when merge.
494 /// It is used in <seealso cref="Theme.Merge(string)"/>, <seealso cref="Theme.Merge(Theme)"/>.
495 /// It is also used in <seealso cref="Theme.GetStyle(string)"/> when the Theme has a parent and needs to merge.
496 /// Please note that it is false by default.
498 [EditorBrowsable(EditorBrowsableState.Never)]
499 public bool SolidNull { get; set; } = false;
502 /// HashSet of dirty properties. Internal use only.
504 internal HashSet<BindableProperty> DirtyProperties { get; private set; }
506 /// <summary>Create a cloned ViewStyle.</summary>
507 [EditorBrowsable(EditorBrowsableState.Never)]
508 public ViewStyle Clone()
510 var cloned = CreateInstance();
511 cloned.CopyFrom(this);
517 /// Release instance.
519 /// <since_tizen> 9 </since_tizen>
520 public void Dispose()
523 global::System.GC.SuppressFinalize(this);
527 [EditorBrowsable(EditorBrowsableState.Never)]
528 public override void CopyFrom(BindableObject other)
530 var source = other as ViewStyle;
532 if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
537 BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
539 if (thisBindableProperties == null)
544 foreach (var sourceProperty in source.DirtyProperties)
546 var sourceValue = source.GetValue(sourceProperty);
548 if (sourceValue == null)
553 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
555 if (destinationProperty != null)
557 SetValue(destinationProperty, sourceValue);
561 IncludeDefaultStyle = source.IncludeDefaultStyle;
562 SolidNull = source.SolidNull;
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);