6d656910733562aed0995553ff3ed966a0bf2c72
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / CustomView / Spin.cs
1 /*
2  * Copyright(c) 2017 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;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI;
21 using Tizen.NUI.UIComponents;
22 using Tizen.NUI.BaseComponents;
23
24 // A spin control (for continously changing values when users can easily predict a set of values)
25
26 namespace Tizen.NUI
27 {
28     ///<summary>
29     ///Spins the CustomView class.
30     /// </summary>
31     /// <since_tizen> 3 </since_tizen>
32     public class Spin : CustomView
33     {
34         private VisualBase _arrowVisual;
35         private TextField _textField;
36         private int _arrowVisualPropertyIndex;
37         private string _arrowImage;
38         private int _currentValue;
39         private int _minValue;
40         private int _maxValue;
41         private int _singleStep;
42         private bool _wrappingEnabled;
43         private int _pointSize;
44         private Color _textColor;
45         private Color _textBackgroundColor;
46         private int _maxTextLength;
47
48         // Called by DALi Builder if it finds a Spin control in a JSON file
49         static CustomView CreateInstance()
50         {
51             return new Spin();
52         }
53
54         // static constructor registers the control type (only runs once)
55         static Spin()
56         {
57             // ViewRegistry registers control type with DALi type registery
58             // also uses introspection to find any properties that need to be registered with type registry
59             CustomViewRegistry.Instance.Register(CreateInstance, typeof(Spin));
60         }
61
62         /// <summary>
63         /// Creates an initialized spin.
64         /// </summary>
65         /// <since_tizen> 3 </since_tizen>
66         public Spin() : base(typeof(Spin).FullName, CustomViewBehaviour.RequiresKeyboardNavigationSupport)
67         {
68         }
69
70         /// <summary>
71         /// Overrides the method of OnInitialize() for the CustomView class.<br />
72         /// This method is called after the control has been initialized.<br />
73         /// Derived classes should do any second phase initialization by overriding this method.<br />
74         /// </summary>
75         /// <since_tizen> 3 </since_tizen>
76         public override void OnInitialize()
77         {
78             // Initialize the propertiesControl
79             //_arrowImage = "/home/tengxb/Workspace/nui-debug/examples/res/images/arrow.png";
80             _arrowImage = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "picture.png";
81             _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
82             _currentValue = 0;
83             _minValue = 0;
84             _maxValue = 0;
85             _singleStep = 1;
86             _maxTextLength = 0;
87
88             // Create image visual for the arrow keys
89             _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new PropertyValue(_arrowImage), Tizen.NUI.PropertyAccessMode.ReadWrite);
90             _arrowVisual = VisualFactory.Instance.CreateVisual(
91                 new PropertyMap().Add(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image))
92                                  .Add(ImageVisualProperty.URL, new PropertyValue(_arrowImage))
93                                  .Add(ImageVisualProperty.DesiredHeight, new PropertyValue(150))
94                                  .Add(ImageVisualProperty.DesiredWidth, new PropertyValue(150)));
95             RegisterVisual(_arrowVisualPropertyIndex, _arrowVisual);
96
97             // Create a text field
98             _textField = new TextField();
99             _textField.PivotPoint = Tizen.NUI.PivotPoint.Center;
100             _textField.WidthResizePolicy = ResizePolicyType.SizeRelativeToParent;
101             _textField.HeightResizePolicy = ResizePolicyType.SizeRelativeToParent;
102             _textField.SizeModeFactor = new Vector3(1.0f, 0.45f, 1.0f);
103             _textField.PlaceholderText = "----";
104             _textField.BackgroundColor = _textBackgroundColor;
105             _textField.HorizontalAlignment = HorizontalAlignment.Center;
106             _textField.VerticalAlignment = VerticalAlignment.Center;
107             _textField.Focusable = (true);
108             _textField.Name = "_textField";
109             _textField.Position2D = new Position2D(0, 40);
110
111             this.Add(_textField);
112
113             _textField.FocusGained += TextFieldKeyInputFocusGained;
114             _textField.FocusLost += TextFieldKeyInputFocusLost;
115         }
116
117         /// <summary>
118         /// Overrides the method of GetNaturalSize() for the CustomView class.<br />
119         /// Returns the natural size of the actor.<br />
120         /// </summary>
121         /// <returns> Natural size of this spin itself.</returns>
122         /// <since_tizen> 3 </since_tizen>
123         public override Size2D GetNaturalSize()
124         {
125             return new Size2D(150, 150);
126         }
127
128         /// <summary>
129         /// An event handler is used when the TextField in the spin gets the key focus.<br />
130         /// Make sure when the current spin that takes input focus, also takes the keyboard focus.<br />
131         /// For example, when you tap the spin directly.<br />
132         /// </summary>
133         /// <param name="source">Sender of this event.</param>
134         /// <param name="e">Event arguments.</param>
135         /// <since_tizen> 3 </since_tizen>
136         public void TextFieldKeyInputFocusGained(object source, EventArgs e)
137         {
138             FocusManager.Instance.SetCurrentFocusView(_textField);
139         }
140
141         /// <summary>
142         /// An event handler when the TextField in the spin looses it's key focus.
143         /// </summary>
144         /// <param name="source"></param>
145         /// <param name="e"></param>
146         /// <since_tizen> 3 </since_tizen>
147         public void TextFieldKeyInputFocusLost(object source, EventArgs e)
148         {
149             int previousValue = _currentValue;
150
151             // If the input value is invalid, change it back to the previous valid value
152             if (int.TryParse(_textField.Text, out _currentValue))
153             {
154                 if (_currentValue < _minValue || _currentValue > _maxValue)
155                 {
156                     _currentValue = previousValue;
157                 }
158             }
159             else
160             {
161                 _currentValue = previousValue;
162             }
163
164             // Otherwise take the new value
165             this.Value = _currentValue;
166         }
167
168         /// <summary>
169         /// Overrides the method of GetNextKeyboardFocusableView() for the CustomView class.<br />
170         /// Gets the next key focusable view in this view towards the given direction.<br />
171         /// A view needs to override this function in order to support two-dimensional key navigation.<br />
172         /// </summary>
173         /// <param name="currentFocusedView">The current focused view.</param>
174         /// <param name="direction">The direction to move the focus towards.</param>
175         /// <param name="loopEnabled">Whether the focus movement should be looped within the control.</param>
176         /// <returns>The next keyboard focusable view in this control or an empty handle if no view can be focused.</returns>
177         /// <since_tizen> 3 </since_tizen>
178         public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
179         {
180             // Respond to Up/Down keys to change the value while keeping the current spin focused
181             View nextFocusedView = currentFocusedView;
182             if (direction == View.FocusDirection.Up)
183             {
184                 this.Value += this.Step;
185                 nextFocusedView = _textField;
186             }
187             else if (direction == View.FocusDirection.Down)
188             {
189                 this.Value -= this.Step;
190                 nextFocusedView = _textField;
191             }
192             else
193             {
194                 // Return null
195                 return null;
196             }
197
198             return nextFocusedView;
199         }
200
201         /// <summary>
202         /// Value to be set in the spin.
203         /// </summary>
204         /// <since_tizen> 3 </since_tizen>
205         [ScriptableProperty()]
206         public int Value
207         {
208             get
209             {
210                 return _currentValue;
211             }
212             set
213             {
214
215                 Tizen.Log.Debug("NUI", "Value set to " + value);
216                 _currentValue = value;
217
218                 // Make sure no invalid value is accepted
219                 if (_currentValue < _minValue)
220                 {
221                     _currentValue = _minValue;
222                 }
223
224                 if (_currentValue > _maxValue)
225                 {
226                     _currentValue = _maxValue;
227                 }
228
229                 _textField.Text = _currentValue.ToString();
230             }
231         }
232
233         /// <summary>
234         /// Minimum value of the spin value.
235         /// </summary>
236         /// <since_tizen> 3 </since_tizen>
237         // MinValue property of type int:
238         /// <since_tizen> 3 </since_tizen>
239         [ScriptableProperty()]
240         public int MinValue
241         {
242             get
243             {
244                 return _minValue;
245             }
246             set
247             {
248                 _minValue = value;
249             }
250         }
251
252         /// <summary>
253         /// Maximum value of the spin value.
254         /// </summary>
255         /// <since_tizen> 3 </since_tizen>
256         // MaxValue property of type int:
257         /// <since_tizen> 3 </since_tizen>
258         [ScriptableProperty()]
259         public int MaxValue
260         {
261             get
262             {
263                 return _maxValue;
264             }
265             set
266             {
267                 _maxValue = value;
268             }
269         }
270
271         /// <summary>
272         /// Increasing, decreasing step of the spin value when up or down keys are pressed.
273         /// </summary>
274         /// <since_tizen> 3 </since_tizen>
275         // Step property of type int:
276         /// <since_tizen> 3 </since_tizen>
277         [ScriptableProperty()]
278         public int Step
279         {
280             get
281             {
282                 return _singleStep;
283             }
284             set
285             {
286                 _singleStep = value;
287             }
288         }
289
290         /// <summary>
291         /// Wrapping enabled status.
292         /// </summary>
293         /// <since_tizen> 3 </since_tizen>
294         // WrappingEnabled property of type bool:
295         /// <since_tizen> 3 </since_tizen>
296         [ScriptableProperty()]
297         public bool WrappingEnabled
298         {
299             get
300             {
301                 return _wrappingEnabled;
302             }
303             set
304             {
305                 _wrappingEnabled = value;
306             }
307         }
308
309         /// <summary>
310         /// Text point size of the spin value.
311         /// </summary>
312         /// <since_tizen> 3 </since_tizen>
313         // TextPointSize property of type int:
314         /// <since_tizen> 3 </since_tizen>
315         [ScriptableProperty()]
316         public int TextPointSize
317         {
318             get
319             {
320                 return _pointSize;
321             }
322             set
323             {
324                 _pointSize = value;
325                 _textField.PointSize = _pointSize;
326             }
327         }
328
329         /// <summary>
330         /// The color of the spin value.
331         /// </summary>
332         /// <since_tizen> 3 </since_tizen>
333         // TextColor property of type Color:
334         /// <since_tizen> 3 </since_tizen>
335         [ScriptableProperty()]
336         public Color TextColor
337         {
338             get
339             {
340                 return _textColor;
341             }
342             set
343             {
344                 Tizen.Log.Debug("NUI", "TextColor set to " + value.R + "," + value.G + "," + value.B);
345
346                 _textColor = value;
347                 _textField.TextColor = _textColor;
348             }
349         }
350
351         /// <summary>
352         /// Maximum text lengh of the spin value.
353         /// </summary>
354         /// <since_tizen> 3 </since_tizen>
355         // MaxTextLength property of type int:
356         /// <since_tizen> 3 </since_tizen>
357         [ScriptableProperty()]
358         public int MaxTextLength
359         {
360             get
361             {
362                 return _maxTextLength;
363             }
364             set
365             {
366                 _maxTextLength = value;
367                 _textField.MaxLength = _maxTextLength;
368             }
369         }
370
371         /// <summary>
372         /// Reference of TextField of the spin.
373         /// </summary>
374         /// <since_tizen> 3 </since_tizen>
375         public TextField SpinText
376         {
377             get
378             {
379                 return _textField;
380             }
381             set
382             {
383                 _textField = value;
384             }
385         }
386
387         /// <summary>
388         /// Show indicator image, for example, up or down arrow image.
389         /// </summary>
390         /// <since_tizen> 3 </since_tizen>
391         public string IndicatorImage
392         {
393             get
394             {
395                 return _arrowImage;
396             }
397             set
398             {
399                 _arrowImage = value;
400                 _arrowVisual = VisualFactory.Instance.CreateVisual(
401                     new PropertyMap().Add(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image))
402                                  .Add(ImageVisualProperty.URL, new PropertyValue(_arrowImage))
403                                  .Add(ImageVisualProperty.DesiredHeight, new PropertyValue(150))
404                                  .Add(ImageVisualProperty.DesiredWidth, new PropertyValue(150)));
405                 RegisterVisual(_arrowVisualPropertyIndex, _arrowVisual);
406             }
407         }
408     }
409 }