[NUI] Add FocusableInTouch property
[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 of style attributes for a view.
26     /// </summary>
27     /// <since_tizen> 9 </since_tizen>
28     public partial class ViewStyle : BindableObject, IDisposable
29     {
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;
48         private Size size;
49         private Extents margin;
50         private bool? themeChangeSensitive;
51         private Vector4 cornerRadius;
52         private float? borderlineWidth;
53         private Color borderlineColor;
54         private float? borderlineOffset;
55
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;
64
65         static ViewStyle() { }
66
67         /// <summary>
68         /// Create an empty style instance.
69         /// </summary>
70         /// <since_tizen> 9 </since_tizen>
71         public ViewStyle() { }
72
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)
76         {
77             CopyFrom(viewAttributes);
78         }
79
80         /// <summary>
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.
83         /// </summary>
84         [EditorBrowsable(EditorBrowsableState.Never)]
85         public bool IncludeDefaultStyle { get; set; } = false;
86
87         /// <summary>
88         /// Gets or sets the image resource url of the background of view.
89         /// The mutually exclusive with "BackgroundColor". Setting it overwrites existing "BackgroundColor".
90         /// </summary>
91         /// <since_tizen> 9 </since_tizen>
92         public Selector<string> BackgroundImage
93         {
94             get
95             {
96                 Selector<string> image = (Selector<string>)GetValue(BackgroundImageProperty);
97                 return (null != image) ? image : backgroundImageSelector = new Selector<string>();
98             }
99             set => SetValue(BackgroundImageProperty, value);
100         }
101
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
105         {
106             get => (bool?)GetValue(FocusableProperty);
107             set => SetValue(FocusableProperty, value);
108         }
109
110         /// <summary>
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.
114         /// </summary>
115         [EditorBrowsable(EditorBrowsableState.Never)]
116         public bool? FocusableInTouch
117         {
118             get => (bool?)GetValue(FocusableInTouchProperty);
119             set => SetValue(FocusableInTouchProperty, value);
120         }
121
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)]
125         public Size2D Size2D
126         {
127             get => (Size2D)GetValue(Size2DProperty);
128             set => SetValue(Size2DProperty, value);
129         }
130
131         /// <summary>
132         /// Defines view's opacity value.
133         /// </summary>
134         /// <since_tizen> 9 </since_tizen>
135         public Selector<float?> Opacity
136         {
137             get
138             {
139                 Selector<float?> opacity = (Selector<float?>)GetValue(OpacityProperty);
140                 return (null != opacity) ? opacity : opacitySelector = new Selector<float?>();
141             }
142             set => SetValue(OpacityProperty, value);
143         }
144
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
149         {
150             get => (Position2D)GetValue(Position2DProperty);
151             set => SetValue(Position2DProperty, value);
152         }
153
154         /// <summary>
155         /// Determines whether the pivot point should be used to determine the position of the view.
156         /// </summary>
157         /// <since_tizen> 9 </since_tizen>
158         public bool? PositionUsesPivotPoint
159         {
160             get => (bool?)GetValue(PositionUsesPivotPointProperty);
161             set => SetValue(PositionUsesPivotPointProperty, value);
162         }
163
164         /// <summary>
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 />
169         /// </summary>
170         /// <since_tizen> 9 </since_tizen>
171         public Position ParentOrigin
172         {
173             get => (Position)GetValue(ParentOriginProperty);
174             set => SetValue(ParentOriginProperty, value);
175         }
176
177         /// <summary>
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 />
183         /// </summary>
184         /// <since_tizen> 9 </since_tizen>
185         public Position PivotPoint
186         {
187             get => (Position)GetValue(PivotPointProperty);
188             set => SetValue(PivotPointProperty, value);
189         }
190
191         /// <summary>
192         /// Gets or sets the width of the view.
193         /// </summary>
194         /// <since_tizen> 9 </since_tizen>
195         public float? SizeWidth
196         {
197             get => (float?)GetValue(SizeWidthProperty);
198             set => SetValue(SizeWidthProperty, value);
199         }
200
201         /// <summary>
202         /// Gets or sets the height of the view.
203         /// </summary>
204         /// <since_tizen> 9 </since_tizen>
205         public float? SizeHeight
206         {
207             get => (float?)GetValue(SizeHeightProperty);
208             set => SetValue(SizeHeightProperty, value);
209         }
210
211         /// <summary>
212         /// Gets or sets the position of the view.
213         /// </summary>
214         /// <since_tizen> 9 </since_tizen>
215         public Position Position
216         {
217             get => (Position)GetValue(PositionProperty);
218             set => SetValue(PositionProperty, 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 float? PositionX
224         {
225             get => (float?)GetValue(PositionXProperty);
226             set => SetValue(PositionXProperty, 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 float? PositionY
232         {
233             get => (float?)GetValue(PositionYProperty);
234             set => SetValue(PositionYProperty, 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 Rotation Orientation
240         {
241             get => (Rotation)GetValue(OrientationProperty);
242             set => SetValue(OrientationProperty, 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 DrawModeType? DrawMode
248         {
249             get => (DrawModeType?)GetValue(DrawModeProperty);
250             set => SetValue(DrawModeProperty, value);
251         }
252
253         /// <summary>
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 />
257         /// </summary>
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
261         {
262             get => (Vector3)GetValue(SizeModeFactorProperty);
263             set => SetValue(SizeModeFactorProperty, value);
264         }
265
266         /// <summary>
267         /// Gets or sets the width resize policy to be used.
268         /// </summary>
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
272         {
273             get => (ResizePolicyType?)GetValue(WidthResizePolicyProperty);
274             set => SetValue(WidthResizePolicyProperty, value);
275         }
276
277         /// <summary>
278         /// Gets or sets the height resize policy to be used.
279         /// </summary>
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
283         {
284             get => (ResizePolicyType?)GetValue(HeightResizePolicyProperty);
285             set => SetValue(HeightResizePolicyProperty, value);
286         }
287
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
291         {
292             get => (bool?)GetValue(WidthForHeightProperty);
293             set => SetValue(WidthForHeightProperty, value);
294         }
295
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
299         {
300             get => (bool?)GetValue(HeightForWidthProperty);
301             set => SetValue(HeightForWidthProperty, value);
302         }
303
304         /// <summary>
305         /// Gets or sets the padding for use in layout.
306         /// </summary>
307         /// <since_tizen> 9 </since_tizen>
308         public Extents Padding
309         {
310             get => (Extents)GetValue(PaddingProperty) ?? (padding = new Extents());
311             set => SetValue(PaddingProperty, value);
312         }
313
314         /// <summary>
315         /// Gets or sets the minimum size the view can be assigned in size negotiation.
316         /// </summary>
317         /// <since_tizen> 9 </since_tizen>
318         public Size2D MinimumSize
319         {
320             get => (Size2D)GetValue(MinimumSizeProperty);
321             set => SetValue(MinimumSizeProperty, value);
322         }
323
324         /// <summary>
325         /// Gets or sets the maximum size the view can be assigned in size negotiation.
326         /// </summary>
327         /// <since_tizen> 9 </since_tizen>
328         public Size2D MaximumSize
329         {
330             get => (Size2D)GetValue(MaximumSizeProperty);
331             set => SetValue(MaximumSizeProperty, value);
332         }
333
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
337         {
338             get => (ClippingModeType?)GetValue(ClippingModeProperty);
339             set => SetValue(ClippingModeProperty, value);
340         }
341
342         /// <summary>
343         /// Sets the size of a view for the width, the height, and the depth.
344         /// </summary>
345         /// <since_tizen> 9 </since_tizen>
346         public Size Size
347         {
348             get => (Size)GetValue(SizeProperty);
349             set => SetValue(SizeProperty, value);
350         }
351
352         /// <summary>
353         /// Gets or sets the Margin for use in layout.
354         /// </summary>
355         /// <since_tizen> 9 </since_tizen>
356         public Extents Margin
357         {
358             get => (Extents)GetValue(MarginProperty) ?? (margin = new Extents());
359             set => SetValue(MarginProperty, value);
360         }
361
362         /// <summary>
363         /// Gets or sets the color of the background of view.
364         /// The mutually exclusive with "BackgroundImage". Setting it overwrites existing "BackgroundImage".
365         /// </summary>
366         /// <since_tizen> 9 </since_tizen>
367         public Selector<Color> BackgroundColor
368         {
369             get
370             {
371                 Selector<Color> color = (Selector<Color>)GetValue(BackgroundColorProperty);
372                 return (null != color) ? color : backgroundColorSelector = new Selector<Color>();
373             }
374             set => SetValue(BackgroundColorProperty, value);
375         }
376
377         /// <summary>
378         /// Color
379         /// </summary>
380         [EditorBrowsable(EditorBrowsableState.Never)]
381         public Selector<Color> Color
382         {
383             get => (Selector<Color>)GetValue(ColorProperty) ?? (colorSelector = new Selector<Color>());
384             set => SetValue(ColorProperty, value);
385         }
386
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
391         {
392             get
393             {
394                 Selector<Rectangle> border = (Selector<Rectangle>)GetValue(BackgroundImageBorderProperty);
395                 return (null != border) ? border : backgroundImageBorderSelector = new Selector<Rectangle>();
396             }
397             set => SetValue(BackgroundImageBorderProperty, value);
398         }
399
400         /// <summary>
401         /// Describes a shadow as an image for a View.
402         /// It is null by default.
403         /// </summary>
404         /// <remarks>
405         /// If BoxShadow is not null, the ImageShadow value will be ignored.
406         /// </remarks>
407         [EditorBrowsable(EditorBrowsableState.Never)]
408         public Selector<ImageShadow> ImageShadow
409         {
410             get => (Selector<ImageShadow>)GetValue(ImageShadowProperty);
411             set => SetValue(ImageShadowProperty, value);
412         }
413
414         /// <summary>
415         /// Describes a box shaped shadow drawing for a View.
416         /// </summary>
417         /// <since_tizen> 9 </since_tizen>
418         public Selector<Shadow> BoxShadow
419         {
420             get => (Selector<Shadow>)GetValue(BoxShadowProperty);
421             set => SetValue(BoxShadowProperty, value);
422         }
423
424         /// <summary>
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).
427         /// </summary>
428         /// <since_tizen> 9 </since_tizen>
429         public Vector4 CornerRadius
430         {
431             get => (Vector4)GetValue(CornerRadiusProperty);
432             set => SetValue(CornerRadiusProperty, value);
433         }
434
435         /// <summary>
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.
439         /// </summary>
440         /// <since_tizen> 9 </since_tizen>
441         public VisualTransformPolicyType? CornerRadiusPolicy
442         {
443             get => (VisualTransformPolicyType?)GetValue(CornerRadiusPolicyProperty);
444             set => SetValue(CornerRadiusPolicyProperty, value);
445         }
446
447         /// <summary>
448         /// The width for the borderline of the View.
449         /// </summary>
450         [EditorBrowsable(EditorBrowsableState.Never)]
451         public float? BorderlineWidth
452         {
453             get => (float?)GetValue(BorderlineWidthProperty);
454             set => SetValue(BorderlineWidthProperty, value);
455         }
456
457         /// <summary>
458         /// The color for the borderline of the View.
459         /// </summary>
460         [EditorBrowsable(EditorBrowsableState.Never)]
461         public Color BorderlineColor
462         {
463             get => (Color)GetValue(BorderlineColorProperty);
464             set => SetValue(BorderlineColorProperty, value);
465         }
466
467         /// <summary>
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.
473         /// </summary>
474         [EditorBrowsable(EditorBrowsableState.Never)]
475         public float? BorderlineOffset
476         {
477             get => (float?)GetValue(BorderlineOffsetProperty);
478             set => SetValue(BorderlineOffsetProperty, value);
479         }
480
481         /// <summary>
482         /// The ThemeChangeSensitive value of the View.
483         /// </summary>
484         [EditorBrowsable(EditorBrowsableState.Never)]
485         public bool? ThemeChangeSensitive
486         {
487             get => (bool?)GetValue(ThemeChangeSensitiveProperty);
488             set => SetValue(ThemeChangeSensitiveProperty, value);
489         }
490
491
492         /// <summary>
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.
498         /// </summary>
499         [EditorBrowsable(EditorBrowsableState.Never)]
500         public bool SolidNull { get; set; } = false;
501
502         /// <summary>
503         /// HashSet of dirty properties. Internal use only.
504         /// </summary>
505         internal HashSet<BindableProperty> DirtyProperties { get; private set; }
506
507         /// <summary>Create a cloned ViewStyle.</summary>
508         [EditorBrowsable(EditorBrowsableState.Never)]
509         public ViewStyle Clone()
510         {
511             var cloned = CreateInstance();
512             cloned.CopyFrom(this);
513
514             return cloned;
515         }
516
517         /// <summary>
518         /// Release instance.
519         /// </summary>
520         /// <since_tizen> 9 </since_tizen>
521         public void Dispose()
522         {
523             Dispose(true);
524             global::System.GC.SuppressFinalize(this);
525         }
526
527         /// <inheritdoc/>
528         [EditorBrowsable(EditorBrowsableState.Never)]
529         public override void CopyFrom(BindableObject other)
530         {
531             var source = other as ViewStyle;
532
533             if (source == null || source.DirtyProperties == null || source.DirtyProperties.Count == 0)
534             {
535                 return;
536             }
537
538             BindableProperty.GetBindablePropertysOfType(GetType(), out var thisBindableProperties);
539
540             if (thisBindableProperties == null)
541             {
542                 return;
543             }
544
545             foreach (var sourceProperty in source.DirtyProperties)
546             {
547                 var sourceValue = source.GetValue(sourceProperty);
548
549                 if (sourceValue == null)
550                 {
551                     continue;
552                 }
553
554                 thisBindableProperties.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
555
556                 if (destinationProperty != null)
557                 {
558                     SetValue(destinationProperty, sourceValue);
559                 }
560             }
561
562             IncludeDefaultStyle = source.IncludeDefaultStyle;
563         }
564
565         /// <summary>
566         /// Release instance.
567         /// </summary>
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)
571         {
572             if (disposed)
573             {
574                 return;
575             }
576
577             if (disposing)
578             {
579                 // Dispose managed state (managed objects).
580                 margin?.Dispose();
581                 maximumSize?.Dispose();
582                 minimumSize?.Dispose();
583                 orientation?.Dispose();
584                 padding?.Dispose();
585                 parentOrigin?.Dispose();
586                 pivotPoint?.Dispose();
587                 position?.Dispose();
588                 size?.Dispose();
589                 sizeModeFactor?.Dispose();
590                 cornerRadius?.Dispose();
591                 borderlineColor?.Dispose();
592             }
593
594             disposed = true;
595         }
596
597         /// <summary>
598         /// Method that is called when a bound property is changed.
599         /// </summary>
600         [EditorBrowsable(EditorBrowsableState.Never)]
601         protected override void OnPropertyChangedWithData(BindableProperty property)
602         {
603             base.OnPropertyChangedWithData(property);
604
605             if (property != null)
606             {
607                 (DirtyProperties ?? (DirtyProperties = new HashSet<BindableProperty>())).Add(property);
608             }
609         }
610
611         internal ViewStyle CreateInstance()
612         {
613             return (ViewStyle)Activator.CreateInstance(GetType());
614         }
615
616         /// <summary>Merge other style into the current style without creating new one.</summary>
617         [EditorBrowsable(EditorBrowsableState.Never)]
618         internal void MergeDirectly(ViewStyle other)
619         {
620             CopyFrom(other);
621         }
622     }
623
624     /// <summary> Extension methods for ViewStyle class.</summary>
625     [EditorBrowsable(EditorBrowsableState.Never)]
626     public static class ViewStyleExtension
627     {
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
632         {
633             var newStyle = value.Clone() as TOut;
634
635             newStyle?.CopyFrom(other);
636
637             return newStyle;
638         }
639     }
640 }