diff --git a/docs/widgets/calendar.rst b/docs/widgets/calendar.rst index 76c53f5253..cbb81dde01 100644 --- a/docs/widgets/calendar.rst +++ b/docs/widgets/calendar.rst @@ -74,6 +74,14 @@ looks like ``const char * day_names[7] = {"Su", "Mo", ...};`` Only the pointer of the day names is saved so the elements should be static, global or constant variables. +Custom year list +---------------- + +Sets a custom year list with :cpp:expr:`lv_calendar_header_dropdown_set_year_list(calendar, years_list)` +where ``years_list`` is a pointer to the custom years list. It can be a constant string +like ``static const char * years = "2023\n2022\n2021\n2020\n2019";``, +or can be generated dynamically into a buffer as well. + .. _lv_calendar_events: Events diff --git a/src/widgets/calendar/lv_calendar_header_dropdown.c b/src/widgets/calendar/lv_calendar_header_dropdown.c index 79495cbcee..46440b3cfd 100644 --- a/src/widgets/calendar/lv_calendar_header_dropdown.c +++ b/src/widgets/calendar/lv_calendar_header_dropdown.c @@ -68,6 +68,31 @@ lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent) return obj; } +void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * years_list) +{ + /* Search for the header dropdown */ + lv_obj_t * header = lv_obj_get_child_by_type(parent, 0, &lv_calendar_header_dropdown_class); + if(NULL == header) { + /* Header not found */ + return; + } + + /* Search for the year dropdown + * Index is 0 because in the header dropdown constructor the year dropdpwn (year_dd) + * is the first created child of the header */ + const int32_t year_dropdown_index = 0; + lv_obj_t * year_dropdown = lv_obj_get_child_by_type(header, year_dropdown_index, &lv_dropdown_class); + if(NULL == year_dropdown) { + /* year dropdpwn not found */ + return; + } + + lv_dropdown_clear_options(year_dropdown); + lv_dropdown_set_options(year_dropdown, years_list); + + lv_obj_invalidate(parent); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -121,8 +146,15 @@ static void year_event_cb(lv_event_t * e) const lv_calendar_date_t * d; d = lv_calendar_get_showed_date(calendar); + + /* Get the first year on the options list + * NOTE: Assumes the first 4 digits in the option list are numbers */ + const char * year_p = lv_dropdown_get_options(dropdown); + const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 + + (year_p[3] - '0'); + lv_calendar_date_t newd = *d; - newd.year = 2023 - sel; + newd.year = year - sel; lv_calendar_set_showed_date(calendar, newd.year, newd.month); } @@ -134,7 +166,14 @@ static void value_changed_event_cb(lv_event_t * e) const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar); lv_obj_t * year_dd = lv_obj_get_child(header, 0); - lv_dropdown_set_selected(year_dd, 2023 - cur_date->year); + + /* Get the first year on the options list + * NOTE: Assumes the first 4 digits in the option list are numbers */ + const char * year_p = lv_dropdown_get_options(year_dd); + const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 + + (year_p[3] - '0'); + + lv_dropdown_set_selected(year_dd, year - cur_date->year); lv_obj_t * month_dd = lv_obj_get_child(header, 1); lv_dropdown_set_selected(month_dd, cur_date->month - 1); diff --git a/src/widgets/calendar/lv_calendar_header_dropdown.h b/src/widgets/calendar/lv_calendar_header_dropdown.h index 92f1f26bf4..c111e0ea09 100644 --- a/src/widgets/calendar/lv_calendar_header_dropdown.h +++ b/src/widgets/calendar/lv_calendar_header_dropdown.h @@ -36,6 +36,15 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_header_dropdown */ lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent); +/** + * Sets a custom calendar year list + * @param parent pointer to a calendar object + * @param years_list pointer to an const char array with the years list, see lv_dropdown set_options for more information. + * E.g. `const char * years = "2023\n2022\n2021\n2020\n2019" + * Only the pointer will be saved so this variable can't be local which will be destroyed later. + */ +void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * years_list); + /********************** * MACROS **********************/ diff --git a/tests/ref_imgs/widgets/calendar_08.png b/tests/ref_imgs/widgets/calendar_08.png new file mode 100644 index 0000000000..b6b061c3ae Binary files /dev/null and b/tests/ref_imgs/widgets/calendar_08.png differ diff --git a/tests/src/test_cases/widgets/test_calendar.c b/tests/src/test_cases/widgets/test_calendar.c index ad2e1668a0..5c2e16bb33 100644 --- a/tests/src/test_cases/widgets/test_calendar.c +++ b/tests/src/test_cases/widgets/test_calendar.c @@ -208,4 +208,16 @@ void test_calendar_get_btnmatrix(void) TEST_ASSERT_NOT_NULL(btnm); } +void test_calendar_custom_year_list(void) +{ + lv_obj_t * calendar = lv_calendar_create(lv_screen_active()); + + lv_calendar_header_dropdown_create(calendar); + + const char * years = "2024\n2023\n2022\n2021\n2020\n2019"; + lv_calendar_header_dropdown_set_year_list(calendar, years); + + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/calendar_08.png"); +} + #endif