1 /* Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using Tizen.NUI.BaseComponents;
19 using System.Collections.Generic;
20 using System.Collections.ObjectModel;
21 using System.ComponentModel;
22 using System.Diagnostics.CodeAnalysis;
23 using System.Globalization;
25 namespace Tizen.NUI.Components
28 /// TimeChangedEventArgs is a class to notify changed TimePicker value argument which will sent to user.
30 [EditorBrowsable(EditorBrowsableState.Never)]
31 public class TimeChangedEventArgs : EventArgs
34 /// TimeChangedEventArgs default constructor.
35 /// <param name="hour">hour value of TimePicker.</param>
36 /// <param name="minute">minute value of TimePicker.</param>
38 [EditorBrowsable(EditorBrowsableState.Never)]
39 public TimeChangedEventArgs(int hour, int minute)
46 /// TimeChangedEventArgs default constructor.
47 /// <returns>The current hour value of TimePicker.</returns>
49 [EditorBrowsable(EditorBrowsableState.Never)]
50 public int Hour { get; }
53 /// TimeChangedEventArgs default constructor.
54 /// <returns>The current minute value of TimePicker.</returns>
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public int Minute { get; }
61 /// TimePicker is a class which provides a function that allows the user to select
62 /// a time through a scrolling motion by expressing the specified value as a list.
63 /// TimePicker expresses the current time using the locale information of the system.
65 [EditorBrowsable(EditorBrowsableState.Never)]
66 public class TimePicker : Control
69 private bool is24HourView;
72 private String[] ampmText;
73 private Picker hourPicker;
74 private Picker minutePicker;
75 private Picker ampmPicker;
76 private TimePickerStyle timePickerStyle => ViewStyle as TimePickerStyle;
79 /// Creates a new instance of TimePicker.
81 [EditorBrowsable(EditorBrowsableState.Never)]
88 /// Creates a new instance of TimePicker.
90 /// <param name="style">Creates TimePicker by special style defined in UX.</param>
91 [EditorBrowsable(EditorBrowsableState.Never)]
92 public TimePicker(string style) : base(style)
98 /// Creates a new instance of TimePicker.
100 /// <param name="timePickerStyle">Creates TimePicker by style customized by user.</param>
101 [EditorBrowsable(EditorBrowsableState.Never)]
102 public TimePicker(TimePickerStyle timePickerStyle) : base(timePickerStyle)
108 /// Dispose TimePicker and all children on it.
110 /// <param name="type">Dispose type.</param>
111 [EditorBrowsable(EditorBrowsableState.Never)]
112 protected override void Dispose(DisposeTypes type)
119 if (type == DisposeTypes.Explicit)
122 Utility.Dispose(hourPicker);
124 Remove(minutePicker);
125 Utility.Dispose(minutePicker);
128 Utility.Dispose(ampmPicker);
136 /// An event emitted when TimePicker value changed, user can subscribe or unsubscribe to this event handler.
138 [EditorBrowsable(EditorBrowsableState.Never)]
139 public event EventHandler<TimeChangedEventArgs> TimeChanged;
142 /// The hour value of TimePicker.
144 [EditorBrowsable(EditorBrowsableState.Never)]
153 if (value < 1 || value > 24 || value == hour) return;
158 if (hour >= 12 && hour <= 23)
161 if (hour == 12) hourPicker.CurrentValue = hour;
162 else hourPicker.CurrentValue = hour -= 12;
163 ampmPicker.CurrentValue = 2;
168 hourPicker.CurrentValue = hour;
169 ampmPicker.CurrentValue = 1;
172 else hourPicker.CurrentValue = hour;
177 /// The Minute value of TimePicker.
179 [EditorBrowsable(EditorBrowsableState.Never)]
188 if (value < 1 || value > 60 || value == minute) return;
191 minutePicker.CurrentValue = minute;
196 /// The is24hourview value of TimePicker.
198 [EditorBrowsable(EditorBrowsableState.Never)]
199 public bool Is24HourView
207 if (is24HourView == value) return;
209 is24HourView = value;
213 hourPicker.MaxValue = 24;
217 hourPicker.MaxValue = 12;
218 PickersOrderSet(true);
225 /// Initialize TimePicker object.
227 [EditorBrowsable(EditorBrowsableState.Never)]
228 public override void OnInitialize()
232 hourPicker = new Picker()
237 hourPicker.ValueChanged += OnHourValueChanged;
239 minutePicker = new Picker()
244 minutePicker.ValueChanged += OnMinuteValueChanged;
246 ampmPicker = new Picker()
251 ampmPicker.ValueChanged += OnAmpmValueChanged;
255 /// Applies style to TimePicker.
257 /// <param name="viewStyle">The style to apply.</param>
258 [EditorBrowsable(EditorBrowsableState.Never)]
259 public override void ApplyStyle(ViewStyle viewStyle)
261 base.ApplyStyle(viewStyle);
264 if (timePickerStyle?.CellPadding != null && Layout != null)
265 ((LinearLayout)Layout).CellPadding = new Size2D(timePickerStyle.CellPadding.Width, timePickerStyle.CellPadding.Height);
267 //Apply Internal Pickers style.
268 if (timePickerStyle?.Pickers != null && hourPicker != null && minutePicker != null && ampmPicker != null)
270 hourPicker.ApplyStyle(timePickerStyle.Pickers);
271 minutePicker.ApplyStyle(timePickerStyle.Pickers);
272 ampmPicker.ApplyStyle(timePickerStyle.Pickers);
276 [SuppressMessage("Microsoft.Reliability",
277 "CA2000:DisposeObjectsBeforeLosingScope",
278 Justification = "The CellPadding will be dispose when the time picker disposed")]
279 private void Initialize()
281 HeightSpecification = LayoutParamPolicies.MatchParent;
283 Layout = new LinearLayout() {
284 LinearOrientation = LinearLayout.Orientation.Horizontal,
285 CellPadding = new Size(timePickerStyle.CellPadding.Width, timePickerStyle.CellPadding.Height),
290 PickersOrderSet(false);
295 hourPicker.MaxValue = 12;
299 private void OnHourValueChanged(object sender, ValueChangedEventArgs e)
301 if (hour == e.Value) return;
307 if (e.Value == 12) hour = 24;
312 if (e.Value == 12) hour = 12;
313 else hour = e.Value + 12;
322 private void OnMinuteValueChanged(object sender, ValueChangedEventArgs e)
324 if (minute == e.Value) return;
331 private void OnAmpmValueChanged(object sender, ValueChangedEventArgs e)
333 if ((isAm && e.Value == 1) || (!isAm && e.Value == 2)) return;
337 if (hour >= 12 || hour < 24)
339 if (hour == 12) hour += 12;
346 if (hour == 24 || hour < 12)
348 if (hour == 24) hour -= 12;
357 private void OnTimeChanged()
359 TimeChangedEventArgs eventArgs = new TimeChangedEventArgs(hour, minute);
360 TimeChanged?.Invoke(this, eventArgs);
363 private void PickersOrderSet(bool ampmForceSet)
365 //FIXME: Check the pickers located in already proper position or not.
367 Remove(minutePicker);
370 //Get current system locale's time pattern
371 String locale = Environment.GetEnvironmentVariable("LC_TIME");
372 DateTimeFormatInfo timeFormatInfo = new CultureInfo(locale, false ).DateTimeFormat;
373 String timePattern = timeFormatInfo.ShortTimePattern;
374 String[] timePatternArray = timePattern.Split(' ', ':');
376 foreach (String format in timePatternArray) {
377 if (format.IndexOf("H") != -1|| format.IndexOf("h") != -1) Add(hourPicker);
378 else if (format.IndexOf("M") != -1 || format.IndexOf("m") != -1) Add(minutePicker);
379 else if (format.IndexOf("t") != -1)
381 is24HourView = false;
382 ampmForceSet = false;
387 if (ampmForceSet) Add(ampmPicker);
390 private void SetAmpmText()
392 //FIXME: There is no localeChanged Event for Component now
393 // AMPM text has to update when system locale changed.
394 String locale = Environment.GetEnvironmentVariable("LC_TIME");
395 CultureInfo info = new CultureInfo(locale);
396 ampmText = new string[] {info.DateTimeFormat.AMDesignator, info.DateTimeFormat.PMDesignator};
397 ampmPicker.DisplayedValues = new ReadOnlyCollection<string>(ampmText);