[NUI] Change CornerRadius type to Vector4 from float (#2863)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / Style / ViewStyle.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 using System;
18 using System.ComponentModel;
19 using System.Collections.Generic;
20 using Tizen.NUI.Binding;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     /// <summary>
25     /// The base class for Children attributes in Components.
26     /// </summary>
27     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
28     [EditorBrowsable(EditorBrowsableState.Never)]
29     public partial class ViewStyle : BindableObject, IDisposable
30     {
31         private bool disposed = false;
32         private bool? focusable;
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;
48         private Size size;
49         private Extents margin;
50         private bool? themeChangeSensitive;
51         private Vector4 cornerRadius;
52
53         private Selector<ImageShadow> imageShadow;
54         private Selector<Shadow> boxShadow;
55         private Selector<string> backgroundImageSelector;
56         private Selector<float?> opacitySelector;
57         private Selector<Color> backgroundColorSelector;
58         private Selector<Rectangle> backgroundImageBorderSelector;
59         private Selector<Color> colorSelector;
60         private VisualTransformPolicyType? cornerRadiusPolicy;
61
62         static ViewStyle() { }
63
64         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public ViewStyle() { }
67
68         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
69         [EditorBrowsable(EditorBrowsableState.Never)]
70         public ViewStyle(ViewStyle viewAttributes)
71         {
72             CopyFrom(viewAttributes);
73         }
74
75         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
76         [EditorBrowsable(EditorBrowsableState.Never)]
77         public Selector<string> BackgroundImage
78         {
79             get
80             {
81                 Selector<string> image = (Selector<string>)GetValue(BackgroundImageSelectorProperty);
82                 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
83             }
84             set => SetValue(BackgroundImageSelectorProperty, value);
85         }
86
87         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
88         [EditorBrowsable(EditorBrowsableState.Never)]
89         public bool? Focusable
90         {
91             get => (bool?)GetValue(FocusableProperty);
92             set => SetValue(FocusableProperty, value);
93         }
94
95         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
96         [Obsolete("Deprecated. Please use Size instead.")]
97         [EditorBrowsable(EditorBrowsableState.Never)]
98         public Size2D Size2D
99         {
100             get => (Size2D)GetValue(Size2DProperty);
101             set => SetValue(Size2DProperty, value);
102         }
103
104         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
105         [EditorBrowsable(EditorBrowsableState.Never)]
106         public Selector<float?> Opacity
107         {
108             get
109             {
110                 Selector<float?> opacity = (Selector<float?>)GetValue(OpacitySelectorProperty);
111                 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
112             }
113             set => SetValue(OpacitySelectorProperty, value);
114         }
115
116         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
117         [Obsolete("Deprecated. Please use Position instead.")]
118         [EditorBrowsable(EditorBrowsableState.Never)]
119         public Position2D Position2D
120         {
121             get => (Position2D)GetValue(Position2DProperty);
122             set => SetValue(Position2DProperty, value);
123         }
124
125         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
126         [EditorBrowsable(EditorBrowsableState.Never)]
127         public bool? PositionUsesPivotPoint
128         {
129             get => (bool?)GetValue(PositionUsesPivotPointProperty);
130             set => SetValue(PositionUsesPivotPointProperty, value);
131         }
132
133         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
134         [EditorBrowsable(EditorBrowsableState.Never)]
135         public Position ParentOrigin
136         {
137             get => (Position)GetValue(ParentOriginProperty);
138             set => SetValue(ParentOriginProperty, value);
139         }
140
141         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
142         [EditorBrowsable(EditorBrowsableState.Never)]
143         public Position PivotPoint
144         {
145             get => (Position)GetValue(PivotPointProperty);
146             set => SetValue(PivotPointProperty, value);
147         }
148
149         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
150         [EditorBrowsable(EditorBrowsableState.Never)]
151         public float? SizeWidth
152         {
153             get => (float?)GetValue(SizeWidthProperty);
154             set => SetValue(SizeWidthProperty, value);
155         }
156
157         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
158         [EditorBrowsable(EditorBrowsableState.Never)]
159         public float? SizeHeight
160         {
161             get => (float?)GetValue(SizeHeightProperty);
162             set => SetValue(SizeHeightProperty, value);
163         }
164
165         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
166         [EditorBrowsable(EditorBrowsableState.Never)]
167         public Position Position
168         {
169             get => (Position)GetValue(PositionProperty);
170             set => SetValue(PositionProperty, value);
171         }
172
173         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
174         [EditorBrowsable(EditorBrowsableState.Never)]
175         public float? PositionX
176         {
177             get => (float?)GetValue(PositionXProperty);
178             set => SetValue(PositionXProperty, value);
179         }
180
181         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
182         [EditorBrowsable(EditorBrowsableState.Never)]
183         public float? PositionY
184         {
185             get => (float?)GetValue(PositionYProperty);
186             set => SetValue(PositionYProperty, value);
187         }
188
189         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
190         [EditorBrowsable(EditorBrowsableState.Never)]
191         public Rotation Orientation
192         {
193             get => (Rotation)GetValue(OrientationProperty);
194             set => SetValue(OrientationProperty, value);
195         }
196
197         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
198         [EditorBrowsable(EditorBrowsableState.Never)]
199         public DrawModeType? DrawMode
200         {
201             get => (DrawModeType?)GetValue(DrawModeProperty);
202             set => SetValue(DrawModeProperty, value);
203         }
204
205         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
206         [EditorBrowsable(EditorBrowsableState.Never)]
207         public Vector3 SizeModeFactor
208         {
209             get => (Vector3)GetValue(SizeModeFactorProperty);
210             set => SetValue(SizeModeFactorProperty, value);
211         }
212
213         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
214         [EditorBrowsable(EditorBrowsableState.Never)]
215         public ResizePolicyType? WidthResizePolicy
216         {
217             get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
218             set => SetValue(WidthResizePolicyProperty, value);
219         }
220
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 ResizePolicyType? HeightResizePolicy
224         {
225             get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
226             set => SetValue(HeightResizePolicyProperty, value);
227         }
228
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 bool? WidthForHeight
232         {
233             get => (bool?)GetValue(WidthForHeightProperty);
234             set => SetValue(WidthForHeightProperty, value);
235         }
236
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 bool? HeightForWidth
240         {
241             get => (bool?)GetValue(HeightForWidthProperty);
242             set => SetValue(HeightForWidthProperty, value);
243         }
244
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 Extents Padding
248         {
249             get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
250             set => SetValue(PaddingProperty, value);
251         }
252
253         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
254         [EditorBrowsable(EditorBrowsableState.Never)]
255         public Size2D MinimumSize
256         {
257             get => (Size2D)GetValue(MinimumSizeProperty);
258             set => SetValue(MinimumSizeProperty, value);
259         }
260
261         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
262         [EditorBrowsable(EditorBrowsableState.Never)]
263         public Size2D MaximumSize
264         {
265             get => (Size2D)GetValue(MaximumSizeProperty);
266             set => SetValue(MaximumSizeProperty, value);
267         }
268
269         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
270         [EditorBrowsable(EditorBrowsableState.Never)]
271         public ClippingModeType? ClippingMode
272         {
273             get => (ClippingModeType?)GetValue(ClippingModeProperty);
274             set => SetValue(ClippingModeProperty, value);
275         }
276
277         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
278         [EditorBrowsable(EditorBrowsableState.Never)]
279         public Size Size
280         {
281             get => (Size)GetValue(SizeProperty);
282             set => SetValue(SizeProperty, value);
283         }
284
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 Extents Margin
288         {
289             get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
290             set => SetValue(MarginProperty, value);
291         }
292
293         /// <summary> View BackgroundColor </summary>
294         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
295         [EditorBrowsable(EditorBrowsableState.Never)]
296         public Selector<Color> BackgroundColor
297         {
298             get
299             {
300                 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorSelectorProperty);
301                 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
302             }
303             set => SetValue(BackgroundColorSelectorProperty, value);
304         }
305
306         /// <summary>
307         /// Color
308         /// </summary>
309         [EditorBrowsable(EditorBrowsableState.Never)]
310         public Selector<Color> Color
311         {
312             get => (Selector<Color>)GetValue(ColorSelectorProperty) ?? (colorSelector = new Selector<Color>());
313             set => SetValue(ColorSelectorProperty, value);
314         }
315
316         /// <summary>View BackgroundBorder</summary>
317         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
318         [EditorBrowsable(EditorBrowsableState.Never)]
319         public Selector<Rectangle> BackgroundImageBorder
320         {
321             get
322             {
323                 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderSelectorProperty);
324                 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
325             }
326             set => SetValue(BackgroundImageBorderSelectorProperty, value);
327         }
328
329         /// <summary>
330         /// Describes a shadow as an image for a View.
331         /// It is null by default.
332         /// </summary>
333         /// <remarks>
334         /// If BoxShadow is not null, the ImageShadow value will be ignored.
335         /// </remarks>
336         [EditorBrowsable(EditorBrowsableState.Never)]
337         public Selector<ImageShadow> ImageShadow
338         {
339             get => (Selector<ImageShadow>)GetValue(ImageShadowSelectorProperty);
340             set => SetValue(ImageShadowSelectorProperty, value);
341         }
342
343         /// <summary>
344         /// Describes a box shaped shadow drawing for a View.
345         /// It is null by default.
346         /// </summary>
347         [EditorBrowsable(EditorBrowsableState.Never)]
348         public Selector<Shadow> BoxShadow
349         {
350             get => (Selector<Shadow>)GetValue(BoxShadowSelectorProperty);
351             set => SetValue(BoxShadowSelectorProperty, value);
352         }
353
354         /// <summary>
355         /// The radius for the rounded corners of the View.
356         /// 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).
357         /// </summary>
358         [EditorBrowsable(EditorBrowsableState.Never)]
359         public Vector4 CornerRadius
360         {
361             get => (Vector4)GetValue(CornerRadiusProperty);
362             set => SetValue(CornerRadiusProperty, value);
363         }
364
365         /// <summary>
366         /// Whether the CornerRadius property value is relative (percentage [0.0f to 1.0f] of the view size) or absolute (in world units).
367         /// It is absolute by default.
368         /// When the policy is relative, the corner radius is relative to the smaller of the view's width and height.
369         /// </summary>
370         [EditorBrowsable(EditorBrowsableState.Never)]
371         public VisualTransformPolicyType? CornerRadiusPolicy
372         {
373             get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
374             set => SetValue(CornerRadiusPolicyProperty, value);
375         }
376
377         /// <summary>
378         /// The ThemeChangeSensitive value of the View.
379         /// </summary>
380         [EditorBrowsable(EditorBrowsableState.Never)]
381         public bool? ThemeChangeSensitive
382         {
383             get => (bool?)GetValue(ThemeChangeSensitiveProperty);
384             set => SetValue(ThemeChangeSensitiveProperty, value);
385         }
386
387
388         /// <summary>
389         /// Allow null properties when merging it into other Theme.
390         /// If the value is true, the null properties reset target properties of the other ViewStyle with same key when merge.
391         /// It is used in <seealso cref="Theme.Merge(string)"/>, <seealso cref="Theme.Merge(Theme)"/>.
392         /// It is also used in <seealso cref="Theme.GetStyle(string)"/> when the Theme has a parent and needs to merge.
393         /// Please note that it is false by default.
394         /// </summary>
395         [EditorBrowsable(EditorBrowsableState.Never)]
396         public bool SolidNull { get; set; } = false;
397
398         /// <summary>
399         /// HashSet of dirty properties. Internal use only.
400         /// </summary>
401         internal HashSet<BindableProperty> DirtyProperties { get; private set; }
402
403         /// <summary>
404         /// Set style's bindable properties from the view.
405         /// </summary>
406         /// <param name="view">The view that includes property data.</param>
407         [EditorBrowsable(EditorBrowsableState.Never)]
408         public virtual void CopyPropertiesFromView(View view)
409         {
410             if (view == null) return;
411
412             BindableProperty.GetBindablePropertysOfType(GetType(), out var styleProperties);
413             BindableProperty.GetBindablePropertysOfType(view.GetType(), out var viewProperties);
414
415
416             if (styleProperties == null || viewProperties == null) return;
417
418             foreach (var stylePropertyItem in styleProperties)
419             {
420                 viewProperties.TryGetValue(stylePropertyItem.Key, out var viewProperty);
421
422                 if (viewProperty == null) continue;
423
424                 SetValue(stylePropertyItem.Value, view.GetValue(viewProperty));
425             }
426         }
427
428         /// <summary>Create a cloned ViewStyle.</summary>
429         [EditorBrowsable(EditorBrowsableState.Never)]
430         public ViewStyle Clone()
431         {
432             var cloned = CreateInstance();
433             cloned.CopyFrom(this);
434
435             return cloned;
436         }
437
438         /// <summary>
439         /// Release instance.
440         /// </summary>
441         [EditorBrowsable(EditorBrowsableState.Never)]
442         public void Dispose()
443         {
444             Dispose(true);
445             global::System.GC.SuppressFinalize(this);
446         }
447
448         /// <summary>Copy properties of other ViewStyle to this.</summary>
449         /// <param name="other">The other BindableProperty merge to this.</param>
450         [EditorBrowsable(EditorBrowsableState.Never)]
451         public override void CopyFrom(BindableObject other)
452         {
453             var source = other as ViewStyle;
454
455             if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
456             {
457                 return;
458             }
459
460             BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
461
462             if (thisBindableProperties == null)
463             {
464                 return;
465             }
466
467             foreach (var sourceProperty in source.DirtyProperties)
468             {
469                 var sourceValue = source.GetValue(sourceProperty);
470
471                 if (sourceValue == null)
472                 {
473                     continue;
474                 }
475
476                 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
477
478                 if (destinationProperty != null)
479                 {
480                     SetValue(destinationProperty, sourceValue);
481                 }
482             }
483         }
484
485         /// <summary>
486         /// Release instance.
487         /// </summary>
488         [EditorBrowsable(EditorBrowsableState.Never)]
489         protected virtual void Dispose(bool disposing)
490         {
491             if (disposed)
492             {
493                 return;
494             }
495
496             if (disposing)
497             {
498                 // Dispose managed state (managed objects).
499                 margin?.Dispose();
500                 maximumSize?.Dispose();
501                 minimumSize?.Dispose();
502                 orientation?.Dispose();
503                 padding?.Dispose();
504                 parentOrigin?.Dispose();
505                 pivotPoint?.Dispose();
506                 position?.Dispose();
507                 size?.Dispose();
508                 sizeModeFactor?.Dispose();
509             }
510
511             disposed = true;
512         }
513
514         /// <summary>
515         /// Method that is called when a bound property is changed.
516         /// </summary>
517         [EditorBrowsable(EditorBrowsableState.Never)]
518         protected override void OnPropertyChangedWithData(BindableProperty property)
519         {
520             base.OnPropertyChangedWithData(property);
521
522             if (property != null)
523             {
524                 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
525             }
526         }
527
528         internal ViewStyle CreateInstance()
529         {
530             return (ViewStyle)Activator.CreateInstance(GetType());
531         }
532
533         /// <summary>Merge other style into the current style without creating new one.</summary>
534         [EditorBrowsable(EditorBrowsableState.Never)]
535         internal void MergeDirectly(ViewStyle other)
536         {
537             CopyFrom(other);
538         }
539     }
540
541     /// <summary> Extension methods for ViewStyle class.</summary>
542     [EditorBrowsable(EditorBrowsableState.Never)]
543     public static class ViewStyleExtension
544     {
545         /// <summary>Merge two styles into the new one.</summary>
546         /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
547         [EditorBrowsable(EditorBrowsableState.Never)]
548         public static TOut Merge<TOut>(this TOut value, TOut other) where TOut : Tizen.NUI.BaseComponents.ViewStyle
549         {
550             var newStyle = value.Clone() as TOut;
551
552             newStyle.CopyFrom(other);
553
554             return newStyle;
555         }
556     }
557 }