[NUI] Scrollbar inherits VisualView instead of Control (#1846)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / VisualView.cs
1 // Copyright (c) 2019 Samsung Electronics Co., Ltd.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15
16 using System;
17 using System.Text;
18 using System.Runtime.InteropServices;
19 using System.Collections.Generic;
20 using System.Linq;
21 using System.ComponentModel;
22
23 namespace Tizen.NUI.BaseComponents
24 {
25     /// <summary>
26     /// A visual view control if a user adds any visual to it.
27     /// </summary>
28     /// <example>
29     /// Example:
30     /// <code>
31     /// VisualView _visualView = new VisualView();
32     /// ImageVisualMap imageVisualMap1 = new ImageVisualMap();
33     /// imageVisualMap1.URL = "./NUISample/res/images/image-1.jpg";
34     /// imageVisualMap1.VisualSize = new Vector2( 300.0f, 300.0f );
35     /// imageVisualMap1.Offset = new Vector2( 50.0f, 50.0f );
36     /// imageVisualMap1.OffsetSizeMode = new Vector4( 1.0f, 1.0f, 1.0f, 1.0f );
37     /// imageVisualMap1.Origin = AlignType.TOP_BEGIN;
38     /// imageVisualMap1.AnchorPoint = AlignType.TOP_BEGIN;
39     /// _visualView.AddVisual("imageVisual1", imageVisualMap1);
40     /// </code>
41     /// </example>
42     /// <since_tizen> 3 </since_tizen>
43     public class VisualView : CustomView
44     {
45         //private LinkedList<VisualBase> _visualList = null;
46         private Dictionary<int, VisualBase> _visualDictionary = null;
47         private Dictionary<int, PropertyMap> _tranformDictionary = null;
48         private PropertyArray _animateArray = null;
49
50         /// <summary>
51         /// Constructor.
52         /// </summary>
53         /// <since_tizen> 3 </since_tizen>
54         public VisualView() : this(CustomViewBehaviour.ViewBehaviourDefault | CustomViewBehaviour.RequiresTouchEventsSupport)
55         {
56         }
57
58         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
59         [EditorBrowsable(EditorBrowsableState.Never)]
60         public VisualView(ViewStyle viewStyle) : this(CustomViewBehaviour.ViewBehaviourDefault | CustomViewBehaviour.RequiresTouchEventsSupport, viewStyle)
61         {
62
63         }
64
65         /// <summary>Create a VisualView with specified behaviour.</summary>
66         /// <param name="behaviour">CustomView behaviour</param>
67         [EditorBrowsable(EditorBrowsableState.Never)]
68         public VisualView(CustomViewBehaviour behaviour) : base(typeof(VisualView).FullName, behaviour)
69         {
70         }
71
72         /// <summary>Create a VisualView with specified behaviour and a style.</summary>
73         /// <param name="behaviour">CustomView behaviour</param>
74         /// <param name="viewStyle">The ViewStyle.</param>
75         [EditorBrowsable(EditorBrowsableState.Never)]
76         public VisualView(CustomViewBehaviour behaviour, ViewStyle viewStyle) : base(typeof(VisualView).FullName, behaviour, viewStyle)
77         {
78         }
79
80         // static constructor registers the control type (for user can add kinds of visuals to it)
81         static VisualView()
82         {
83             // ViewRegistry registers control type with DALi type registery
84             // also uses introspection to find any properties that need to be registered with type registry
85             CustomViewRegistry.Instance.Register(CreateInstance, typeof(VisualView));
86         }
87
88         /// <summary>
89         /// Gets the total number of visuals which are added by users.
90         /// </summary>
91         /// <since_tizen> 3 </since_tizen>
92         public int NumberOfVisuals
93         {
94             get
95             {
96                 return _visualDictionary.Count;
97             }
98         }
99
100         /// <summary>
101         /// Overrides the parent method.
102         /// </summary>
103         /// <since_tizen> 3 </since_tizen>
104         public override void OnInitialize()
105         {
106             //Initialize empty
107             _visualDictionary = new Dictionary<int, VisualBase>();
108             _tranformDictionary = new Dictionary<int, PropertyMap>();
109             _animateArray = new PropertyArray();
110         }
111
112         /// <summary>
113         /// Adds or updates a visual to visual view.
114         /// </summary>
115         /// <param name="visualName">The name of a visual to add. If a name is added to an existing visual name, the visual will be replaced.</param>
116         /// <param name="visualMap">The property map of a visual to create.</param>
117         /// <since_tizen> 3 </since_tizen>
118         public void AddVisual(string visualName, VisualMap visualMap)
119         {
120             VisualBase visual = null;
121             int visualIndex = -1;
122
123             /* If the visual had added, then replace it using RegisterVusal. */
124             //visual.Name = name;
125             foreach (var item in _visualDictionary)
126             {
127                 if (item.Value.Name == visualName)
128                 {
129                     /* Find a existed visual, its key also exited. */
130                     visualIndex = item.Key;
131                     UnregisterVisual(visualIndex);
132                     _visualDictionary.Remove(visualIndex);
133                     _tranformDictionary.Remove(visualIndex);
134                     break;
135                 }
136             }
137
138             if (visualIndex == -1) // The visual is a new one, create index for it. */
139             {
140                 visualIndex = RegisterProperty(visualName, new PropertyValue(visualName), PropertyAccessMode.ReadWrite);
141             }
142
143             if (visualIndex > 0)
144             {
145                 visual = VisualFactory.Instance.CreateVisual(visualMap.OutputVisualMap); // Create a visual for the new one.
146                 visual.Name = visualName;
147                 visual.DepthIndex = visualMap.DepthIndex;
148
149                 RegisterVisual(visualIndex, visual);
150
151                 _visualDictionary.Add(visualIndex, visual);
152                 _tranformDictionary.Add(visualIndex, visualMap.OutputTransformMap);
153
154                 visualMap.VisualIndex = visualIndex;
155                 visualMap.Name = visualName;
156                 visualMap.Parent = this;
157
158                 RelayoutRequest();
159             }
160         }
161
162         /// <summary>
163         /// Removes a visual by name.
164         /// </summary>
165         /// <param name="visualName">The name of a visual to remove.</param>
166         /// <since_tizen> 3 </since_tizen>
167         public void RemoveVisual(string visualName)
168         {
169             foreach (var item in _visualDictionary)
170             {
171                 if (item.Value.Name == visualName)
172                 {
173                     EnableVisual(item.Key, false);
174                     UnregisterVisual(item.Key);
175                     _tranformDictionary.Remove(item.Key);
176                     _visualDictionary.Remove(item.Key);
177
178                     RelayoutRequest();
179                     break;
180                 }
181             }
182         }
183
184         /// <summary>
185         /// Removes all visuals of the visual view.
186         /// </summary>
187         /// <since_tizen> 3 </since_tizen>
188         public void RemoveAll()
189         {
190             foreach (var item in _visualDictionary)
191             {
192                 EnableVisual(item.Key, false);
193                 UnregisterVisual(item.Key);
194             }
195             _visualDictionary.Clear();
196             _tranformDictionary.Clear();
197             RelayoutRequest();
198         }
199
200         /// <summary>
201         /// Overrides the method of OnRelayout() for CustomView class.<br />
202         /// Called after the size negotiation has been finished for this control.<br />
203         /// The control is expected to assign this given size to itself or its children.<br />
204         /// Should be overridden by derived classes if they need to layout actors differently after certain operations like add or remove actors, resize, or after changing specific properties.<br />
205         /// </summary>
206         /// <remarks>As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).</remarks>
207         /// <param name="size">The allocated size.</param>
208         /// <param name="container">The control should add actors to this container that it is not able to allocate a size for.</param>
209         /// <since_tizen> 3 </since_tizen>
210         public override void OnRelayout(Vector2 size, RelayoutContainer container)
211         {
212             foreach (var item in _visualDictionary)
213             {
214                 item.Value.SetTransformAndSize(_tranformDictionary[item.Key], size);
215                 EnableVisual(item.Key, true);
216             }
217         }
218
219         /// <summary>
220         /// Creates a visual animation (transition) with the input parameters.
221         /// </summary>
222         /// <param name="target">The visual map to animation.</param>
223         /// <param name="property">The property of visual to animation.</param>
224         /// <param name="destinationValue">The destination value of property after animation.</param>
225         /// <param name="startTime">The start time of visual animation.</param>
226         /// <param name="endTime">The end time of visual animation.</param>
227         /// <param name="alphaFunction">The alpha function of visual animation.</param>
228         /// <param name="initialValue">The initial property value of visual animation.</param>
229         /// <returns>Animation instance</returns>
230         /// <since_tizen> 3 </since_tizen>
231         public Animation AnimateVisual(VisualMap target, string property, object destinationValue, int startTime, int endTime, AlphaFunction.BuiltinFunctions? alphaFunction = null, object initialValue = null)
232         {
233             string _alphaFunction = alphaFunction?.GetDescription();
234
235             foreach (var item in _visualDictionary.ToList())
236             {
237                 if (item.Value.Name == target.Name)
238                 {
239                     PropertyMap _animator = new PropertyMap();
240                     if (_alphaFunction != null) { _animator.Add("alphaFunction", new PropertyValue(_alphaFunction)); }
241
242                     PropertyMap _timePeriod = new PropertyMap();
243                     _timePeriod.Add("duration", new PropertyValue((endTime - startTime) / 1000.0f));
244                     _timePeriod.Add("delay", new PropertyValue(startTime / 1000.0f));
245                     _animator.Add("timePeriod", new PropertyValue(_timePeriod));
246
247                     StringBuilder sb = new StringBuilder(property);
248                     sb[0] = (char)(sb[0] | 0x20);
249                     string _str = sb.ToString();
250                     if (_str == "position") { _str = "offset"; }
251
252                     PropertyValue destVal = PropertyValue.CreateFromObject(destinationValue);
253
254                     PropertyMap _transition = new PropertyMap();
255                     _transition.Add("target", new PropertyValue(target.Name));
256                     _transition.Add("property", new PropertyValue(_str));
257                     if (initialValue != null)
258                     {
259                         PropertyValue initVal = PropertyValue.CreateFromObject(initialValue);
260                         _transition.Add("initialValue", new PropertyValue(initVal));
261                     }
262                     _transition.Add("targetValue", destVal);
263                     _transition.Add("animator", new PropertyValue(_animator));
264
265                     TransitionData _transitionData = new TransitionData(_transition);
266                     return this.CreateTransition(_transitionData);
267                 }
268             }
269             return null;
270         }
271
272         /// <summary>
273         /// Adds a group visual animation (transition) map with the input parameters.
274         /// </summary>
275         /// <param name="target">The visual map to animation.</param>
276         /// <param name="property">The property of visual to animation.</param>
277         /// <param name="destinationValue">The destination value of property after animation.</param>
278         /// <param name="startTime">The start time of visual animation.</param>
279         /// <param name="endTime">The end time of visual animation.</param>
280         /// <param name="alphaFunction">The alpha function of visual animation.</param>
281         /// <param name="initialValue">The initial property value of visual animation.</param>
282         /// <since_tizen> 3 </since_tizen>
283         public void AnimateVisualAdd(VisualMap target, string property, object destinationValue, int startTime, int endTime, AlphaFunction.BuiltinFunctions? alphaFunction = null, object initialValue = null)
284         {
285             string _alphaFunction = alphaFunction?.GetDescription();
286
287             foreach (var item in _visualDictionary.ToList())
288             {
289                 if (item.Value.Name == target.Name)
290                 {
291                     PropertyMap _animator = new PropertyMap();
292                     if (_alphaFunction != null) { _animator.Add("alphaFunction", new PropertyValue(_alphaFunction)); }
293
294                     PropertyMap _timePeriod = new PropertyMap();
295                     _timePeriod.Add("duration", new PropertyValue((endTime - startTime) / 1000.0f));
296                     _timePeriod.Add("delay", new PropertyValue(startTime / 1000.0f));
297                     _animator.Add("timePeriod", new PropertyValue(_timePeriod));
298
299                     StringBuilder sb = new StringBuilder(property);
300                     sb[0] = (char)(sb[0] | 0x20);
301                     string _str = sb.ToString();
302                     if (_str == "position") { _str = "offset"; }
303
304                     PropertyValue destVal = PropertyValue.CreateFromObject(destinationValue);
305
306                     PropertyMap _transition = new PropertyMap();
307                     _transition.Add("target", new PropertyValue(target.Name));
308                     _transition.Add("property", new PropertyValue(_str));
309                     if (initialValue != null)
310                     {
311                         PropertyValue initVal = PropertyValue.CreateFromObject(initialValue);
312                         _transition.Add("initialValue", new PropertyValue(initVal));
313                     }
314                     _transition.Add("targetValue", destVal);
315                     _transition.Add("animator", new PropertyValue(_animator));
316
317                     _animateArray.Add(new PropertyValue(_transition));
318                 }
319             }
320         }
321
322         /// <summary>
323         /// Finishes to add a visual animation (transition) map and creates a transition animation.
324         /// </summary>
325         /// <returns>Animation instance.</returns>
326         /// <since_tizen> 3 </since_tizen>
327         public Animation AnimateVisualAddFinish()
328         {
329             if (_animateArray == null || _animateArray.Empty())
330             {
331                 Tizen.Log.Fatal("NUI", "animate visual property array is empty!");
332                 return null;
333             }
334             TransitionData _transitionData = new TransitionData(_animateArray);
335
336             return this.CreateTransition(_transitionData);
337         }
338
339         /// <summary>
340         /// temporary fix to pass TCT.
341         /// </summary>
342         /// <since_tizen> 3 </since_tizen>
343         public Animation VisualAnimate(Tizen.NUI.VisualAnimator visualMap)
344         {
345             foreach (var item in _visualDictionary.ToList())
346             {
347                 if (item.Value.Name == visualMap.Target)
348                 {
349                     TransitionData _transitionData = new TransitionData(visualMap.OutputVisualMap);
350                     return this.CreateTransition(_transitionData);
351                 }
352             }
353             return null;
354         }
355         //temporary fix to pass TCT
356
357         internal void UpdateVisual(int visualIndex, string visualName, VisualMap visualMap)
358         {
359             VisualBase visual = null;
360
361             visual = VisualFactory.Instance.CreateVisual(visualMap.OutputVisualMap);
362             visual.Name = visualName;
363             visual.DepthIndex = visualMap.DepthIndex;
364
365             RegisterVisual(visualIndex, visual);
366
367             _visualDictionary[visualIndex] = visual;
368             _tranformDictionary[visualIndex] = visualMap.OutputTransformMap;
369
370             RelayoutRequest();
371             NUILog.Debug("UpdateVisual() name=" + visualName);
372         }
373
374         static CustomView CreateInstance()
375         {
376             return new VisualView();
377         }
378
379     }
380 }