2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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.
18 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
25 /// Enumeration for event periodicity, used to define if a mark should be repeated beyond event's day. It's set when a mark is added.
27 public enum CalendarMarkRepeatType
30 /// Default value. Marks will be displayed only on event day.
35 /// Marks will be displayed every day after event day.
40 /// Marks will be displayed every week after event day.
45 /// Marks will be displayed every month day that coincides to event day.
50 /// Marks will be displayed every year that coincides to event day.
55 /// Marks will be displayed every last day of month after event day.
61 /// Enumeration for the mode, which determine how user could select a day.
63 public enum CalendarSelectMode
66 /// Default value. a day is always selected.
71 /// A day is always selected.
76 /// None of the days can be selected.
81 /// User may have selected a day or not.
87 public enum CalendarSelectable
96 /// The CalendarMark is a Item for marking a Calendar's type,date and repeat type.
98 public class CalendarMark
100 internal IntPtr Handle;
103 /// A string used to define the type of mark.
108 /// A time struct to represent the date of inclusion of the mark.
110 public DateTime Date;
113 /// Repeat the event following this periodicity.
115 public CalendarMarkRepeatType Repeat;
118 /// Creates and initializes a new instance of the CalendarMark class.
120 /// <param name="type">Type of mark</param>
121 /// <param name="date">Date of inclusion of the mark</param>
122 /// <param name="repeat">Repeat type</param>
123 public CalendarMark(string type, DateTime date, CalendarMarkRepeatType repeat)
125 Handle = IntPtr.Zero;
133 /// The Calendar is a widget that helps applications to flexibly display a calender with day of the week, date, year and month.
135 public class Calendar : Layout
138 DateTime _cacheSelectedDate;
139 SmartEvent _displayedMonthChanged;
140 int _cacheDisplayedMonth;
142 Interop.Elementary.Elm_Calendar_Format_Cb _calendarFormat;
143 DateFormatDelegate _dateFormatDelegate = null;
146 /// Creates and initializes a new instance of the Calendar class.
148 /// <param name="parent">
149 /// The EvasObject to which the new Calendar will be attached as a child.
151 public Calendar(EvasObject parent) : base(parent)
153 _changed = new SmartEvent(this, this.RealHandle, "changed");
154 _changed.On += (sender, e) =>
156 DateTime selectedDate = SelectedDate;
157 DateChanged?.Invoke(this, new DateChangedEventArgs(_cacheSelectedDate, selectedDate));
158 _cacheSelectedDate = selectedDate;
161 _displayedMonthChanged = new SmartEvent(this, this.RealHandle, "display,changed");
162 _displayedMonthChanged.On += (sender, e) =>
164 int currentDisplayedMonth = DisplayedTime.Month;
165 DisplayedMonthChanged?.Invoke(this, new DisplayedMonthChangedEventArgs(_cacheDisplayedMonth, currentDisplayedMonth));
166 _cacheDisplayedMonth = currentDisplayedMonth;
169 _calendarFormat = (t) => { return _dateFormatDelegate(t); };
173 /// DateChanged will be triggered when the date in the calendar is changed.
175 public event EventHandler<DateChangedEventArgs> DateChanged;
178 /// DisplayedMonthChanged will be triggered when the current month displayed in the calendar is changed.
180 public event EventHandler<DisplayedMonthChangedEventArgs> DisplayedMonthChanged;
183 /// This delegate type is used to format the string that will be used to display month and year.
185 /// <param name="time">DateTime</param>
186 /// <returns></returns>
187 public delegate string DateFormatDelegate(DateTime time);
190 /// Sets or gets the minimum for year.
192 public int MinimumYear
198 Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out minimumYear, out unused);
205 Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out unused, out maximumYear);
206 if (maximumYear < 1902)
208 maximumYear = DateTime.MaxValue.Year;
210 Interop.Elementary.elm_calendar_min_max_year_set(RealHandle, value, maximumYear);
215 /// Sets or gets the maximum for the year.
217 public int MaximumYear
223 Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out unused, out maximumYear);
230 Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out minimumYear, out unused);
231 Interop.Elementary.elm_calendar_min_max_year_set(RealHandle, minimumYear, value);
236 /// Sets or gets the first day of week, who are used on Calendar.
238 public DateTime DisplayedTime
242 var tm = new Interop.Libc.SystemTime();
243 Interop.Elementary.elm_calendar_displayed_time_get(RealHandle, out tm);
245 ///If the defect is fixed, it will be removed.
246 var daysInMonth = DateTime.DaysInMonth(tm.tm_year + 1900, tm.tm_mon + 1);
247 var day = tm.tm_mday;
249 if (day > daysInMonth)
254 DateTime date = new DateTime(tm.tm_year + 1900, tm.tm_mon + 1, day, tm.tm_hour, tm.tm_min, tm.tm_sec);
261 /// Sets or gets the first day of week, who are used on Calendar.
263 public DayOfWeek FirstDayOfWeek
267 return (DayOfWeek)Interop.Elementary.elm_calendar_first_day_of_week_get(RealHandle);
271 Interop.Elementary.elm_calendar_first_day_of_week_set(RealHandle, (int)value);
276 /// Sets or gets the weekdays names to be displayed by the Calendar.
279 /// The usage should be like this;
280 /// List<string> weekDayNames = new List<string>() { "S", "M", "T", "W", "T", "F", "S" };
281 /// Calendar.WeekDayNames = weekDayNames;
283 public IReadOnlyList<string> WeekDayNames
287 IntPtr stringArrayPtr = Interop.Elementary.elm_calendar_weekdays_names_get(RealHandle);
288 string[] stringArray;
289 IntPtrToStringArray(stringArrayPtr, 7, out stringArray);
294 if (value != null && value.Count == 7)
296 Interop.Elementary.elm_calendar_weekdays_names_set(RealHandle, value.ToArray());
302 /// Sets or gets the selected date.
305 /// Selected date changes when the user goes to next/previous month or select a day pressing over it on calendar.
307 public DateTime SelectedDate
311 var tm = new Interop.Libc.SystemTime();
312 Interop.Elementary.elm_calendar_selected_time_get(RealHandle, ref tm);
313 if (tm.tm_year == 0 && tm.tm_mon == 0 && tm.tm_mday == 0)
321 Interop.Libc.SystemTime tm = value;
322 Interop.Elementary.elm_calendar_selected_time_set(RealHandle, ref tm);
323 _cacheSelectedDate = value;
328 /// Sets or gets the interval on time updates for an user mouse button
329 /// hold on calendar widgets' month/year selection.
331 public double Interval
335 return Interop.Elementary.elm_calendar_interval_get(RealHandle);
339 Interop.Elementary.elm_calendar_interval_set(RealHandle, value);
344 /// Gets or sets the select day mode used.
346 public CalendarSelectMode SelectMode
350 return (CalendarSelectMode)Interop.Elementary.elm_calendar_select_mode_get(RealHandle);
354 Interop.Elementary.elm_calendar_select_mode_set(RealHandle, (Interop.Elementary.Elm_Calendar_Select_Mode)value);
359 /// Gets or sets fields of a datetime will be taken into account, when SelectedDate set is invoked.
361 public CalendarSelectable Selectable
365 return (CalendarSelectable)Interop.Elementary.elm_calendar_selectable_get(RealHandle);
369 Interop.Elementary.elm_calendar_selectable_set(RealHandle, (int)value);
374 /// Gets or sets date format the string that will be used to display month and year.
375 /// By default it uses strftime with "%B %Y" format string.
376 /// It should allocate the memory that will be used by the string, that will be freed by the widget after usage.A pointer to the string and a pointer to the time struct will be provided.
378 public DateFormatDelegate DateFormat
382 return _dateFormatDelegate;
386 _dateFormatDelegate = value;
389 Interop.Elementary.elm_calendar_format_function_set(RealHandle, _calendarFormat);
393 Interop.Elementary.elm_calendar_format_function_set(RealHandle, null);
399 /// Add a new mark to the calendar.
401 /// <param name="type">A string used to define the type of mark. It will be emitted to the theme, that should display a related modification on these days representation.</param>
402 /// <param name="date">A time struct to represent the date of inclusion of the mark. For marks that repeats it will just be displayed after the inclusion date in the calendar.</param>
403 /// <param name="repeat">Repeat the event following this periodicity. Can be a unique mark (that don't repeat), daily, weekly, monthly or annually.</param>
404 /// <returns>Item for a calendar mark.</returns>
405 public CalendarMark AddMark(string type, DateTime date, CalendarMarkRepeatType repeat)
407 CalendarMark mark = new CalendarMark(type, date, repeat);
408 Interop.Libc.SystemTime tm = date;
409 IntPtr nativeHandle = Interop.Elementary.elm_calendar_mark_add(RealHandle, type, ref tm, (Interop.Elementary.Elm_Calendar_Mark_Repeat_Type)repeat);
410 mark.Handle = nativeHandle;
416 /// Delete mark from the calendar.
418 /// <param name="mark">Item for a calendar mark</param>
419 public void DeleteMark(CalendarMark mark)
421 Interop.Elementary.elm_calendar_mark_del(mark.Handle);
425 /// Draw calendar marks.
427 public void DrawMarks()
429 Interop.Elementary.elm_calendar_marks_draw(RealHandle);
433 /// Remove all calendar's marks.
435 public void ClearMarks()
437 Interop.Elementary.elm_calendar_marks_clear(RealHandle);
440 protected override IntPtr CreateHandle(EvasObject parent)
442 IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
443 Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
445 RealHandle = Interop.Elementary.elm_calendar_add(handle);
446 Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
451 static void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
453 managedArray = new string[size];
454 IntPtr[] IntPtrArray = new IntPtr[size];
456 Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
458 for (int iterator = 0; iterator < size; iterator++)
460 managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);