From: JEONGHYUN YUN Date: Tue, 10 Jan 2017 07:22:29 +0000 (+0900) Subject: elm_calendar: add APIs for minimum and maximum values for the date X-Git-Tag: submit/tizen/20170110.235747^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0686a84daca5d59ebc18cd1520e6a4eb640883d;p=platform%2Fupstream%2Felementary.git elm_calendar: add APIs for minimum and maximum values for the date elm_calendar already have minimum and maximum year set/get APIs. I've added new APIs that exapanded from the year to the date. These APIs help us not only set min/max month but also set min/max day. If you set the minimum date, changing the displayed month or year if needed. Displayed day also to be disabled if it is smaller than minimum date. Reviewers: woohyun, Hermet, jpeg, CHAN, cedric Reviewed By: CHAN, cedric Subscribers: CHAN, cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4226 Change-Id: If93e888eb76e1f84b2601a87b12b8b67f2d4820c Signed-off-by: JEONGHYUN YUN --- diff --git a/src/bin/test_calendar.c b/src/bin/test_calendar.c index 6f3eb5685..35e1bf95a 100644 --- a/src/bin/test_calendar.c +++ b/src/bin/test_calendar.c @@ -38,7 +38,6 @@ set_api_state(api_data *api) { Evas_Object *cal = eina_list_nth(items, 0); time_t the_time = (SEC_PER_YEAR * 41) + (SEC_PER_DAY * 9); /* Set date to DEC 31, 2010 */ - elm_calendar_min_max_year_set(cal, 2010, 2011); m = elm_calendar_mark_add(cal, "checked", gmtime(&the_time), ELM_CALENDAR_MONTHLY); elm_calendar_selected_time_set(cal, gmtime(&the_time)); } @@ -143,7 +142,6 @@ test_calendar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_ time_t the_time = (SEC_PER_YEAR * 41) + (SEC_PER_DAY * 9); /* Set date to DEC 31, 2010 */ elm_calendar_selected_time_set(cal, gmtime(&the_time)); - elm_calendar_min_max_year_set(cal, 2010, 2012); evas_object_show(cal); @@ -155,25 +153,30 @@ _print_cal_info(Evas_Object *cal, Evas_Object *en) { char info[1024]; double interval; - int year_min, year_max; Eina_Bool sel_enabled; const char **wds; struct tm stm; + const struct tm *mintm, *maxtm; if (!elm_calendar_selected_time_get(cal, &stm)) return; interval = elm_calendar_interval_get(cal); - elm_calendar_min_max_year_get(cal, &year_min, &year_max); + mintm = elm_calendar_date_min_get(cal); + maxtm = elm_calendar_date_max_get(cal); sel_enabled = !!(elm_calendar_select_mode_get(cal) != ELM_CALENDAR_SELECT_MODE_NONE); wds = elm_calendar_weekdays_names_get(cal); snprintf(info, sizeof(info), " Day: %i, Mon: %i, Year %i, WeekDay: %i
" - " Interval: %0.2f, Year_Min: %i, Year_Max %i, Sel Enabled : %i
" + " Interval: %0.2f, Sel Enabled : %i
" + " Day_Min : %i, Mon_Min : %i, Year_Min : %i
" + " Day_Max : %i, Mon_Max : %i, Year_Max : %i
" " Weekdays: %s, %s, %s, %s, %s, %s, %s
", stm.tm_mday, stm.tm_mon, stm.tm_year + 1900, stm.tm_wday, - interval, year_min, year_max, sel_enabled, + interval, sel_enabled, + mintm->tm_mday, mintm->tm_mon + 1, mintm->tm_year + 1900, + maxtm->tm_mday, maxtm->tm_mon + 1, maxtm->tm_year + 1900, wds[0], wds[1], wds[2], wds[3], wds[4], wds[5], wds[6]); elm_object_text_set(en, info); @@ -231,7 +234,11 @@ _calendar_create(Evas_Object *parent) elm_calendar_first_day_of_week_set(cal, ELM_DAY_SATURDAY); elm_calendar_interval_set(cal, 0.4); elm_calendar_format_function_set(cal, _format_month_year); - elm_calendar_min_max_year_set(cal, 2010, 2020); + + time_t the_time = (SEC_PER_YEAR * 40) + (SEC_PER_DAY * 24); /* Set min date to JAN 15, 2010 */ + elm_calendar_date_min_set(cal, gmtime(&the_time)); + the_time = (SEC_PER_YEAR * 42) + (SEC_PER_DAY * 3); /* Set max date to DEC 25, 2011 */ + elm_calendar_date_max_set(cal, gmtime(&the_time)); current_time = time(NULL) + 4 * SEC_PER_DAY; localtime_r(¤t_time, &selected_time); @@ -327,7 +334,6 @@ test_calendar2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event elm_calendar_marks_draw(cal3); evas_object_show(cal3); elm_box_pack_end(bxh, cal3); - elm_calendar_min_max_year_set(cal3, -1, -1); evas_object_show(win); } diff --git a/src/lib/elm_calendar.c b/src/lib/elm_calendar.c index 916cfda0f..994d58316 100644 --- a/src/lib/elm_calendar.c +++ b/src/lib/elm_calendar.c @@ -446,6 +446,17 @@ _cit_mark(Evas_Object *cal, int cit, const char *mtype) { + ELM_CALENDAR_DATA_GET(cal, sd); + + int day = cit - sd->first_day_it + 1; + int mon = sd->shown_time.tm_mon; + int yr = sd->shown_time.tm_year; + + if (strcmp(mtype, "clear") + && (((yr == sd->date_min.tm_year) && (mon == sd->date_min.tm_mon) && (day < sd->date_min.tm_mday)) + || ((yr == sd->date_max.tm_year) && (mon == sd->date_max.tm_mon) && (day > sd->date_max.tm_mday)))) + return; + char sign[64]; snprintf(sign, sizeof(sign), "cit_%i,%s", cit, mtype); @@ -820,7 +831,12 @@ _populate(Evas_Object *obj) if ((day) && (day <= maxdays)) { - _enable(sd, i); + if (((yr == sd->date_min.tm_year) && (mon == sd->date_min.tm_mon) && (day < sd->date_min.tm_mday)) + || ((yr == sd->date_max.tm_year) && (mon == sd->date_max.tm_mon) && (day > sd->date_max.tm_mday))) + _disable(sd, i); + else + _enable(sd, i); + snprintf(day_s, sizeof(day_s), "%i", day++); } else @@ -1127,6 +1143,20 @@ _fix_selected_time(Elm_Calendar_Data *sd) sd->selected_time.tm_mon = sd->shown_time.tm_mon; if (sd->selected_time.tm_year != sd->shown_time.tm_year) sd->selected_time.tm_year = sd->shown_time.tm_year; + + if ((sd->selected_time.tm_year == sd->date_min.tm_year) + && (sd->selected_time.tm_mon == sd->date_min.tm_mon) + && (sd->selected_time.tm_mday < sd->date_min.tm_mday)) + { + sd->selected_time.tm_mday = sd->date_min.tm_mday; + } + else if ((sd->selected_time.tm_year == sd->date_max.tm_year) + && (sd->selected_time.tm_mon == sd->date_max.tm_mon) + && (sd->selected_time.tm_mday > sd->date_max.tm_mday)) + { + sd->selected_time.tm_mday = sd->date_max.tm_mday; + } + mktime(&sd->selected_time); } @@ -1151,35 +1181,55 @@ _update_data(Evas_Object *obj, Eina_Bool month, if (month) { sd->shown_time.tm_mon += delta; - if (sd->shown_time.tm_mon < 0) + if (delta < 0) { - if (sd->shown_time.tm_year == sd->year_min) + if (sd->shown_time.tm_year == sd->date_min.tm_year) + { + if (sd->shown_time.tm_mon < sd->date_min.tm_mon) + { + sd->shown_time.tm_mon = sd->date_min.tm_mon; + return EINA_FALSE; + } + } + else if (sd->shown_time.tm_mon < 0) { - sd->shown_time.tm_mon++; - return EINA_FALSE; + sd->shown_time.tm_mon = 11; + sd->shown_time.tm_year--; } - sd->shown_time.tm_mon = 11; - sd->shown_time.tm_year--; } - else if (sd->shown_time.tm_mon > 11) + else { - if (sd->shown_time.tm_year == sd->year_max) + if (sd->shown_time.tm_year == sd->date_max.tm_year) { - sd->shown_time.tm_mon--; - return EINA_FALSE; + if (sd->shown_time.tm_mon > sd->date_max.tm_mon) + { + sd->shown_time.tm_mon = sd->date_max.tm_mon; + return EINA_FALSE; + } + } + else if (sd->shown_time.tm_mon > 11) + { + sd->shown_time.tm_mon = 0; + sd->shown_time.tm_year++; } - sd->shown_time.tm_mon = 0; - sd->shown_time.tm_year++; } } else { years = sd->shown_time.tm_year + delta; - if (((years > sd->year_max) && (sd->year_max != -1)) || - years < sd->year_min) + if (((years > sd->date_max.tm_year) && (sd->date_max.tm_year != -1)) || + years < sd->date_min.tm_year) return EINA_FALSE; sd->shown_time.tm_year = years; + if ((years == sd->date_min.tm_year) && (sd->shown_time.tm_mon < sd->date_min.tm_mon)) + { + sd->shown_time.tm_mon = sd->date_min.tm_mon; + } + else if ((years == sd->date_max.tm_year) && (sd->shown_time.tm_mon > sd->date_max.tm_mon)) + { + sd->shown_time.tm_mon = sd->date_max.tm_mon; + } } if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) @@ -1451,6 +1501,19 @@ _get_item_day(Evas_Object *obj, if ((day < 0) || (day > _maxdays_get(&sd->shown_time, 0))) return 0; + if ((sd->shown_time.tm_year == sd->date_min.tm_year) + && (sd->shown_time.tm_mon == sd->date_min.tm_mon) + && (day < sd->date_min.tm_mday)) + { + return 0; + } + else if ((sd->shown_time.tm_year == sd->date_max.tm_year) + && (sd->shown_time.tm_mon == sd->date_max.tm_mon) + && (day > sd->date_max.tm_mday)) + { + return 0; + } + return day; } @@ -1947,8 +2010,12 @@ _elm_calendar_evas_object_smart_add(Eo *obj, Elm_Calendar_Data *priv) elm_widget_sub_object_parent_add(obj); priv->first_interval = 0.85; - priv->year_min = 2; - priv->year_max = -1; + priv->date_min.tm_year = 2; + priv->date_min.tm_mon = 0; + priv->date_min.tm_mday = 1; + priv->date_max.tm_year = -1; + priv->date_max.tm_mon = 11; + priv->date_max.tm_mday = 31; priv->today_it = -1; priv->selected_it = -1; priv->first_day_it = -1; @@ -2242,29 +2309,157 @@ _elm_calendar_interval_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd) return sd->first_interval; } -EOLIAN static void -_elm_calendar_min_max_year_set(Eo *obj, Elm_Calendar_Data *sd, int min, int max) +EAPI void +elm_calendar_min_max_year_set(Evas_Object *obj, int min, int max) { + ELM_CALENDAR_DATA_GET(obj, sd); + min -= 1900; max -= 1900; - if ((sd->year_min == min) && (sd->year_max == max)) return; - sd->year_min = min > 2 ? min : 2; - if (max > sd->year_min) - sd->year_max = max; + if ((sd->date_min.tm_year == min) && (sd->date_max.tm_year == max)) return; + sd->date_min.tm_year = min > 2 ? min : 2; + if (max > sd->date_min.tm_year) + sd->date_max.tm_year = max; else - sd->year_max = sd->year_min; - if (sd->shown_time.tm_year > sd->year_max) - sd->shown_time.tm_year = sd->year_max; - if (sd->shown_time.tm_year < sd->year_min) - sd->shown_time.tm_year = sd->year_min; + sd->date_max.tm_year = sd->date_min.tm_year; + sd->date_min.tm_mon = 0; + sd->date_min.tm_mday = 1; + sd->date_max.tm_mon = 11; + sd->date_max.tm_mday = 31; + + if (sd->shown_time.tm_year > sd->date_max.tm_year) + sd->shown_time.tm_year = sd->date_max.tm_year; + if (sd->shown_time.tm_year < sd->date_min.tm_year) + sd->shown_time.tm_year = sd->date_min.tm_year; + evas_object_smart_changed(obj); } +EAPI void +elm_calendar_min_max_year_get(const Evas_Object *obj, int *min, int *max) +{ + ELM_CALENDAR_DATA_GET(obj, sd); + + if (min) *min = sd->date_min.tm_year + 1900; + if (max) *max = sd->date_max.tm_year + 1900; +} + EOLIAN static void -_elm_calendar_min_max_year_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd, int *min, int *max) +_elm_calendar_date_min_set(Eo *obj, Elm_Calendar_Data *sd, const struct tm *min) +{ + Eina_Bool upper = EINA_FALSE; + + if ((sd->date_min.tm_year == min->tm_year) + && (sd->date_min.tm_mon == min->tm_mon) + && (sd->date_min.tm_mday == min->tm_mday)) + return; + + if (min->tm_year < 2) + { + sd->date_min.tm_year = 2; + sd->date_min.tm_mon = 0; + sd->date_min.tm_mday = 1; + } + else + { + if (sd->date_max.tm_year != -1) + { + if (min->tm_year > sd->date_max.tm_year) + { + upper = EINA_TRUE; + } + else if (min->tm_year == sd->date_max.tm_year) + { + if (min->tm_mon > sd->date_max.tm_mon) + upper = EINA_TRUE; + else if ((min->tm_mon == sd->date_max.tm_mon) && (min->tm_mday > sd->date_max.tm_mday)) + upper = EINA_TRUE; + } + } + + if (upper) + { + sd->date_min.tm_year = sd->date_max.tm_year; + sd->date_min.tm_mon = sd->date_max.tm_mon; + sd->date_min.tm_mday = sd->date_max.tm_mday; + } + else + { + sd->date_min.tm_year = min->tm_year; + sd->date_min.tm_mon = min->tm_mon; + sd->date_min.tm_mday = min->tm_mday; + } + } + + if (sd->shown_time.tm_year <= sd->date_min.tm_year) + { + sd->shown_time.tm_year = sd->date_min.tm_year; + if (sd->shown_time.tm_mon < sd->date_min.tm_mon) + sd->shown_time.tm_mon = sd->date_min.tm_mon; + } + + _fix_selected_time(sd); + + evas_object_smart_changed(obj); +} + +EOLIAN static const struct tm * +_elm_calendar_date_min_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd) +{ + return &(sd->date_min); +} + +EOLIAN static void +_elm_calendar_date_max_set(Eo *obj, Elm_Calendar_Data *sd, const struct tm *max) +{ + Eina_Bool lower = EINA_FALSE; + + if ((sd->date_max.tm_year == max->tm_year) + && (sd->date_max.tm_mon == max->tm_mon) + && (sd->date_max.tm_mday == max->tm_mday)) + return; + + if (max->tm_year < sd->date_min.tm_year) + { + lower = EINA_TRUE; + } + else if (max->tm_year == sd->date_min.tm_year) + { + if (max->tm_mon < sd->date_min.tm_mon) + lower = EINA_TRUE; + else if ((max->tm_mon == sd->date_min.tm_mon) && (max->tm_mday < sd->date_min.tm_mday)) + lower = EINA_TRUE; + } + + if (lower) + { + sd->date_max.tm_year = sd->date_min.tm_year; + sd->date_max.tm_mon = sd->date_min.tm_mon; + sd->date_max.tm_mday = sd->date_min.tm_mday; + } + else + { + sd->date_max.tm_year = max->tm_year; + sd->date_max.tm_mon = max->tm_mon; + sd->date_max.tm_mday = max->tm_mday; + } + + if (sd->shown_time.tm_year >= sd->date_max.tm_year) + { + sd->shown_time.tm_year = sd->date_max.tm_year; + if (sd->shown_time.tm_mon > sd->date_max.tm_mon) + sd->shown_time.tm_mon = sd->date_max.tm_mon; + } + + _fix_selected_time(sd); + + evas_object_smart_changed(obj); +} + +EOLIAN static const struct tm * +_elm_calendar_date_max_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd) { - if (min) *min = sd->year_min + 1900; - if (max) *max = sd->year_max + 1900; + return &(sd->date_max); } EINA_DEPRECATED EAPI void diff --git a/src/lib/elm_calendar.eo b/src/lib/elm_calendar.eo index 871a1ebe1..6ec33236c 100644 --- a/src/lib/elm_calendar.eo +++ b/src/lib/elm_calendar.eo @@ -263,47 +263,6 @@ class Elm.Calendar (Elm.Layout, Elm_Interface_Atspi_Widget_Action) mode: Elm.Calendar.Select.Mode; [[The select mode to use.]] } } - @property min_max_year { - set { - [[\@MOBILE_ONLY - - Set the minimum and maximum values for the year - - Maximum must be greater than minimum, except if you don't want to set - maximum year. - Default values are 1902 and -1. - - If the maximum year is a negative value, it will be limited depending - on the platform architecture (year 2037 for 32 bits); - - See also @.min_max_year.get. - - \@ref calendar_example_03. - - \@if MOBILE \@since_tizen 2.4 - \@endif - ]] - } - get { - [[\@MOBILE_ONLY - - Get the minimum and maximum values for the year - - Default values are 1902 and -1. - - See also @.min_max_year.set for more details. - - \@ref calendar_example_05. - - \@if MOBILE \@since_tizen 2.4 - \@endif - ]] - } - values { - min: int; [[The minimum year, greater than 1901;]] - max: int; [[The maximum year;]] - } - } @property format_function { set { [[\@MOBILE_ONLY @@ -341,6 +300,58 @@ class Elm.Calendar (Elm.Layout, Elm_Interface_Atspi_Widget_Action) the selected date.]] } } + @property date_min { + [[Minimum date on calendar. + + See also @.date_max.set, @.date_max.get + + @since 1.19 + ]] + set { + [[Set minimum date on calendar. + + Set the minimum date, changing the displayed month or year if needed. + Displayed day also to be disabled if it is smaller than minimum date. + ]] + } + get { + [[Get minimum date. + + Default value is 1 JAN,1902. + ]] + } + values { + min: const(Elm_Calendar_Time)*; [[A tm struct to point to minimum date.]] + } + } + @property date_max { + [[Maximum date on calendar. + + See also @.date_min.set, @.date_min.get + + @since 1.19 + ]] + set { + [[Set maximum date on calendar. + + Set the maximum date, changing the displayed month or year if needed. + Displayed day also to be disabled if it is bigger than maximum date. + ]] + } + get { + [[Get maximum date. + + Default maximum year is -1. + Default maximum day and month are 31 and DEC. + + If the maximum year is a negative value, it will be limited depending + on the platform architecture (year 2037 for 32 bits); + ]] + } + values { + max: const(Elm_Calendar_Time)*; [[A tm struct to point to maximum date.]] + } + } @property marks { get { [[\@MOBILE_ONLY diff --git a/src/lib/elm_calendar_legacy.h b/src/lib/elm_calendar_legacy.h index 4cdc9f4fb..942de0898 100644 --- a/src/lib/elm_calendar_legacy.h +++ b/src/lib/elm_calendar_legacy.h @@ -1,3 +1,5 @@ +#include "elm_calendar.eo.legacy.h" + /** * @MOBILE_ONLY * @@ -18,4 +20,32 @@ */ EAPI Evas_Object *elm_calendar_add(Evas_Object *parent); -#include "elm_calendar.eo.legacy.h" \ No newline at end of file +/** + * Set the minimum and maximum values for the year. + * + * @param min The minimum year, greater than 1901. + * @param max The maximum year. + * + * Maximum must be greater than minimum, except if you don't want to set maximum year. + * Default values are 1902 and -1. + * If the maximum year is a negative value, it will be limited depending on the platform architecture. (year 2037 for 32 bits) + * + * @see elm_calendar_min_max_year_get() + * + * @ref calendar_example_03 + */ +EAPI void elm_calendar_min_max_year_set(Evas_Object *obj, int min, int max); + +/** + * Get the minimum and maximum values for the year. + * + * @param[out] min The minimum year, greater than 1901. + * @param[out] max The maximum year. + * + * Default values are 1902 and -1. + * + * @see elm_calendar_min_max_year_set() + * + * @ref calendar_example_05 + */ +EAPI void elm_calendar_min_max_year_get(const Evas_Object *obj, int *min, int *max); diff --git a/src/lib/elm_widget_calendar.h b/src/lib/elm_widget_calendar.h index 36ec378e5..45a3d1e14 100644 --- a/src/lib/elm_widget_calendar.h +++ b/src/lib/elm_widget_calendar.h @@ -38,7 +38,7 @@ struct _Elm_Calendar_Data Evas_Object *obj; // the object itself Eina_List *marks; double interval, first_interval; - int year_min, year_max, spin_speed; + int spin_speed; //TIZEN_ONLY(20161123): Support Focused UI. int focused_it; // @@ -46,7 +46,7 @@ struct _Elm_Calendar_Data Ecore_Timer *spin_month, *spin_year, *update_timer; Elm_Calendar_Format_Cb format_func; const char *weekdays[ELM_DAY_LAST]; - struct tm current_time, selected_time, shown_time; + struct tm current_time, selected_time, shown_time, date_min, date_max; Day_Color day_color[42]; // EINA_DEPRECATED Evas_Object *inc_btn_month; Evas_Object *dec_btn_month;