2 * Copyright (c) 2016 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;
22 namespace MyCSharpExample
24 // A spin control (for continously changing values when users can easily predict a set of values)
25 class Spin : CustomView
27 private VisualBase _arrowVisual;
28 private TextField _textField;
29 private int _arrowVisualPropertyIndex;
30 private string _arrowImage;
31 private int _currentValue;
32 private int _minValue;
33 private int _maxValue;
34 private int _singleStep;
35 private bool _wrappingEnabled;
36 private string _fontFamily;
37 private string _fontStyle;
38 private int _pointSize;
39 private Color _textColor;
40 private Color _textBackgroundColor;
41 private int _maxTextLength;
43 public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS)
47 public override void OnInitialize()
49 // Initialize the properties
50 _arrowImage = "./images/arrow.png";
51 _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
58 // Create image visual for the arrow keys
59 _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new Dali.Property.Value(_arrowImage), Dali.Property.AccessMode.READ_WRITE);
60 _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
61 RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
63 // Create a text field
64 _textField = new TextField();
65 _textField.ParentOrigin = NDalic.ParentOriginCenter;
66 _textField.AnchorPoint = NDalic.AnchorPointCenter;
67 _textField.WidthResizePolicy = "SIZE_RELATIVE_TO_PARENT";
68 _textField.HeightResizePolicy = "SIZE_RELATIVE_TO_PARENT";
69 _textField.SizeModeFactor = new Vector3( 1.0f, 0.45f, 1.0f );
70 _textField.PlaceholderText = "----";
71 _textField.BackgroundColor = _textBackgroundColor;
72 _textField.HorizontalAlignment = "Center";
73 _textField.VerticalAlignment = "Center";
74 _textField.SetKeyboardFocusable(true);
75 _textField.Name = "_textField";
79 _textField.KeyInputFocusGained += TextFieldKeyInputFocusGained;
80 _textField.KeyInputFocusLost += TextFieldKeyInputFocusLost;
83 public override Vector3 GetNaturalSize()
85 return new Vector3(150.0f, 150.0f, 0.0f);
88 public void TextFieldKeyInputFocusGained(object source, KeyInputFocusGainedEventArgs e)
90 // Make sure when the current spin that takes input focus also takes the keyboard focus
91 // For example, when you tap the spin directly
92 KeyboardFocusManager.Get().SetCurrentFocusActor(_textField);
95 public void TextFieldKeyInputFocusLost(object source, KeyInputFocusLostEventArgs e)
97 int previousValue = _currentValue;
99 // If the input value is invalid, change it back to the previous valid value
100 if(int.TryParse(_textField.Text, out _currentValue))
102 if (_currentValue < _minValue || _currentValue > _maxValue)
104 _currentValue = previousValue;
109 _currentValue = previousValue;
112 // Otherwise take the new value
113 this.Value = _currentValue;
116 public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled)
118 // Respond to Up/Down keys to change the value while keeping the current spin focused
119 Actor nextFocusedActor = currentFocusedActor;
120 if (direction == View.KeyboardFocus.Direction.UP)
122 this.Value += this.Step;
123 nextFocusedActor = _textField;
125 else if (direction == View.KeyboardFocus.Direction.DOWN)
127 this.Value -= this.Step;
128 nextFocusedActor = _textField;
132 // Return a native empty handle as nothing can be focused in the left or right
133 nextFocusedActor = new Actor();
134 nextFocusedActor.Reset();
137 return nextFocusedActor;
140 // Value property of type int:
145 return _currentValue;
149 _currentValue = value;
151 // Make sure no invalid value is accepted
152 if (_currentValue < _minValue)
154 _currentValue = _minValue;
157 if (_currentValue > _maxValue)
159 _currentValue = _maxValue;
162 _textField.Text = _currentValue.ToString();
166 // MinValue property of type int:
179 // MaxValue property of type int:
192 // Step property of type int:
205 // WrappingEnabled property of type bool:
206 public bool WrappingEnabled
210 return _wrappingEnabled;
214 _wrappingEnabled = value;
218 // TextPointSize property of type int:
219 public int TextPointSize
228 _textField.PointSize = _pointSize;
232 // TextColor property of type Color:
233 public Color TextColor
242 _textField.TextColor = _textColor;
246 // MaxTextLength property of type int:
247 public int MaxTextLength
251 return _maxTextLength;
255 _maxTextLength = value;
256 _textField.MaxLength = _maxTextLength;
260 public TextField SpinText
272 // Indicator property of type string:
273 public string IndicatorImage
282 _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
283 RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
290 private Dali.Application _application;
291 private FlexContainer _container;
292 private Spin _spinYear;
293 private Spin _spinMonth;
294 private Spin _spinDay;
296 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
297 delegate void CallbackDelegate();
299 public Example(Dali.Application application)
301 _application = application;
302 _application.Initialized += Initialize;
305 public void Initialize(object source, AUIApplicationInitEventArgs e)
307 Stage stage = Stage.GetCurrent();
308 stage.BackgroundColor = Color.White;
310 // Create a container for the spins
311 _container = new FlexContainer();
313 _container.ParentOrigin = NDalic.ParentOriginCenter;
314 _container.AnchorPoint = NDalic.AnchorPointCenter;
315 _container.FlexDirection = (int)FlexContainer.FlexDirectionType.ROW;
316 _container.Size = new Vector3(480.0f, 150.0f, 0.0f);
318 stage.Add(_container);
320 // Create a Spin control for year
321 _spinYear = new Spin();
322 _spinYear.ParentOrigin = NDalic.ParentOriginCenter;
323 _spinYear.AnchorPoint = NDalic.AnchorPointCenter;
324 _spinYear.Flex = 0.3f;
325 _spinYear.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
326 _container.Add(_spinYear);
328 _spinYear.MinValue = 1900;
329 _spinYear.MaxValue = 2100;
330 _spinYear.Value = 2016;
332 _spinYear.MaxTextLength = 4;
333 _spinYear.TextPointSize = 26;
334 _spinYear.TextColor = Color.White;
335 _spinYear.SetKeyboardFocusable(true);
336 _spinYear.Name = "_spinYear";
338 // Create a Spin control for month
339 _spinMonth = new Spin();
340 _spinMonth.ParentOrigin = NDalic.ParentOriginCenter;
341 _spinMonth.AnchorPoint = NDalic.AnchorPointCenter;
342 _spinMonth.Flex = 0.3f;
343 _spinMonth.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
344 _container.Add(_spinMonth);
346 _spinMonth.MinValue = 1;
347 _spinMonth.MaxValue = 12;
348 _spinMonth.Value = 10;
350 _spinMonth.MaxTextLength = 2;
351 _spinMonth.TextPointSize = 26;
352 _spinMonth.TextColor = Color.White;
353 _spinMonth.SetKeyboardFocusable(true);
354 _spinMonth.Name = "_spinMonth";
356 // Create a Spin control for day
357 _spinDay = new Spin();
358 _spinDay.ParentOrigin = NDalic.ParentOriginCenter;
359 _spinDay.AnchorPoint = NDalic.AnchorPointCenter;
360 _spinDay.Flex = 0.3f;
361 _spinDay.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
362 _container.Add(_spinDay);
364 _spinDay.MinValue = 1;
365 _spinDay.MaxValue = 31;
368 _spinDay.MaxTextLength = 2;
369 _spinDay.TextPointSize = 26;
370 _spinDay.TextColor = Color.White;
371 _spinDay.SetKeyboardFocusable(true);
372 _spinDay.Name = "_spinDay";
374 KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.Get();
375 keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange;
376 keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed;
380 private Actor OnKeyboardPreFocusChange(object source, KeyboardFocusManager.PreFocusChangeEventArgs e)
382 Actor nextFocusActor = e.Proposed;
384 // When nothing has been focused initially, focus the text field in the first spin
385 if (!e.Current && !e.Proposed)
387 nextFocusActor = _spinYear.SpinText;
389 else if(e.Direction == View.KeyboardFocus.Direction.LEFT)
391 // Move the focus to the spin in the left of the current focused spin
392 if(e.Current == _spinMonth.SpinText)
394 nextFocusActor = _spinYear.SpinText;
396 else if(e.Current == _spinDay.SpinText)
398 nextFocusActor = _spinMonth.SpinText;
401 else if(e.Direction == View.KeyboardFocus.Direction.RIGHT)
403 // Move the focus to the spin in the right of the current focused spin
404 if(e.Current == _spinYear.SpinText)
406 nextFocusActor = _spinMonth.SpinText;
408 else if(e.Current == _spinMonth.SpinText)
410 nextFocusActor = _spinDay.SpinText;
414 return nextFocusActor;
417 private void OnFocusedActorEnterKeyPressed(object source, KeyboardFocusManager.FocusedActorEnterKeyEventArgs e)
419 // Make the text field in the current focused spin to take the key input
420 KeyInputFocusManager manager = KeyInputFocusManager.Get();
422 if (e.Actor == _spinYear.SpinText)
424 if (manager.GetCurrentFocusControl() != _spinYear.SpinText)
426 manager.SetFocus(_spinYear.SpinText);
429 else if (e.Actor == _spinMonth.SpinText)
431 if (manager.GetCurrentFocusControl() != _spinMonth.SpinText)
433 manager.SetFocus(_spinMonth.SpinText);
436 else if (e.Actor == _spinDay.SpinText)
438 if (manager.GetCurrentFocusControl() != _spinDay.SpinText)
440 manager.SetFocus(_spinDay.SpinText);
445 public void MainLoop()
447 _application.MainLoop ();
451 /// The main entry point for the application.
454 static void Main(string[] args)
456 Example example = new Example(Application.NewApplication());