2 * Copyright(c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 using System.Runtime.InteropServices;
21 using Tizen.NUI.UIComponents;
22 using Tizen.NUI.BaseComponents;
24 // A spin control (for continously changing values when users can easily predict a set of values)
29 ///Spins the CustomView class.
31 /// <since_tizen> 3 </since_tizen>
32 public class Spin : CustomView
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;
48 // static constructor registers the control type (only runs once)
51 // ViewRegistry registers control type with DALi type registery
52 // also uses introspection to find any properties that need to be registered with type registry
53 CustomViewRegistry.Instance.Register(CreateInstance, typeof(Spin));
57 /// Creates an initialized spin.
59 /// <since_tizen> 3 </since_tizen>
60 public Spin() : base(typeof(Spin).FullName, CustomViewBehaviour.RequiresKeyboardNavigationSupport)
65 /// Value to be set in the spin.
67 /// <since_tizen> 3 </since_tizen>
68 [ScriptableProperty()]
69 // GetValue() is in BindableObject. It's different from this Value.
70 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1721: Property names should not match get methods")]
79 NUILog.Debug("Value set to " + value);
80 _currentValue = value;
82 // Make sure no invalid value is accepted
83 if (_currentValue < _minValue)
85 _currentValue = _minValue;
88 if (_currentValue > _maxValue)
90 _currentValue = _maxValue;
93 _textField.Text = _currentValue.ToString();
98 /// Minimum value of the spin value.
100 /// <since_tizen> 3 </since_tizen>
101 [ScriptableProperty()]
115 /// Maximum value of the spin value.
117 /// <since_tizen> 3 </since_tizen>
118 [ScriptableProperty()]
132 /// Increasing, decreasing step of the spin value when up or down keys are pressed.
134 /// <since_tizen> 3 </since_tizen>
135 [ScriptableProperty()]
149 /// Wrapping enabled status.
151 /// <since_tizen> 3 </since_tizen>
152 [ScriptableProperty()]
153 public bool WrappingEnabled
157 return _wrappingEnabled;
161 _wrappingEnabled = value;
166 /// Text point size of the spin value.
168 /// <since_tizen> 3 </since_tizen>
169 [ScriptableProperty()]
170 public int TextPointSize
179 _textField.PointSize = _pointSize;
184 /// The color of the spin value.
186 /// <since_tizen> 3 </since_tizen>
187 [ScriptableProperty()]
188 public Color TextColor
198 NUILog.Debug("TextColor set to " + value.R + "," + value.G + "," + value.B);
202 _textField.TextColor = _textColor;
207 /// Maximum text lengh of the spin value.
209 /// <since_tizen> 3 </since_tizen>
210 [ScriptableProperty()]
211 public int MaxTextLength
215 return _maxTextLength;
219 _maxTextLength = value;
220 _textField.MaxLength = _maxTextLength;
225 /// Reference of TextField of the spin.
227 /// <since_tizen> 3 </since_tizen>
228 public TextField SpinText
241 /// Show indicator image, for example, up or down arrow image.
243 /// <since_tizen> 3 </since_tizen>
244 public string IndicatorImage
253 var ptMap = new PropertyMap();
254 var temp = new PropertyValue((int)Visual.Type.Image);
255 ptMap.Add(Visual.Property.Type, temp);
258 temp = new PropertyValue(_arrowImage);
259 ptMap.Add(ImageVisualProperty.URL, temp);
262 temp = new PropertyValue(150);
263 ptMap.Add(ImageVisualProperty.DesiredHeight, temp);
266 temp = new PropertyValue(150);
267 ptMap.Add(ImageVisualProperty.DesiredWidth, temp);
270 _arrowVisual = VisualFactory.Instance.CreateVisual(ptMap);
273 RegisterVisual(_arrowVisualPropertyIndex, _arrowVisual);
277 // Called by DALi Builder if it finds a Spin control in a JSON file
278 static CustomView CreateInstance()
284 /// Overrides the method of OnInitialize() for the CustomView class.<br />
285 /// This method is called after the control has been initialized.<br />
286 /// Derived classes should do any second phase initialization by overriding this method.<br />
288 /// <since_tizen> 3 </since_tizen>
289 public override void OnInitialize()
291 // Initialize the propertiesControl
292 _arrowImage = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "picture.png";
293 _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
300 // Create image visual for the arrow keys
301 var temp = new PropertyValue(_arrowImage);
302 _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", temp, Tizen.NUI.PropertyAccessMode.ReadWrite);
305 var ptMap = new PropertyMap();
306 temp = new PropertyValue((int)Visual.Type.Image);
307 ptMap.Add(Visual.Property.Type, temp);
310 temp = new PropertyValue(_arrowImage);
311 ptMap.Add(ImageVisualProperty.URL, temp);
314 temp = new PropertyValue(150);
315 ptMap.Add(ImageVisualProperty.DesiredHeight, temp);
318 temp = new PropertyValue(150);
319 ptMap.Add(ImageVisualProperty.DesiredWidth, temp);
322 _arrowVisual = VisualFactory.Instance.CreateVisual(ptMap);
324 RegisterVisual(_arrowVisualPropertyIndex, _arrowVisual);
326 // Create a text field
327 _textField = new TextField();
328 _textField.PivotPoint = Tizen.NUI.PivotPoint.Center;
329 _textField.WidthResizePolicy = ResizePolicyType.SizeRelativeToParent;
330 _textField.HeightResizePolicy = ResizePolicyType.SizeRelativeToParent;
331 _textField.SizeModeFactor = new Vector3(1.0f, 0.45f, 1.0f);
332 _textField.PlaceholderText = "----";
333 _textField.BackgroundColor = _textBackgroundColor;
334 _textField.HorizontalAlignment = HorizontalAlignment.Center;
335 _textField.VerticalAlignment = VerticalAlignment.Center;
336 _textField.Focusable = (true);
337 _textField.Name = "_textField";
338 _textField.Position2D = new Position2D(0, 40);
340 this.Add(_textField);
342 _textField.FocusGained += TextFieldKeyInputFocusGained;
343 _textField.FocusLost += TextFieldKeyInputFocusLost;
347 /// Overrides the method of GetNaturalSize() for the CustomView class.<br />
348 /// Returns the natural size of the actor.<br />
350 /// <returns> Natural size of this spin itself.</returns>
351 /// <since_tizen> 3 </since_tizen>
352 public override Size2D GetNaturalSize()
354 return new Size2D(150, 150);
358 /// An event handler is used when the TextField in the spin gets the key focus.<br />
359 /// Make sure when the current spin that takes input focus, also takes the keyboard focus.<br />
360 /// For example, when you tap the spin directly.<br />
362 /// <param name="source">Sender of this event.</param>
363 /// <param name="e">Event arguments.</param>
364 /// <since_tizen> 3 </since_tizen>
365 public void TextFieldKeyInputFocusGained(object source, EventArgs e)
367 FocusManager.Instance.SetCurrentFocusView(_textField);
371 /// An event handler when the TextField in the spin looses it's key focus.
373 /// <param name="source"></param>
374 /// <param name="e"></param>
375 /// <since_tizen> 3 </since_tizen>
376 public void TextFieldKeyInputFocusLost(object source, EventArgs e)
378 int previousValue = _currentValue;
380 // If the input value is invalid, change it back to the previous valid value
381 if (int.TryParse(_textField.Text, out _currentValue))
383 if (_currentValue < _minValue || _currentValue > _maxValue)
385 _currentValue = previousValue;
390 _currentValue = previousValue;
393 // Otherwise take the new value
394 this.Value = _currentValue;
398 /// Overrides the method of GetNextKeyboardFocusableView() for the CustomView class.<br />
399 /// Gets the next key focusable view in this view towards the given direction.<br />
400 /// A view needs to override this function in order to support two-dimensional key navigation.<br />
402 /// <param name="currentFocusedView">The current focused view.</param>
403 /// <param name="direction">The direction to move the focus towards.</param>
404 /// <param name="loopEnabled">Whether the focus movement should be looped within the control.</param>
405 /// <returns>The next keyboard focusable view in this control or an empty handle if no view can be focused.</returns>
406 /// <since_tizen> 3 </since_tizen>
407 public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
409 // Respond to Up/Down keys to change the value while keeping the current spin focused
410 View nextFocusedView = currentFocusedView;
411 if (direction == View.FocusDirection.Up)
413 this.Value += this.Step;
414 nextFocusedView = _textField;
416 else if (direction == View.FocusDirection.Down)
418 this.Value -= this.Step;
419 nextFocusedView = _textField;
427 return nextFocusedView;