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:
Gabor Kiss-Vamosi
2021-10-25 18:38:51 +02:00
parent b59cc9cfb8
commit 2e08f80361
10 changed files with 174 additions and 122 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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*/

View File

@@ -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

View File

@@ -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*/

View File

@@ -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

View File

@@ -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);
}
}
}