feat(calendar): add the header directly into the calendar widget
In v8.0 the header was a detached object which made it difficult to move the header and the calendar together. Besides there were no way to notifi the header of the calendar's shown date has changed. BREAKING CHANGE: API of cleander headers, the appearence of the calendars related to #2573"
This commit is contained in:
@@ -14,7 +14,7 @@ The Calendar object is a classic calendar which can:
|
||||
|
||||
The Calendar is added to the default group (if it is set). Calendar is an editable object which allow selecting and clicking the dates with encoder navigation too.
|
||||
|
||||
To make the Calendar flexible, by default it doesn't show the current year or month. Instead, there are external "headers" that can be attached to the calendar.
|
||||
To make the Calendar flexible, by default it doesn't show the current year or month. Instead, there are optional "headers" that can be attached to the calendar.
|
||||
|
||||
## Parts and Styles
|
||||
The calendar object uses the [Button matrix](/widgets/core/btnmatrix) object under the hood to arrange the days into a matrix.
|
||||
@@ -57,14 +57,15 @@ Learn more about [Keys](/overview/indev).
|
||||
|
||||
## Headers
|
||||
|
||||
**From v8.1 the header is added directly into the Calendar widget and the API of the headers has been changed. **
|
||||
|
||||
### Arrow buttons
|
||||
|
||||
`lv_calendar_header_arrow_create(parent, calendar, button_size)` creates a header that contains a left and right arrow on the sides and a text with the current year and month between them.
|
||||
`lv_calendar_header_arrow_create(calendar)` creates a header that contains a left and right arrow on the sides and a text with the current year and month between them.
|
||||
|
||||
|
||||
### Drop-down
|
||||
`lv_calendar_header_dropdown_create(parent, calendar)` creates a header that contains 2 drop-drown lists: one for the year and another for the month.
|
||||
|
||||
`lv_calendar_header_dropdown_create(calendar)` creates a header that contains 2 drop-drown lists: one for the year and another for the month.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
static void event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
lv_obj_t * obj = lv_event_get_current_target(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
lv_calendar_date_t date;
|
||||
@@ -41,10 +41,11 @@ void lv_example_calendar_1(void)
|
||||
lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);
|
||||
|
||||
#if LV_USE_CALENDAR_HEADER_DROPDOWN
|
||||
lv_calendar_header_dropdown_create(lv_scr_act(), calendar);
|
||||
lv_calendar_header_dropdown_create(calendar);
|
||||
#elif LV_USE_CALENDAR_HEADER_ARROW
|
||||
lv_calendar_header_arrow_create(lv_scr_act(), calendar, 25);
|
||||
lv_calendar_header_arrow_create(calendar);
|
||||
#endif
|
||||
lv_calendar_set_showed_date(calendar, 2021, 10);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -118,7 +118,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
lv_style_t calendar_bg, calendar_day;
|
||||
lv_style_t calendar_btnm_bg, calendar_btnm_day, calendar_header;
|
||||
#endif
|
||||
|
||||
#if LV_USE_COLORWHEEL
|
||||
@@ -489,16 +489,21 @@ static void style_init(void)
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
style_init_reset(&styles->calendar_bg);
|
||||
lv_style_set_pad_all(&styles->calendar_bg, PAD_SMALL);
|
||||
lv_style_set_pad_gap(&styles->calendar_bg, PAD_SMALL / 2);
|
||||
lv_style_set_radius(&styles->calendar_bg, 0);
|
||||
style_init_reset(&styles->calendar_btnm_bg);
|
||||
lv_style_set_pad_all(&styles->calendar_btnm_bg, PAD_SMALL);
|
||||
lv_style_set_pad_gap(&styles->calendar_btnm_bg, PAD_SMALL / 2);
|
||||
|
||||
style_init_reset(&styles->calendar_day);
|
||||
lv_style_set_border_width(&styles->calendar_day, lv_disp_dpx(theme.disp, 1));
|
||||
lv_style_set_border_color(&styles->calendar_day, color_grey);
|
||||
lv_style_set_bg_color(&styles->calendar_day, color_card);
|
||||
lv_style_set_bg_opa(&styles->calendar_day, LV_OPA_20);
|
||||
style_init_reset(&styles->calendar_btnm_day);
|
||||
lv_style_set_border_width(&styles->calendar_btnm_day, lv_disp_dpx(theme.disp, 1));
|
||||
lv_style_set_border_color(&styles->calendar_btnm_day, color_grey);
|
||||
lv_style_set_bg_color(&styles->calendar_btnm_day, color_card);
|
||||
lv_style_set_bg_opa(&styles->calendar_btnm_day, LV_OPA_20);
|
||||
|
||||
style_init_reset(&styles->calendar_header);
|
||||
lv_style_set_pad_hor(&styles->calendar_header, PAD_SMALL);
|
||||
lv_style_set_pad_top(&styles->calendar_header, PAD_SMALL);
|
||||
lv_style_set_pad_bottom(&styles->calendar_header, PAD_TINY);
|
||||
lv_style_set_pad_gap(&styles->calendar_header, PAD_SMALL);
|
||||
#endif
|
||||
|
||||
#if LV_USE_COLORWHEEL
|
||||
@@ -659,6 +664,15 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
else if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) {
|
||||
/*No style*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_add_style(obj, &styles->card, 0);
|
||||
lv_obj_add_style(obj, &styles->scrollbar, LV_PART_SCROLLBAR);
|
||||
lv_obj_add_style(obj, &styles->scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED);
|
||||
@@ -714,6 +728,20 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) {
|
||||
lv_obj_add_style(obj, &styles->calendar_btnm_bg, 0);
|
||||
lv_obj_add_style(obj, &styles->outline_primary, LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles->outline_secondary, LV_STATE_EDITED);
|
||||
lv_obj_add_style(obj, &styles->calendar_btnm_day, LV_PART_ITEMS);
|
||||
lv_obj_add_style(obj, &styles->pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
|
||||
lv_obj_add_style(obj, &styles->disabled, LV_PART_ITEMS | LV_STATE_DISABLED);
|
||||
lv_obj_add_style(obj, &styles->outline_primary, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles->outline_secondary, LV_PART_ITEMS | LV_STATE_EDITED);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
lv_obj_add_style(obj, &styles->card, 0);
|
||||
lv_obj_add_style(obj, &styles->outline_primary, LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles->outline_secondary, LV_STATE_EDITED);
|
||||
@@ -901,26 +929,19 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
#if LV_USE_CALENDAR
|
||||
else if(lv_obj_check_type(obj, &lv_calendar_class)) {
|
||||
lv_obj_add_style(obj, &styles->card, 0);
|
||||
lv_obj_add_style(obj, &styles->calendar_bg, 0);
|
||||
lv_obj_add_style(obj, &styles->outline_primary, LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles->outline_secondary, LV_STATE_EDITED);
|
||||
lv_obj_add_style(obj, &styles->calendar_day, LV_PART_ITEMS);
|
||||
lv_obj_add_style(obj, &styles->pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
|
||||
lv_obj_add_style(obj, &styles->disabled, LV_PART_ITEMS | LV_STATE_DISABLED);
|
||||
lv_obj_add_style(obj, &styles->outline_primary, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles->outline_secondary, LV_PART_ITEMS | LV_STATE_EDITED);
|
||||
lv_obj_add_style(obj, &styles->pad_zero, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR_HEADER_ARROW
|
||||
else if(lv_obj_check_type(obj, &lv_calendar_header_arrow_class)) {
|
||||
lv_obj_add_style(obj, &styles->card, 0);
|
||||
lv_obj_add_style(obj, &styles->calendar_header, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR_HEADER_DROPDOWN
|
||||
else if(lv_obj_check_type(obj, &lv_calendar_header_dropdown_class)) {
|
||||
lv_obj_add_style(obj, &styles->card, 0);
|
||||
lv_obj_add_style(obj, &styles->calendar_header, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,10 +44,9 @@ const lv_obj_class_t lv_calendar_class = {
|
||||
.height_def = (LV_DPI_DEF * 3) / 2,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
|
||||
.instance_size = sizeof(lv_calendar_t),
|
||||
.base_class = &lv_btnmatrix_class
|
||||
.base_class = &lv_obj_class
|
||||
};
|
||||
|
||||
|
||||
static const char * day_names_def[7] = LV_CALENDAR_DEFAULT_DAY_NAMES;
|
||||
|
||||
/**********************
|
||||
@@ -79,6 +78,7 @@ void lv_calendar_set_day_names(lv_obj_t * obj, const char * day_names[])
|
||||
for(i = 0; i < 7; i++) {
|
||||
calendar->map[i] = day_names[i];
|
||||
}
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, uint32_t day)
|
||||
@@ -123,9 +123,9 @@ void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month)
|
||||
uint8_t i;
|
||||
|
||||
/*Remove the disabled state but revert it for day names*/
|
||||
lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
lv_btnmatrix_clear_btn_ctrl_all(calendar->btnm, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
for(i = 0; i < 7; i++) {
|
||||
lv_btnmatrix_set_btn_ctrl(obj, i, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
lv_btnmatrix_set_btn_ctrl(calendar->btnm, i, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
}
|
||||
|
||||
uint8_t act_mo_len = get_month_length(d.year, d.month);
|
||||
@@ -138,33 +138,44 @@ void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month)
|
||||
uint8_t prev_mo_len = get_month_length(d.year, d.month - 1);
|
||||
for(i = 0, c = prev_mo_len - day_first + 1; i < day_first; i++, c++) {
|
||||
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
|
||||
lv_btnmatrix_set_btn_ctrl(obj, i + 7, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
lv_btnmatrix_set_btn_ctrl(calendar->btnm, i + 7, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
}
|
||||
|
||||
for(i = day_first + act_mo_len, c = 1; i < 6 * 7; i++, c++) {
|
||||
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
|
||||
lv_btnmatrix_set_btn_ctrl(obj, i + 7, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
lv_btnmatrix_set_btn_ctrl(calendar->btnm, i + 7, LV_BTNMATRIX_CTRL_DISABLED);
|
||||
}
|
||||
|
||||
highlight_update(obj);
|
||||
|
||||
/*Reset the focused button if the days changes*/
|
||||
if(lv_btnmatrix_get_selected_btn(obj) != LV_BTNMATRIX_BTN_NONE) {
|
||||
lv_btnmatrix_set_selected_btn(obj, day_first + 7);
|
||||
if(lv_btnmatrix_get_selected_btn(calendar->btnm) != LV_BTNMATRIX_BTN_NONE) {
|
||||
lv_btnmatrix_set_selected_btn(calendar->btnm, day_first + 7);
|
||||
}
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
/* The children of the calendar are probably headers.
|
||||
* Notify them to let the headers updated to the new date*/
|
||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
lv_obj_t * child = lv_obj_get_child(obj, i);
|
||||
if(child == calendar->btnm) continue;
|
||||
lv_event_send(child, LV_EVENT_VALUE_CHANGED, obj);
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return return pointer to an `lv_calendar_date_t` variable containing the date of today.
|
||||
*/
|
||||
lv_obj_t * lv_calendar_get_btnmatrix(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
const lv_calendar_t * calendar = (lv_calendar_t *)obj;
|
||||
return calendar->btnm;
|
||||
}
|
||||
|
||||
const lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -173,11 +184,6 @@ const lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * obj)
|
||||
return &calendar->today;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently showed
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to an `lv_calendar_date_t` variable containing the date is being shown.
|
||||
*/
|
||||
const lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -186,11 +192,6 @@ const lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * obj)
|
||||
return &calendar->showed_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to an `lv_calendar_date_t` array containing the dates.
|
||||
*/
|
||||
lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -212,7 +213,7 @@ lv_res_t lv_calendar_get_pressed_date(const lv_obj_t * obj, lv_calendar_date_t *
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_calendar_t * calendar = (lv_calendar_t *)obj;
|
||||
|
||||
uint16_t d = lv_btnmatrix_get_selected_btn(obj);
|
||||
uint16_t d = lv_btnmatrix_get_selected_btn(calendar->btnm);
|
||||
if(d == LV_BTNMATRIX_BTN_NONE) {
|
||||
date->year = 0;
|
||||
date->month = 0;
|
||||
@@ -220,7 +221,7 @@ lv_res_t lv_calendar_get_pressed_date(const lv_obj_t * obj, lv_calendar_date_t *
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
const char * txt = lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj));
|
||||
const char * txt = lv_btnmatrix_get_btn_text(calendar->btnm, lv_btnmatrix_get_selected_btn(calendar->btnm));
|
||||
|
||||
if(txt[1] == 0) date->day = txt[0] - '0';
|
||||
else date->day = (txt[0] - '0') * 10 + (txt[1] - '0');
|
||||
@@ -272,14 +273,19 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o
|
||||
}
|
||||
calendar->map[8 * 7 - 1] = "";
|
||||
|
||||
lv_btnmatrix_set_map(obj, calendar->map);
|
||||
lv_btnmatrix_set_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CLICK_TRIG | LV_BTNMATRIX_CTRL_NO_REPEAT);
|
||||
calendar->btnm = lv_btnmatrix_create(obj);
|
||||
lv_btnmatrix_set_map(calendar->btnm, calendar->map);
|
||||
lv_btnmatrix_set_btn_ctrl_all(calendar->btnm, LV_BTNMATRIX_CTRL_CLICK_TRIG | LV_BTNMATRIX_CTRL_NO_REPEAT);
|
||||
lv_obj_add_event_cb(calendar->btnm, draw_part_begin_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
lv_obj_set_width(calendar->btnm, lv_pct(100));
|
||||
|
||||
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_grow(calendar->btnm, 1);
|
||||
|
||||
lv_calendar_set_showed_date(obj, calendar->showed_date.year, calendar->showed_date.month);
|
||||
lv_calendar_set_today_date(obj, calendar->today.year, calendar->today.month, calendar->today.day);
|
||||
|
||||
lv_obj_add_event_cb(obj, draw_part_begin_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
lv_obj_add_flag(calendar->btnm, LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
}
|
||||
|
||||
static void draw_part_begin_event_cb(lv_event_t * e)
|
||||
@@ -315,9 +321,6 @@ static void draw_part_begin_event_cb(lv_event_t * e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of days in a month
|
||||
* @param year a year
|
||||
@@ -378,20 +381,20 @@ static void highlight_update(lv_obj_t * obj)
|
||||
uint16_t i;
|
||||
|
||||
/*Clear all kind of selection*/
|
||||
lv_btnmatrix_clear_btn_ctrl_all(obj, LV_CALENDAR_CTRL_TODAY | LV_CALENDAR_CTRL_HIGHLIGHT);
|
||||
lv_btnmatrix_clear_btn_ctrl_all(calendar->btnm, LV_CALENDAR_CTRL_TODAY | LV_CALENDAR_CTRL_HIGHLIGHT);
|
||||
|
||||
uint8_t day_first = get_day_of_week(calendar->showed_date.year, calendar->showed_date.month, 1);
|
||||
if(calendar->highlighted_dates) {
|
||||
for(i = 0; i < calendar->highlighted_dates_num; i++) {
|
||||
if(calendar->highlighted_dates[i].year == calendar->showed_date.year &&
|
||||
calendar->highlighted_dates[i].month == calendar->showed_date.month) {
|
||||
lv_btnmatrix_set_btn_ctrl(obj, calendar->highlighted_dates[i].day - 1 + day_first + 7, LV_CALENDAR_CTRL_HIGHLIGHT);
|
||||
lv_btnmatrix_set_btn_ctrl(calendar->btnm, calendar->highlighted_dates[i].day - 1 + day_first + 7, LV_CALENDAR_CTRL_HIGHLIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(calendar->showed_date.year == calendar->today.year && calendar->showed_date.month == calendar->today.month) {
|
||||
lv_btnmatrix_set_btn_ctrl(obj, calendar->today.day - 1 + day_first + 7, LV_CALENDAR_CTRL_TODAY);
|
||||
lv_btnmatrix_set_btn_ctrl(calendar->btnm, calendar->today.day - 1 + day_first + 7, LV_CALENDAR_CTRL_TODAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ typedef struct {
|
||||
|
||||
/*Data of calendar*/
|
||||
typedef struct {
|
||||
lv_btnmatrix_t btnm;
|
||||
lv_obj_t obj;
|
||||
lv_obj_t * btnm;
|
||||
/*New data for this type*/
|
||||
lv_calendar_date_t today; /*Date of today*/
|
||||
lv_calendar_date_t showed_date; /*Currently visible month (day is ignored)*/
|
||||
@@ -102,6 +103,22 @@ void lv_calendar_set_day_names(lv_obj_t * obj, const char ** day_names);
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the header object of the calendar.
|
||||
* Date selectors can be created here
|
||||
* @param obj pointer to a calendar object
|
||||
* @return pointer to a container (lv_obj) for a header
|
||||
*/
|
||||
lv_obj_t * lv_calendar_get_header(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the button matrix object of the calendar.
|
||||
* It shows the dates and day names.
|
||||
* @param obj pointer to a calendar object
|
||||
* @return pointer to a the button matrix
|
||||
*/
|
||||
lv_obj_t * lv_calendar_get_btnmatrix(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
|
||||
@@ -27,18 +27,19 @@
|
||||
**********************/
|
||||
static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void month_event_cb(lv_event_t * e);
|
||||
static void value_changed_event_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
const lv_obj_class_t lv_calendar_header_arrow_class = {
|
||||
.base_class = &lv_obj_class,
|
||||
.constructor_cb = my_constructor
|
||||
.constructor_cb = my_constructor,
|
||||
.width_def = LV_PCT(100),
|
||||
.height_def = LV_DPI_DEF / 3
|
||||
};
|
||||
|
||||
static const char * month_names_def[12] = LV_CALENDAR_DEFAULT_MONTH_NAMES;
|
||||
static lv_obj_t * calendar_param;
|
||||
static lv_coord_t btn_size_param;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -48,10 +49,8 @@ static lv_coord_t btn_size_param;
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent, lv_obj_t * calendar, lv_coord_t btn_size)
|
||||
lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent)
|
||||
{
|
||||
calendar_param = calendar;
|
||||
btn_size_param = btn_size;
|
||||
lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_arrow_class, parent);
|
||||
lv_obj_class_init_obj(obj);
|
||||
return obj;
|
||||
@@ -67,41 +66,36 @@ static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
|
||||
LV_UNUSED(class_p);
|
||||
|
||||
/*Use the same paddings as the calendar_param*/
|
||||
lv_obj_set_style_pad_left(obj, lv_obj_get_style_pad_left(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_right(obj, lv_obj_get_style_pad_right(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_top(obj, lv_obj_get_style_pad_top(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_bottom(obj, lv_obj_get_style_pad_bottom(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_column(obj, lv_obj_get_style_pad_column(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_radius(obj, lv_obj_get_style_radius(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_move_to_index(obj, 0);
|
||||
|
||||
const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar_param);
|
||||
|
||||
lv_obj_update_layout(calendar_param);
|
||||
lv_coord_t w = lv_obj_get_width(calendar_param);
|
||||
lv_obj_set_size(obj, w, LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
|
||||
|
||||
lv_obj_t * mo_prev = lv_btn_create(obj);
|
||||
lv_obj_set_style_bg_img_src(mo_prev, LV_SYMBOL_LEFT, 0);
|
||||
lv_obj_set_size(mo_prev, btn_size_param, btn_size_param);
|
||||
lv_obj_add_event_cb(mo_prev, month_event_cb, LV_EVENT_CLICKED, calendar_param);
|
||||
lv_obj_set_height(mo_prev, lv_pct(100));
|
||||
lv_obj_update_layout(mo_prev);
|
||||
lv_coord_t btn_size = lv_obj_get_height(mo_prev);
|
||||
lv_obj_set_width(mo_prev, btn_size);
|
||||
|
||||
lv_obj_add_event_cb(mo_prev, month_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_clear_flag(mo_prev, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
|
||||
lv_obj_t * label = lv_label_create(obj);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_obj_set_flex_grow(label, 1);
|
||||
lv_label_set_text_fmt(label, "%d %s", cur_date->year, month_names_def[cur_date->month - 1]);
|
||||
|
||||
lv_obj_t * mo_next = lv_btn_create(obj);
|
||||
lv_obj_set_style_bg_img_src(mo_next, LV_SYMBOL_RIGHT, 0);
|
||||
lv_obj_set_size(mo_next, btn_size_param, btn_size_param);
|
||||
lv_obj_add_event_cb(mo_next, month_event_cb, LV_EVENT_CLICKED, calendar_param);
|
||||
lv_obj_set_size(mo_next, btn_size, btn_size);
|
||||
|
||||
lv_obj_add_event_cb(mo_next, month_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_clear_flag(mo_next, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
|
||||
lv_obj_align_to(obj, calendar_param, LV_ALIGN_OUT_TOP_MID, 0, 0);
|
||||
lv_obj_add_event_cb(obj, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
/*Refresh the drop downs*/
|
||||
lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
}
|
||||
|
||||
static void month_event_cb(lv_event_t * e)
|
||||
@@ -109,7 +103,7 @@ static void month_event_cb(lv_event_t * e)
|
||||
lv_obj_t * btn = lv_event_get_target(e);
|
||||
|
||||
lv_obj_t * header = lv_obj_get_parent(btn);
|
||||
lv_obj_t * calendar = lv_event_get_user_data(e);
|
||||
lv_obj_t * calendar = lv_obj_get_parent(header);
|
||||
|
||||
const lv_calendar_date_t * d;
|
||||
d = lv_calendar_get_showed_date(calendar);
|
||||
@@ -141,5 +135,15 @@ static void month_event_cb(lv_event_t * e)
|
||||
lv_label_set_text_fmt(label, "%d %s", newd.year, month_names_def[newd.month - 1]);
|
||||
}
|
||||
|
||||
static void value_changed_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * header = lv_event_get_target(e);
|
||||
lv_obj_t * calendar = lv_obj_get_parent(header);
|
||||
|
||||
const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar);
|
||||
lv_obj_t * label = lv_obj_get_child(header, 1);
|
||||
lv_label_set_text_fmt(label, "%d %s", cur_date->year, month_names_def[cur_date->month - 1]);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_CALENDAR_HEADER_ARROW*/
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ extern const lv_obj_class_t lv_calendar_header_arrow_class;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a calendar objects
|
||||
* @param par pointer to an object, it will be the parent of the new calendar
|
||||
* @return pointer to the created calendar
|
||||
* Create a calendar header with drop-drowns to select the year and month
|
||||
* @param parent pointer to a calendar object.
|
||||
* @return the created header
|
||||
*/
|
||||
lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent, lv_obj_t * calendar, lv_coord_t btn_size);
|
||||
lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -27,12 +27,15 @@
|
||||
static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void year_event_cb(lv_event_t * e);
|
||||
static void month_event_cb(lv_event_t * e);
|
||||
static void value_changed_event_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
const lv_obj_class_t lv_calendar_header_dropdown_class = {
|
||||
.base_class = &lv_obj_class,
|
||||
.width_def = LV_PCT(100),
|
||||
.height_def = LV_SIZE_CONTENT,
|
||||
.constructor_cb = my_constructor
|
||||
};
|
||||
|
||||
@@ -47,8 +50,6 @@ static const char * year_list = {
|
||||
"1920\n1919\n1918\n1917\n1916\n1915\n1914\n1913\n1912\n1911\n1910\n1909\n1908\n1907\n1906\n1905\n1904\n1903\n1902\n1901"
|
||||
};
|
||||
|
||||
static lv_obj_t * calendar_param;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -57,9 +58,8 @@ static lv_obj_t * calendar_param;
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent, lv_obj_t * calendar)
|
||||
lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent)
|
||||
{
|
||||
calendar_param = calendar;
|
||||
lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_dropdown_class, parent);
|
||||
lv_obj_class_init_obj(obj);
|
||||
|
||||
@@ -76,36 +76,23 @@ static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
|
||||
LV_UNUSED(class_p);
|
||||
|
||||
/*Use the same paddings as the calendar_param*/
|
||||
lv_obj_set_style_pad_left(obj, lv_obj_get_style_pad_left(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_right(obj, lv_obj_get_style_pad_right(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_top(obj, lv_obj_get_style_pad_top(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_bottom(obj, lv_obj_get_style_pad_bottom(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_pad_column(obj, lv_obj_get_style_pad_column(calendar_param, LV_PART_MAIN), 0);
|
||||
lv_obj_set_style_radius(obj, lv_obj_get_style_radius(calendar_param, LV_PART_MAIN), 0);
|
||||
|
||||
const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar_param);
|
||||
|
||||
lv_obj_update_layout(calendar_param);
|
||||
lv_coord_t w = lv_obj_get_width(calendar_param);
|
||||
lv_obj_set_size(obj, w, LV_SIZE_CONTENT);
|
||||
lv_obj_t * calendar = lv_obj_get_parent(obj);
|
||||
lv_obj_move_to_index(obj, 0);
|
||||
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
|
||||
|
||||
lv_obj_t * year_dd = lv_dropdown_create(obj);
|
||||
lv_dropdown_set_options(year_dd, year_list);
|
||||
lv_dropdown_set_selected(year_dd, 2023 - cur_date->year);
|
||||
lv_obj_add_event_cb(year_dd, year_event_cb, LV_EVENT_VALUE_CHANGED, calendar_param);
|
||||
lv_obj_add_event_cb(year_dd, year_event_cb, LV_EVENT_VALUE_CHANGED, calendar);
|
||||
lv_obj_set_flex_grow(year_dd, 1);
|
||||
|
||||
lv_obj_t * month_dd = lv_dropdown_create(obj);
|
||||
lv_dropdown_set_options(month_dd, month_list);
|
||||
lv_dropdown_set_selected(month_dd, cur_date->month - 1);
|
||||
lv_obj_add_event_cb(month_dd, month_event_cb, LV_EVENT_VALUE_CHANGED, calendar_param);
|
||||
lv_obj_add_event_cb(month_dd, month_event_cb, LV_EVENT_VALUE_CHANGED, calendar);
|
||||
lv_obj_set_flex_grow(month_dd, 1);
|
||||
|
||||
lv_obj_align_to(obj, calendar_param, LV_ALIGN_OUT_TOP_MID, 0, 0);
|
||||
|
||||
lv_obj_add_event_cb(obj, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
/*Refresh the drop downs*/
|
||||
lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
}
|
||||
|
||||
static void month_event_cb(lv_event_t * e)
|
||||
@@ -122,6 +109,7 @@ static void month_event_cb(lv_event_t * e)
|
||||
|
||||
lv_calendar_set_showed_date(calendar, newd.year, newd.month);
|
||||
}
|
||||
|
||||
static void year_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * dropdown = lv_event_get_target(e);
|
||||
@@ -137,5 +125,18 @@ static void year_event_cb(lv_event_t * e)
|
||||
lv_calendar_set_showed_date(calendar, newd.year, newd.month);
|
||||
}
|
||||
|
||||
static void value_changed_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * header = lv_event_get_target(e);
|
||||
lv_obj_t * calendar = lv_obj_get_parent(header);
|
||||
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);
|
||||
|
||||
lv_obj_t * month_dd = lv_obj_get_child(header, 1);
|
||||
lv_dropdown_set_selected(month_dd, cur_date->month - 1);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_CALENDAR_HEADER_ARROW*/
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ extern const lv_obj_class_t lv_calendar_header_dropdown_class;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a calendar objects
|
||||
* @param par pointer to an object, it will be the parent of the new calendar
|
||||
* @return pointer to the created calendar
|
||||
* Create a calendar header with drop-drowns to select the year and month
|
||||
* @param parent pointer to a calendar object.
|
||||
* @return the created header
|
||||
*/
|
||||
lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent, lv_obj_t * calendar);
|
||||
lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -858,7 +858,11 @@ static void draw_main(lv_event_t * e)
|
||||
txt_coords.y2 = obj->coords.y2;
|
||||
}
|
||||
|
||||
lv_draw_label(&txt_coords, clip_area, &label_draw_dsc, label->text, hint);
|
||||
if(label->long_mode == LV_LABEL_LONG_SCROLL || label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) {
|
||||
lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint);
|
||||
} else {
|
||||
lv_draw_label(&txt_coords, clip_area, &label_draw_dsc, label->text, hint);
|
||||
}
|
||||
|
||||
if(label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) {
|
||||
lv_point_t size;
|
||||
@@ -871,7 +875,7 @@ static void draw_main(lv_event_t * e)
|
||||
lv_font_get_glyph_width(label_draw_dsc.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||
label_draw_dsc.ofs_y = label->offset.y;
|
||||
|
||||
lv_draw_label(&txt_coords, clip_area, &label_draw_dsc, label->text, hint);
|
||||
lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint);
|
||||
}
|
||||
|
||||
/*Draw the text again below the original to make a circular effect */
|
||||
@@ -879,7 +883,7 @@ static void draw_main(lv_event_t * e)
|
||||
label_draw_dsc.ofs_x = label->offset.x;
|
||||
label_draw_dsc.ofs_y = label->offset.y + size.y + lv_font_get_line_height(label_draw_dsc.font);
|
||||
|
||||
lv_draw_label(&txt_coords, clip_area, &label_draw_dsc, label->text, hint);
|
||||
lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user