[NUI] Make bindable properties in Style and View have same property name. (#2850)
[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(BackgroundImageProperty);
82                 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
83             }
84             set => SetValue(BackgroundImageProperty, 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(OpacityProperty);
111                 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
112             }
113             set => SetValue(OpacityProperty, 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(BackgroundColorProperty);
301                 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
302             }
303             set => SetValue(BackgroundColorProperty, value);
304         }
305
306         /// <summary>
307         /// Color
308         /// </summary>
309         [EditorBrowsable(EditorBrowsableState.Never)]
310         public Selector<Color> Color
311         {
312             get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
313             set => SetValue(ColorProperty, 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(BackgroundImageBorderProperty);
324                 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
325             }
326             set => SetValue(BackgroundImageBorderProperty, 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(ImageShadowProperty);
340             set => SetValue(ImageShadowProperty, 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(BoxShadowProperty);
351             set => SetValue(BoxShadowProperty, 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>Create a cloned ViewStyle.</summary>
404         [EditorBrowsable(EditorBrowsableState.Never)]
405         public ViewStyle Clone()
406         {
407             var cloned = CreateInstance();
408             cloned.CopyFrom(this);
409
410             return cloned;
411         }
412
413         /// <summary>
414         /// Release instance.
415         /// </summary>
416         [EditorBrowsable(EditorBrowsableState.Never)]
417         public void Dispose()
418         {
419             Dispose(true);
420             global::System.GC.SuppressFinalize(this);
421         }
422
423         /// <summary>Copy properties of other ViewStyle to this.</summary>
424         /// <param name="other">The other BindableProperty merge to this.</param>
425         [EditorBrowsable(EditorBrowsableState.Never)]
426         public override void CopyFrom(BindableObject other)
427         {
428             var source = other as ViewStyle;
429
430             if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
431             {
432                 return;
433             }
434
435             BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
436
437             if (thisBindableProperties == null)
438             {
439                 return;
440             }
441
442             foreach (var sourceProperty in source.DirtyProperties)
443             {
444                 var sourceValue = source.GetValue(sourceProperty);
445
446                 if (sourceValue == null)
447                 {
448                     continue;
449                 }
450
451                 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
452
453                 if (destinationProperty != null)
454                 {
455                     SetValue(destinationProperty, sourceValue);
456                 }
457             }
458         }
459
460         /// <summary>
461         /// Release instance.
462         /// </summary>
463         [EditorBrowsable(EditorBrowsableState.Never)]
464         protected virtual void Dispose(bool disposing)
465         {
466             if (disposed)
467             {
468                 return;
469             }
470
471             if (disposing)
472             {
473                 // Dispose managed state (managed objects).
474                 margin?.Dispose();
475                 maximumSize?.Dispose();
476                 minimumSize?.Dispose();
477                 orientation?.Dispose();
478                 padding?.Dispose();
479                 parentOrigin?.Dispose();
480                 pivotPoint?.Dispose();
481                 position?.Dispose();
482                 size?.Dispose();
483                 sizeModeFactor?.Dispose();
484             }
485
486             disposed = true;
487         }
488
489         /// <summary>
490         /// Method that is called when a bound property is changed.
491         /// </summary>
492         [EditorBrowsable(EditorBrowsableState.Never)]
493         protected override void OnPropertyChangedWithData(BindableProperty property)
494         {
495             base.OnPropertyChangedWithData(property);
496
497             if (property != null)
498             {
499                 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
500             }
501         }
502
503         internal ViewStyle CreateInstance()
504         {
505             return (ViewStyle)Activator.CreateInstance(GetType());
506         }
507
508         /// <summary>Merge other style into the current style without creating new one.</summary>
509         [EditorBrowsable(EditorBrowsableState.Never)]
510         internal void MergeDirectly(ViewStyle other)
511         {
512             CopyFrom(other);
513         }
514     }
515
516     /// <summary> Extension methods for ViewStyle class.</summary>
517     [EditorBrowsable(EditorBrowsableState.Never)]
518     public static class ViewStyleExtension
519     {
520         /// <summary>Merge two styles into the new one.</summary>
521         /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
522         [EditorBrowsable(EditorBrowsableState.Never)]
523         public static TOut Merge<TOut>(this TOut value, TOut other) where TOut : Tizen.NUI.BaseComponents.ViewStyle
524         {
525             var newStyle = value.Clone() as TOut;
526
527             newStyle.CopyFrom(other);
528
529             return newStyle;
530         }
531     }
532 }