1 #include <Elementary.h>
8 * A calendar is a widget that allows the user to select a date. It has
9 * support to adding check marks (holidays and checks by default). The calendar
10 * is displayed one month at a time.
12 * Weekday names and the function used to format month and year to
13 * be displayed can be set, giving more flexibility to this widget.
15 * Signals that you can add callbacks for are:
17 * changed - emitted when the user selects a day or changes the displayed
18 * month, what actually changes the selected day as well.
20 typedef struct _Widget_Data Widget_Data;
24 Evas_Object *calendar;
26 double interval, first_interval;
27 int year_min, year_max, spin_speed;
28 int today_it, selected_it, first_day_it;
29 Ecore_Timer *spin, *update_timer;
30 char * (*format_func) (struct tm *stime);
31 const char *weekdays[7];
32 struct tm current_time, selected_time;
33 Eina_Bool selection_enabled : 1;
36 struct _Elm_Calendar_Mark
41 const char *mark_type;
42 Elm_Calendar_Mark_Repeat repeat;
45 static const char *widtype = NULL;
47 static const char *_days_abbrev[] =
49 "Sun", "Mon", "Tue", "Wed",
53 static int _days_in_month[2][12] =
55 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
56 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
59 static Elm_Calendar_Mark *
60 _mark_new(Evas_Object *obj, const char *mark_type, struct tm *mark_time, Elm_Calendar_Mark_Repeat repeat)
62 Widget_Data *wd = elm_widget_data_get(obj);
63 Elm_Calendar_Mark *mark;
66 mark = calloc(1, sizeof(Elm_Calendar_Mark));
67 if (!mark) return NULL;
69 mark->mark_type = eina_stringshare_add(mark_type);
70 mark->mark_time = *mark_time;
71 mark->repeat = repeat;
76 _mark_free(Elm_Calendar_Mark *mark)
78 eina_stringshare_del(mark->mark_type);
83 _sizing_eval(Evas_Object *obj)
85 Widget_Data *wd = elm_widget_data_get(obj);
86 Evas_Coord minw = -1, minh = -1;
88 elm_coords_finger_size_adjust(8, &minw, 7, &minh);
89 edje_object_size_min_restricted_calc(wd->calendar, &minw, &minh, minw, minh);
90 evas_object_size_hint_min_set(obj, minw, minh);
91 evas_object_size_hint_max_set(obj, -1, -1);
95 _maxdays_get(struct tm *time)
100 year = time->tm_year + 1900;
102 return _days_in_month[(!(year % 4) && (!(year % 400) || (year % 100)))]
107 _unselect(Widget_Data *wd, int selected)
110 snprintf(emission, sizeof(emission), "cit_%i,unselected", selected);
111 edje_object_signal_emit(wd->calendar, emission, "elm");
115 _select(Widget_Data *wd, int selected)
118 snprintf(emission, sizeof(emission), "cit_%i,selected", selected);
119 edje_object_signal_emit(wd->calendar, emission, "elm");
123 _not_today(Widget_Data *wd)
126 snprintf(emission, sizeof(emission), "cit_%i,not_today", wd->today_it);
127 edje_object_signal_emit(wd->calendar, emission, "elm");
132 _today(Widget_Data *wd, int it)
135 snprintf(emission, sizeof(emission), "cit_%i,today", it);
136 edje_object_signal_emit(wd->calendar, emission, "elm");
141 _format_month_year(struct tm *stime)
144 if (!strftime(buf, sizeof(buf), "%B %Y", stime)) return NULL;
149 _cit_mark(Evas_Object *cal, int cit, const char *mtype)
152 snprintf(sign, sizeof(sign), "cit_%i,%s", cit, mtype);
153 edje_object_signal_emit(cal, sign, "elm");
157 _weekday_get(int first_week_day, int day)
159 return (day + first_week_day - 1) % 7;
163 _populate(Evas_Object *obj)
165 int maxdays, day, mon, year, i;
166 Elm_Calendar_Mark *mark;
167 char part[12], day_s[3];
171 Eina_Bool last_row=1;
172 Widget_Data *wd = elm_widget_data_get(obj);
176 if (wd->today_it > 0) _not_today(wd);
178 maxdays = _maxdays_get(&wd->selected_time);
179 mon = wd->selected_time.tm_mon;
180 year = wd->selected_time.tm_year;
182 /* Set selected month */
183 buf = wd->format_func(&wd->selected_time);
186 edje_object_part_text_set(wd->calendar, "month_text", buf);
190 edje_object_part_text_set(wd->calendar, "month_text", "");
194 first_day = wd->selected_time;
195 first_day.tm_mday = 1;
198 wd->first_day_it = first_day.tm_wday;
200 if ((35- wd->first_day_it) >(maxdays-1))
205 for (i = 0; i < 5; i++)
208 snprintf(emission, sizeof(emission), "cseph_%i,row_hide", i);
209 edje_object_signal_emit(wd->calendar, emission, "elm");
212 snprintf(emission, sizeof(emission), "cseph_%i,row_invisible", 5);
213 edje_object_signal_emit(wd->calendar, emission, "elm");
215 for (i = 0; i < 35; i++)
218 snprintf(emission, sizeof(emission), "cit_%i,cell_expanded", i);
219 edje_object_signal_emit(wd->calendar, emission, "elm");
221 for (i = 35; i < 42; i++)
224 snprintf(emission, sizeof(emission), "cit_%i,cell_invisible", i);
225 edje_object_signal_emit(wd->calendar, emission, "elm");
230 for (i = 0; i < 6; i++)
233 snprintf(emission, sizeof(emission), "cseph_%i,row_show", i);
234 edje_object_signal_emit(wd->calendar, emission, "elm");
237 for (i = 0; i < 42; i++)
240 snprintf(emission, sizeof(emission), "cit_%i,cell_default", i);
241 edje_object_signal_emit(wd->calendar, emission, "elm");
245 for (i = 0; i < 42; i++)
247 if ((!day) && (i == first_day.tm_wday))
250 if ((day == wd->current_time.tm_mday)&& (mon == wd->current_time.tm_mon)&& (year == wd->current_time.tm_year))
253 if (day == wd->selected_time.tm_mday)
255 if ((wd->selected_it > -1) && (wd->selected_it != i))
256 _unselect(wd, wd->selected_it);
258 if (wd->selection_enabled) _select(wd, i);
263 if (day && (day <= maxdays))
264 snprintf(day_s, sizeof(day_s), "%d", day++);
268 snprintf(part, sizeof(part), "cit_%i.text", i);
269 edje_object_part_text_set(wd->calendar, part, day_s);
270 /* Clear previous marks */
271 _cit_mark(wd->calendar, i, "clear");
275 EINA_LIST_FOREACH(wd->marks, l, mark)
277 struct tm *mtime = &mark->mark_time;
278 int mon = wd->selected_time.tm_mon;
279 int year = wd->selected_time.tm_year;
280 int mday_it = mtime->tm_mday + wd->first_day_it - 1;
282 switch (mark->repeat)
284 case ELM_CALENDAR_UNIQUE:
286 if ((mtime->tm_mon == mon) && (mtime->tm_year == year))
287 _cit_mark(wd->calendar, mday_it, mark->mark_type);
290 case ELM_CALENDAR_DAILY:
292 if (((mtime->tm_year == year) && (mtime->tm_mon < mon)) ||(mtime->tm_year < year)) day = 1;
293 else if ((mtime->tm_year == year) && (mtime->tm_mon == mon))day = mtime->tm_mday;
295 for (; day <= maxdays; day++)
296 _cit_mark(wd->calendar, day + wd->first_day_it -1, mark->mark_type);
299 case ELM_CALENDAR_WEEKLY:
301 if (((mtime->tm_year == year) && (mtime->tm_mon < mon)) || (mtime->tm_year < year))day = 1;
302 else if ((mtime->tm_year == year) && (mtime->tm_mon == mon))day = mtime->tm_mday;
304 for (; day <= maxdays; day++)
305 if (mtime->tm_wday == _weekday_get(wd->first_day_it, day))
306 _cit_mark(wd->calendar, day + wd->first_day_it - 1,mark->mark_type);
309 case ELM_CALENDAR_MONTHLY:
311 if (((mtime->tm_year < year) ||((mtime->tm_year == year) && (mtime->tm_mon <= mon))) &&(mtime->tm_mday <= maxdays))
312 _cit_mark(wd->calendar, mday_it, mark->mark_type);
315 case ELM_CALENDAR_ANNUALLY:
317 if ((mtime->tm_year <= year) && (mtime->tm_mon == mon) &&(mtime->tm_mday <= maxdays))
318 _cit_mark(wd->calendar, mday_it, mark->mark_type);
326 _set_headers(Evas_Object *obj)
328 static char part[] = "ch_0.text";
330 Widget_Data *wd = elm_widget_data_get(obj);
333 for (i = 0; i < 7; i++)
336 edje_object_part_text_set(wd->calendar, part, wd->weekdays[i]);
341 _del_hook(Evas_Object *obj)
344 Elm_Calendar_Mark *mark;
345 Widget_Data *wd = elm_widget_data_get(obj);
349 if (wd->spin) ecore_timer_del(wd->spin);
350 if (wd->update_timer) ecore_timer_del(wd->update_timer);
353 EINA_LIST_FREE(wd->marks, mark)
358 for (i = 0; i < 7; i++)
359 eina_stringshare_del(wd->weekdays[i]);
365 _theme_hook(Evas_Object *obj)
367 Widget_Data *wd = elm_widget_data_get(obj);
369 _elm_theme_object_set(obj, wd->calendar, "calendar", "base",
370 elm_widget_style_get(obj));
373 edje_object_message_signal_process(wd->calendar);
374 edje_object_scale_set(wd->calendar,
375 elm_widget_scale_get(obj) * _elm_config->scale);
380 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
382 Widget_Data *wd = elm_widget_data_get(obj);
384 edje_object_signal_emit(wd->calendar, emission, source);
388 _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
390 Widget_Data *wd = elm_widget_data_get(obj);
392 edje_object_signal_callback_add(wd->calendar, emission,
393 source, func_cb, data);
397 _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source))
399 Widget_Data *wd = elm_widget_data_get(obj);
400 if (!wd) return NULL;
401 return edje_object_signal_callback_del(wd->calendar, emission, source, func_cb);
404 /* Set correct tm_wday and tm_yday after other fields changes*/
406 _fix_selected_time(Widget_Data *wd)
408 mktime(&wd->selected_time);
412 _update_month(Evas_Object *obj, int delta)
414 struct tm time_check;
416 Widget_Data *wd = elm_widget_data_get(obj);
417 if (!wd) return EINA_FALSE;
419 /* check if it's a valid time. for 32 bits, year greater than 2037 is not */
420 time_check = wd->selected_time;
421 time_check.tm_mon += delta;
422 if (mktime(&time_check) == -1)
425 wd->selected_time.tm_mon += delta;
426 if (wd->selected_time.tm_mon < 0)
428 if (wd->selected_time.tm_year == wd->year_min)
430 wd->selected_time.tm_mon++;
433 wd->selected_time.tm_mon = 11;
434 wd->selected_time.tm_year--;
436 else if (wd->selected_time.tm_mon > 11)
438 if (wd->selected_time.tm_year == wd->year_max)
440 wd->selected_time.tm_mon--;
443 wd->selected_time.tm_mon = 0;
444 wd->selected_time.tm_year++;
447 maxdays = _maxdays_get(&wd->selected_time);
448 if (wd->selected_time.tm_mday > maxdays)
449 wd->selected_time.tm_mday = maxdays;
451 _fix_selected_time(wd);
452 evas_object_smart_callback_call(obj, "changed", NULL);
458 _spin_value(void *data)
460 Widget_Data *wd = elm_widget_data_get(data);
461 if (!wd) return ECORE_CALLBACK_CANCEL;
462 if (_update_month(data, wd->spin_speed)) _populate(data);
463 wd->interval = wd->interval / 1.05;
464 ecore_timer_interval_set(wd->spin, wd->interval);
465 return ECORE_CALLBACK_RENEW;
469 _button_inc_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
471 Widget_Data *wd = elm_widget_data_get(data);
473 wd->interval = wd->first_interval;
475 if (wd->spin) ecore_timer_del(wd->spin);
476 wd->spin = ecore_timer_add(wd->interval, _spin_value, data);
481 _button_dec_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
483 Widget_Data *wd = elm_widget_data_get(data);
485 wd->interval = wd->first_interval;
487 if (wd->spin) ecore_timer_del(wd->spin);
488 wd->spin = ecore_timer_add(wd->interval, _spin_value, data);
493 _button_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
495 Widget_Data *wd = elm_widget_data_get(data);
497 wd->interval = wd->first_interval;
498 if (wd->spin) ecore_timer_del(wd->spin);
503 _get_item_day(Evas_Object *obj, int selected_it)
506 Widget_Data *wd = elm_widget_data_get(obj);
509 day = selected_it - wd->first_day_it + 1;
510 if ((day < 0) || (day > _maxdays_get(&wd->selected_time)))
517 _day_selected(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source)
520 Widget_Data *wd = elm_widget_data_get(data);
521 if ((!wd) || (!wd->selection_enabled))
523 sel_it = atoi(source);
524 day = _get_item_day(data, sel_it);
527 _unselect(wd, wd->selected_it);
528 wd->selected_it = sel_it;
529 wd->selected_time.tm_mday = day;
530 _select(wd, wd->selected_it);
531 _fix_selected_time(wd);
532 evas_object_smart_callback_call(data, "changed", NULL);
536 _time_to_next_day(struct tm *t)
538 return (((24 - t->tm_hour) * 60) - t->tm_min) * 60 - t->tm_sec;
542 _update_cur_date(void *data)
546 Widget_Data *wd = elm_widget_data_get(data);
547 if (!wd) return ECORE_CALLBACK_RENEW;
549 if (wd->today_it > 0) _not_today(wd);
551 current_time = time(NULL);
552 localtime_r(¤t_time, &wd->current_time);
553 t = _time_to_next_day(&wd->current_time);
554 ecore_timer_interval_set(wd->update_timer, t);
556 if ((wd->current_time.tm_mon != wd->selected_time.tm_mon) || (wd->current_time.tm_year!= wd->selected_time.tm_year))
557 return ECORE_CALLBACK_RENEW;
559 day = wd->current_time.tm_mday + wd->first_day_it - 1;
562 return ECORE_CALLBACK_RENEW;
566 * Add a new calendar to the parent
568 * @param parent The parent object
569 * @return The new object or NULL if it cannot be created
574 elm_calendar_add(Evas_Object *parent)
582 wd = ELM_NEW(Widget_Data);
583 e = evas_object_evas_get(parent);
584 obj = elm_widget_add(e);
585 ELM_SET_WIDTYPE(widtype, "calendar");
586 elm_widget_type_set(obj, "calendar");
587 elm_widget_sub_object_add(parent, obj);
588 elm_widget_data_set(obj, wd);
589 elm_widget_del_hook_set(obj, _del_hook);
590 elm_widget_theme_hook_set(obj, _theme_hook);
591 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
592 elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
593 elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
595 wd->first_interval = 0.85;
599 wd->selected_it = -1;
600 wd->first_day_it = -1;
601 wd->selection_enabled = EINA_TRUE;
602 wd->format_func = _format_month_year;
605 wd->calendar = edje_object_add(e);
606 _elm_theme_object_set(obj, wd->calendar, "calendar", "base", "default");
607 elm_widget_resize_object_set(obj, wd->calendar);
609 edje_object_signal_callback_add(wd->calendar, "elm,action,increment,start",
610 "*", _button_inc_start, obj);
611 edje_object_signal_callback_add(wd->calendar, "elm,action,decrement,start",
612 "*", _button_dec_start, obj);
613 edje_object_signal_callback_add(wd->calendar, "elm,action,stop",
614 "*", _button_stop, obj);
615 edje_object_signal_callback_add(wd->calendar, "elm,action,selected",
616 "*", _day_selected, obj);
618 for (i = 0; i < 7; i++)
619 wd->weekdays[i] = eina_stringshare_add(_days_abbrev[i]);
621 current_time = time(NULL);
622 localtime_r(¤t_time, &wd->selected_time);
623 wd->current_time = wd->selected_time;
624 t = _time_to_next_day(&wd->current_time);
625 wd->update_timer = ecore_timer_add(t, _update_cur_date, obj);
634 * Set weekdays names to display in the calendar.
636 * By default, the following abbreviations are displayed:
637 * "Sun, Mon, Tue, Wed, Thu, Fri, Sat"
638 * The first string should be related to Sunday, the second to Monday...
640 * The usage should be like this:
642 * const char *weekdays[] =
644 * "Sunday", "Monday", "Tuesday", "Wednesday",
645 * "Thursday", "Friday", "Saturday"
647 * elm_calendar_weekdays_names_set(calendar, weekdays);
650 * @param obj The calendar object
651 * @param weedays Array of seven strings to be used as weekday names.
652 * Warning: it must have 7 elements, or it will access invalid memory.
653 * The strings must be NULL terminated ('@\0').
658 elm_calendar_weekdays_names_set(Evas_Object *obj, const char *weekdays[])
661 ELM_CHECK_WIDTYPE(obj, widtype);
662 Widget_Data *wd = elm_widget_data_get(obj);
665 for (i = 0; i < 7; i++)
667 eina_stringshare_replace(&wd->weekdays[i], weekdays[i]);
673 * Get weekdays names displayed in the calendar.
675 * By default, the following abbreviations are displayed:
676 * "Sun, Mon, Tue, Wed, Thu, Fri, Sat"
677 * The first string is related to Sunday, the second to Monday...
679 * @param obj The calendar object
680 * @return Array of seven strings to used as weekday names.
685 elm_calendar_weekdays_names_get(const Evas_Object *obj)
687 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
688 Widget_Data *wd = elm_widget_data_get(obj);
689 if (!wd) return NULL;
694 * Set the interval for the calendar
696 * The interval value is decreased while the user increments or decrements
697 * the calendar value. The next interval value is the previous interval / 1.05,
698 * so it speed up a bit. Default value is 0.85 seconds.
700 * @param obj The calendar object
701 * @param interval The interval value in seconds
706 elm_calendar_interval_set(Evas_Object *obj, double interval)
708 ELM_CHECK_WIDTYPE(obj, widtype);
709 Widget_Data *wd = elm_widget_data_get(obj);
711 wd->first_interval = interval;
715 * Get the interval of the calendar
717 * The interval value is decreased while the user increments or decrements
718 * the calendar value. The next interval value is the previous interval / 1.05,
719 * so it speed up a bit. Default value is 0.85 seconds.
721 * @param obj The calendar object
722 * @return The value of the first interval in seconds
727 elm_calendar_interval_get(const Evas_Object *obj)
729 ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
730 Widget_Data *wd = elm_widget_data_get(obj);
732 return wd->first_interval;
736 * Set the minimum and maximum values for the year
738 * Maximum must be greater than minimum, except if you don't wan't to set
740 * Default values are 1902 and -1.
742 * If the maximum year is a negative value, it will be limited depending of the
743 * platform architecture (2037 for 32 bits);
745 * @param obj The calendar object
746 * @param min The minimum year, greater than 1901;
747 * @param max The maximum year;
752 elm_calendar_min_max_year_set(Evas_Object *obj, int min, int max)
754 ELM_CHECK_WIDTYPE(obj, widtype);
755 Widget_Data *wd = elm_widget_data_get(obj);
759 if ((wd->year_min == min) && (wd->year_max == max)) return;
760 wd->year_min = min > 2 ? min : 2;
761 if (wd->selected_time.tm_year > wd->year_max)
762 wd->selected_time.tm_year = wd->year_max;
763 if (wd->selected_time.tm_year < wd->year_min)
764 wd->selected_time.tm_year = wd->year_min;
765 _fix_selected_time(wd);
770 * Get the minimum and maximum values for the year
772 * Default values are 1902 and -1.
774 * If the maximum year is a negative value, it will be limited depending of the
775 * platform architecture (2037 for 32 bits);
777 * @param obj The calendar object
778 * @param min The minimum year
779 * @param max The maximum year
784 elm_calendar_min_max_year_get(const Evas_Object *obj, int *min, int *max)
788 ELM_CHECK_WIDTYPE(obj, widtype);
789 Widget_Data *wd = elm_widget_data_get(obj);
791 if (min) *min = wd->year_min + 1900;
792 if (max) *max = wd->year_max + 1900;
796 * Enable or disable day selection
798 * Enabled by default. If disabled, the user can select months, but not days.
799 * It should be used if you won't need such selection for the widget usage.
801 * @param obj The calendar object
802 * @param enabled Boolean to enable (true) or disable (false) day selection
807 elm_calendar_day_selection_enabled_set(Evas_Object *obj, Eina_Bool enabled)
809 ELM_CHECK_WIDTYPE(obj, widtype);
810 Widget_Data *wd = elm_widget_data_get(obj);
812 wd->selection_enabled = enabled;
814 _select(wd, wd->selected_it);
816 _unselect(wd, wd->selected_it);
820 * Get day selection state
822 * Enabled by default. If disabled, the user can select months, but not days.
823 * It should be used if you won't need such selection for the widget usage.
825 * @param obj The calendar object
826 * @return True if day selection is enabled, or false otherwise. It will
827 * return false if it can't get widget data.
832 elm_calendar_day_selection_enabled_get(const Evas_Object *obj)
834 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
835 Widget_Data *wd = elm_widget_data_get(obj);
836 if (!wd) return EINA_FALSE;
837 return wd->selection_enabled;
843 * Set the time selected, changing the displayed month if needed.
844 * Selected time changes when the user changes the month or select a day.
846 * @param obj The calendar object
847 * @param selected_time A tm struct to represent the selected date
852 elm_calendar_selected_time_set(Evas_Object *obj, struct tm *selected_time)
854 ELM_CHECK_WIDTYPE(obj, widtype);
855 Widget_Data *wd = elm_widget_data_get(obj);
857 wd->selected_time = *selected_time;
865 * Get the time selected by the user.
866 * Selected time changes when the user changes the month or select a day.
868 * @param obj The calendar object
869 * @param selected_time A tm struct to represent the selected date
870 * @return It will return false if it can't get widget data, or true otherwise
875 elm_calendar_selected_time_get(const Evas_Object *obj, struct tm *selected_time)
877 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
878 Widget_Data *wd = elm_widget_data_get(obj);
879 if (!wd) return EINA_FALSE;
880 if (selected_time) *selected_time = wd->selected_time;
885 * Set a function to format the string that will be used to display
888 * By default it uses strftime with "%B %Y" format string.
889 * It should allocate the memory that will be used by the string,
890 * that will be freed by the widget after usage.
891 * A pointer to the string and a pointer to the time struct will be provided.
896 * _format_month_year(struct tm *stime)
899 * if (!strftime(buf, sizeof(buf), "%B %Y", stime)) return NULL;
900 * return strdup(buf);
902 * elm_calendar_format_function_set(calendar, _format_month_year);
905 * @param obj The calendar object
906 * @param format_function Function to set the month-year string given
912 elm_calendar_format_function_set(Evas_Object *obj, char * (*format_function) (struct tm *stime))
914 ELM_CHECK_WIDTYPE(obj, widtype);
915 Widget_Data *wd = elm_widget_data_get(obj);
917 wd->format_func = format_function;
921 * Add a new mark to the calendar
923 * Add a mark that will be drawn in the calendar respecting the insertion time
924 * and periodicity. It will emit the type as signal to the widget theme.
925 * By default, it supports "holiday" and "checked", but it can be extended.
927 * It won't immediately update the calendar, drawing the marks. For this, call
928 * elm_calendar_marks_draw().
932 * struct tm selected_time;
933 * time_t current_time;
935 * current_time = time(NULL) + 5 * 84600;
936 * localtime_r(¤t_time, &selected_time);
937 * elm_calendar_mark_add(cal, "holiday", selected_time, ELM_CALENDAR_ANNUALLY);
939 * current_time = time(NULL) + 1 * 84600;
940 * localtime_r(¤t_time, &selected_time);
941 * elm_calendar_mark_add(cal, "checked", selected_time, ELM_CALENDAR_UNIQUE);
943 * elm_calendar_marks_draw(cal);
946 * @param obj The calendar object
947 * @param mark_type A string used to define the type of mark. It will be
948 * emmitted to the theme, that should display a related modification on these
949 * days representation.
950 * @param mark_time A time struct to represent the date of inclusion of the
951 * mark. For marks that repeats it will just be displayed after the inclusion
952 * date in the calendar.
953 * @param repeat Repeat the event following this periodicity. Can be a unique
954 * mark (that don't repeat), daily, weekly, monthly or annually.
956 * @return The created mark or NULL upon failure
960 EAPI Elm_Calendar_Mark *
961 elm_calendar_mark_add(Evas_Object *obj, const char *mark_type, struct tm *mark_time, Elm_Calendar_Mark_Repeat repeat)
963 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
964 Widget_Data *wd = elm_widget_data_get(obj);
965 Elm_Calendar_Mark *mark;
966 if (!wd) return NULL;
968 mark = _mark_new(obj, mark_type, mark_time, repeat);
969 wd->marks = eina_list_append(wd->marks, mark);
970 mark->node = eina_list_last(wd->marks);
975 * Delete mark from the calendar.
977 * @param mark The mark to delete
982 elm_calendar_mark_del(Elm_Calendar_Mark *mark)
990 wd = elm_widget_data_get(obj);
993 wd->marks = eina_list_remove_list(wd->marks, mark->node);
998 * Remove all the marks from the calendar
1000 * @param obj The calendar object
1005 elm_calendar_marks_clear(Evas_Object *obj)
1007 ELM_CHECK_WIDTYPE(obj, widtype);
1008 Widget_Data *wd = elm_widget_data_get(obj);
1009 Elm_Calendar_Mark *mark;
1012 EINA_LIST_FREE(wd->marks, mark)
1017 * Returns a list of all the calendar marks.
1019 * @param obj The calendar object
1020 * @return An Eina_List* of the calendar marks, or NULL on failure
1024 EAPI const Eina_List *
1025 elm_calendar_marks_get(const Evas_Object *obj)
1027 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1028 Widget_Data *wd = elm_widget_data_get(obj);
1029 if (!wd) return NULL;
1034 * Draw calendar marks.
1036 * Should be used after adding, removing or clearing marks.
1037 * It will go through the entire marks list updating the calendar
1038 * (not a cheap function). So if lots of marks will be added,
1039 * add all the marks and then call this function.
1041 * When the month is changed marks will be drawed.
1043 * @param obj The calendar object
1048 elm_calendar_marks_draw(Evas_Object *obj)
1050 ELM_CHECK_WIDTYPE(obj, widtype);
1051 Widget_Data *wd = elm_widget_data_get(obj);
1057 * Set a text color - blue.
1059 * @param obj The calendar object
1060 * @param pos The text position
1065 elm_calendar_text_saturday_color_set(const Evas_Object *obj, int pos)
1067 ELM_CHECK_WIDTYPE(obj, widtype);
1068 Widget_Data *wd = elm_widget_data_get(obj);
1072 snprintf(emission, sizeof(emission), "cit_%d,saturday", pos);
1073 edje_object_signal_emit(wd->calendar, emission, "elm");
1077 * Set a text color - red.
1079 * @param obj The calendar object
1080 * @param pos The text position
1085 elm_calendar_text_sunday_color_set(const Evas_Object *obj, int pos)
1087 ELM_CHECK_WIDTYPE(obj, widtype);
1088 Widget_Data *wd = elm_widget_data_get(obj);
1092 snprintf(emission, sizeof(emission), "cit_%d,sunday", pos);
1093 edje_object_signal_emit(wd->calendar, emission, "elm");
1097 * Set a text color - black.
1099 * @param obj The calendar object
1100 * @param pos The text position
1105 elm_calendar_text_weekday_color_set(const Evas_Object *obj, int pos)
1107 ELM_CHECK_WIDTYPE(obj, widtype);
1108 Widget_Data *wd = elm_widget_data_get(obj);
1112 snprintf(emission, sizeof(emission), "cit_%d,weekday", pos);
1113 edje_object_signal_emit(wd->calendar, emission, "elm");