elm/calendar: add APIs for minimum and maximum values for the date

Summary:
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

Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
This commit is contained in:
JEONGHYUN YUN 2016-11-17 16:39:42 -08:00 committed by Cedric Bail
parent ec12506a88
commit 3f76638b37
5 changed files with 319 additions and 64 deletions

View File

@ -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<br/>"
" Interval: %0.2f, Year_Min: %i, Year_Max %i, Sel Enabled : %i<br/>"
" Interval: %0.2f, Sel Enabled : %i<br/>"
" Day_Min : %i, Mon_Min : %i, Year_Min : %i<br/>"
" Day_Max : %i, Mon_Max : %i, Year_Max : %i<br/>"
" Weekdays: %s, %s, %s, %s, %s, %s, %s<br/>",
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(&current_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);
}

View File

@ -287,6 +287,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);
@ -575,7 +586,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
@ -885,6 +901,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);
}
@ -909,35 +939,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)
{
sd->shown_time.tm_mon++;
return EINA_FALSE;
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 = 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)
@ -1209,6 +1259,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;
}
@ -1394,8 +1457,12 @@ _elm_calendar_efl_canvas_group_group_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;
@ -1647,29 +1714,153 @@ _elm_calendar_interval_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd)
return sd->first_interval;
}
EOLIAN static void
EAPI void
_elm_calendar_min_max_year_set(Eo *obj, Elm_Calendar_Data *sd, int min, int max)
{
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);
}
EOLIAN static void
EAPI void
_elm_calendar_min_max_year_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd, int *min, int *max)
{
if (min) *min = sd->year_min + 1900;
if (max) *max = sd->year_max + 1900;
if (min) *min = sd->date_min.tm_year + 1900;
if (max) *max = sd->date_max.tm_year + 1900;
}
EOLIAN static void
_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)
{
return &(sd->date_max);
}
EINA_DEPRECATED EAPI void

View File

@ -187,30 +187,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 {
[[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.
\@ref calendar_example_05.
]]
set {
}
get {
}
values {
min: int; [[The minimum year, greater than 1901;]]
max: int; [[The maximum year;]]
}
}
@property format_function {
set {
[[Set a function to format the string that will be used to display
@ -255,6 +231,58 @@ class Elm.Calendar (Elm.Layout, Elm.Interface.Atspi_Widget_Action)
return: const(list<ptr(Elm.Calendar.Mark)>); [[List with all calendar marks]]
}
}
@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(Efl.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(Efl.Time)*; [[A tm struct to point to maximum date.]]
}
}
selected_time_set {
[[Set selected date to be highlighted on calendar.

View File

@ -28,3 +28,33 @@ EAPI Evas_Object *elm_calendar_add(Evas_Object *parent);
* @ref calendar_example_06
*/
EAPI void elm_calendar_mark_del(Elm_Calendar_Mark *mark);
/**
* 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(Elm_Calendar *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 Elm_Calendar *obj, int *min, int *max);

View File

@ -37,12 +37,12 @@ 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;
int today_it, selected_it, first_day_it;
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;