[NUI] Implement shadow in View (#1223)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / ViewProperty / TransformablePropertyMap.cs
1 /*
2  * Copyright(c) 2019 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
18  using System.ComponentModel;
19
20 namespace Tizen.NUI
21 {
22
23     /// <summary>
24     /// The property map class that has transform property for one of its items.
25     /// This class can be used to convert visual properties to map.
26     /// </summary>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     abstract public class TransformablePropertyMap
29     {
30         internal delegate void PropertyChangedCallback(TransformablePropertyMap instance);
31
32         internal PropertyChangedCallback OnPropertyChanged = null;
33
34         private static readonly Vector2 noOffset = new Vector2(0, 0);
35
36         private static readonly Vector2 noScale = new Vector2(1, 1);
37
38         private static readonly Vector2 defaultOffset = new Vector2(0, 0);
39
40         private static readonly Vector2 defaultOffsetPolicy = new Vector2((int)VisualTransformPolicyType.Absolute, (int)VisualTransformPolicyType.Absolute);
41
42
43         /// <summary>
44         /// The offset value that tansform should have in common
45         /// </summary>
46         protected internal Vector2 offset = defaultOffset;
47
48         /// <summary>
49         /// The size value in scale that tansform should have in common
50         /// </summary>
51         protected internal Vector2 scale = noScale;
52
53         /// <summary>
54         /// The output property map
55         /// </summary>
56         protected internal PropertyMap propertyMap;
57
58         /// <summary>
59         /// The transform property map
60         /// </summary>
61         protected internal PropertyMap transformMap;
62
63         /// <summary>
64         /// Constructor
65         /// </summary>
66         [EditorBrowsable(EditorBrowsableState.Never)]
67         public TransformablePropertyMap()
68         {
69             // Initialize maps
70             propertyMap = new PropertyMap();
71             transformMap = new PropertyMap();
72
73             // Offet has default value, so need to update map
74             transformMap[(int)VisualTransformPropertyType.OffsetPolicy] = new PropertyValue(defaultOffsetPolicy);
75             transformMap[(int)VisualTransformPropertyType.Offset] = PropertyValue.CreateWithGuard(offset);
76             propertyMap[Visual.Property.Transform] = new PropertyValue(transformMap);
77         }
78
79         private void OnOffsetChanged(float x, float y)
80         {
81             UpdateOffset();
82         }
83
84         private void OnScaleChanged(float widht, float height)
85         {
86             UpdateScale();
87         }
88
89         private void UpdateOffset()
90         {
91             if (!ClearTransformMapIfNeeds())
92             {
93                 transformMap[(int)VisualTransformPropertyType.Offset] = PropertyValue.CreateWithGuard(offset);
94                 propertyMap[Visual.Property.Transform] = new PropertyValue(transformMap);
95             }
96             OnPropertyChanged?.Invoke(this);
97         }
98
99         private void UpdateScale()
100         {
101             if (!ClearTransformMapIfNeeds())
102             {
103                 transformMap[(int)VisualTransformPropertyType.Size] = PropertyValue.CreateWithGuard(scale);
104                 propertyMap[Visual.Property.Transform] = new PropertyValue(transformMap);
105             }
106             OnPropertyChanged?.Invoke(this);
107         }
108
109         /// <summary>
110         /// Indicates whether the transform map is needed or not.
111         /// This checks offset and scale values are valid.
112         /// It can be overwritten in the derived class.
113         /// </summary>
114         virtual protected internal bool NeedTransformMap()
115         {
116             return (offset != null && !offset.Equals(noOffset)) || (scale != null && !scale.Equals(noScale));
117         }
118
119         /// <summary>
120         /// If this map does not need to have transform property(= no offset and no size),
121         /// clear existing transform map and return true.
122         /// Return false when it needs to transform.
123         /// </summary>
124         protected internal bool ClearTransformMapIfNeeds()
125         {
126             if (!NeedTransformMap())
127             {
128                 transformMap.Clear();
129                 transformMap[(int)VisualTransformPropertyType.OffsetPolicy] = new PropertyValue(defaultOffsetPolicy);
130                 propertyMap[Visual.Property.Transform] = new PropertyValue();
131                 return true;
132             }
133             return false;
134         }
135
136         /// <summary>
137         /// The position offset value (x, y) from the top left corner.
138         /// </summary>
139         [EditorBrowsable(EditorBrowsableState.Never)]
140         public Vector2 Offset
141         {
142             get
143             {
144                 return offset;
145             }
146             set
147             {
148                 offset = value == null? null : new Vector2(OnOffsetChanged, value);
149                 UpdateOffset();
150             }
151         }
152
153         /// <summary>
154         /// The value indicates percentage of the container size. <br />
155         /// e.g. (0.5f, 1.0f) means 50% of the container's width and 100% of container's height.
156         /// </summary>
157         public Vector2 Scale
158         {
159             get
160             {
161                 return scale;
162             }
163             set
164             {
165                 scale = value == null? null : new Vector2(OnScaleChanged, value);
166                 UpdateScale();
167             }
168         }
169
170         abstract internal string ToDebugString();
171
172         abstract internal bool IsValid();
173
174         static internal PropertyValue ToPropertyValue(TransformablePropertyMap instance)
175         {
176             return (instance != null && instance.IsValid()) ? new PropertyValue(instance.propertyMap) : new PropertyValue();
177         }
178     }
179 }
180
181