1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

Update lv_calendar.c

This commit is contained in:
Ali Rostami 2018-10-14 14:03:51 +03:30 committed by GitHub
parent a482132652
commit def0169dda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -34,7 +34,9 @@ typedef uint8_t day_draw_state_t;
**********************/ **********************/
static bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_design_mode_t mode); static bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_design_mode_t mode);
static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void * param); static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void * param);
static bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touched_point);
static lv_coord_t get_header_height(lv_obj_t * calendar); static lv_coord_t get_header_height(lv_obj_t * calendar);
static lv_coord_t get_day_names_height(lv_obj_t * calendar);
static void draw_header(lv_obj_t * calendar, const lv_area_t * mask); static void draw_header(lv_obj_t * calendar, const lv_area_t * mask);
static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask); static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask);
static void draw_days(lv_obj_t * calendar, const lv_area_t * mask); static void draw_days(lv_obj_t * calendar, const lv_area_t * mask);
@ -45,6 +47,7 @@ static const char * get_month_name(lv_obj_t * calendar, int32_t month);
static uint8_t get_month_length(int32_t year, int32_t month); static uint8_t get_month_length(int32_t year, int32_t month);
static uint8_t is_leap_year(uint32_t year); static uint8_t is_leap_year(uint32_t year);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
@ -183,6 +186,19 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
* Setter functions * Setter functions
*====================*/ *====================*/
/**
* Set a function to call when a calendar event happens
* @param calendar pointer to a calendar object
* @param action type of event form 'lv_action_t' (press, release, long press, long press repeat)
*/
void lv_calendar_set_action(lv_obj_t * calendar, lv_calendar_action_t type, lv_action_t action)
{
if(type >= LV_CALENDAR_ACTION_NUM) return;
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->actions[type] = action;
}
/** /**
* Set the today's date * Set the today's date
* @param calendar pointer to a calendar object * @param calendar pointer to a calendar object
@ -299,6 +315,18 @@ void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, lv_sty
* Getter functions * Getter functions
*====================*/ *====================*/
/**
* Get the action of a calendar
* @param calendar pointer to a calendar object
* @return pointer to the action function
*/
lv_action_t lv_calendar_get_action(const lv_obj_t * calendar, lv_calendar_action_t type)
{
if(type >= LV_CALENDAR_ACTION_NUM) return NULL;
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->actions[type];
}
/** /**
* Get the today's date * Get the today's date
@ -465,11 +493,26 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
if(sign == LV_SIGNAL_CLEANUP) { if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_PRESSED) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
/*Call the press action, 'param' is the caller indev_proc*/
if(ext->actions[LV_CALENDAR_ACTION_PR]) {
lv_indev_t * indev = lv_indev_get_act();
lv_point_t p;
lv_indev_get_point(indev, &p);
if(calculate_touched_day(calendar, &p)){
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
ext->btn_pressing = 0;
res = ext->actions[LV_CALENDAR_ACTION_PR](calendar);
}
}
} else if(sign == LV_SIGNAL_PRESSING) { } else if(sign == LV_SIGNAL_PRESSING) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
lv_area_t header_area; lv_area_t header_area;
lv_area_copy(&header_area, &calendar->coords); lv_area_copy(&header_area, &calendar->coords);
header_area.y2 = header_area.y1 + get_header_height(calendar); header_area.y2 = header_area.y1 + get_header_height(calendar);
lv_indev_t * indev = lv_indev_get_act(); lv_indev_t * indev = lv_indev_get_act();
lv_point_t p; lv_point_t p;
lv_indev_get_point(indev, &p); lv_indev_get_point(indev, &p);
@ -482,14 +525,22 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
if(ext->btn_pressing != 1) lv_obj_invalidate(calendar); if(ext->btn_pressing != 1) lv_obj_invalidate(calendar);
ext->btn_pressing = 1; ext->btn_pressing = 1;
} }
ext->pressed_date.year = 0;
} else if(calculate_touched_day(calendar, &p)) {
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
ext->btn_pressing = 0;
} else { } else {
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar); if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
ext->btn_pressing = 0; ext->btn_pressing = 0;
ext->pressed_date.year = 0;
} }
} else if(sign == LV_SIGNAL_PRESS_LOST) { } else if(sign == LV_SIGNAL_PRESS_LOST) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->pressed_date.year = 0;
ext->btn_pressing = 0; ext->btn_pressing = 0;
lv_obj_invalidate(calendar); lv_obj_invalidate(calendar);
} else if(sign == LV_SIGNAL_RELEASED) { } else if(sign == LV_SIGNAL_RELEASED) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
if(ext->btn_pressing < 0) { if(ext->btn_pressing < 0) {
@ -507,10 +558,28 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
ext->showed_date.month ++; ext->showed_date.month ++;
} }
} }
else if(ext->pressed_date.year != 0)
{
if(ext->actions[LV_CALENDAR_ACTION_CLICK]) {
res = ext->actions[LV_CALENDAR_ACTION_CLICK](calendar);
}
}
ext->pressed_date.year = 0;
ext->btn_pressing = 0; ext->btn_pressing = 0;
lv_obj_invalidate(calendar); lv_obj_invalidate(calendar);
} else if(sign == LV_SIGNAL_LONG_PRESS) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
if(ext->actions[LV_CALENDAR_ACTION_LONG_PR] && (ext->pressed_date.year != 0)) {
res = ext->actions[LV_CALENDAR_ACTION_LONG_PR](calendar);
}
} else if(sign == LV_SIGNAL_LONG_PRESS_REP) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
if(ext->actions[LV_CALENDAR_ACTION_LONG_PR_REPEAT] && (ext->pressed_date.year != 0)) {
res = ext->actions[LV_CALENDAR_ACTION_LONG_PR_REPEAT](calendar);
}
} else if(sign == LV_SIGNAL_CONTROLL) { } else if(sign == LV_SIGNAL_CONTROLL) {
uint8_t c = *((uint8_t *) param); uint8_t c = *((uint8_t *) param);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
@ -543,6 +612,60 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
return res; return res;
} }
/**
* It will check if the days part of calendar is touched
* and if it is, it will calculate the day and put it in pressed_date of calendar object.
* @param calendar pointer to a calendar object
* @param pointer to a point
* @return true: days part of calendar is touched and its related date is put in pressed date
* false: the point is out of days part area.
*/
static bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touched_point)
{
lv_area_t days_area;
lv_area_copy(&days_area, &calendar->coords);
lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
days_area.x1 += style_bg->body.padding.hor;
days_area.x2 -= style_bg->body.padding.hor;
days_area.y1 = calendar->coords.y1 + get_header_height(calendar) + get_day_names_height(calendar) - style_bg->body.padding.ver;
if(lv_area_is_point_on(&days_area, touched_point)) {
lv_coord_t w = (days_area.x2 - days_area.x1 + 1) / 7;
lv_coord_t h = (days_area.y2 - days_area.y1 + 1) / 6;
uint8_t x_pos = 0;
x_pos = (touched_point->x - days_area.x1) / w;
if(x_pos > 6) x_pos = 6;
uint8_t y_pos = 0;
y_pos = (touched_point->y - days_area.y1) / h;
if(y_pos > 5) y_pos = 5;
uint8_t i_pos = 0;
i_pos = (y_pos * 7) + x_pos;
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
if(i_pos < get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) ) {
ext->pressed_date.year = ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0);
ext->pressed_date.month = ext->showed_date.month == 1 ? 12 : (ext->showed_date.month - 1);
ext->pressed_date.day = get_month_length(ext->pressed_date.year, ext->pressed_date.month) -
get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;
}
else if(i_pos < (get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +
get_month_length(ext->showed_date.year, ext->showed_date.month))) {
ext->pressed_date.year = ext->showed_date.year;
ext->pressed_date.month = ext->showed_date.month;
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
}
else if(i_pos < 42) {
ext->pressed_date.year = ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0);
ext->pressed_date.month = ext->showed_date.month == 12 ? 1 : (ext->showed_date.month + 1);
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)
- get_month_length(ext->showed_date.year, ext->showed_date.month);
}
return true;
}else {
return false;
}
}
/** /**
* Get the height of a calendar's header based on it's style * Get the height of a calendar's header based on it's style
* @param calendar point to a calendar * @param calendar point to a calendar
@ -555,6 +678,18 @@ static lv_coord_t get_header_height(lv_obj_t * calendar)
return lv_font_get_height(ext->style_header->text.font) + ext->style_header->body.padding.ver * 2; return lv_font_get_height(ext->style_header->text.font) + ext->style_header->body.padding.ver * 2;
} }
/**
* Get the height of a calendar's day_names based on it's style
* @param calendar point to a calendar
* @return the day_names's height
*/
static lv_coord_t get_day_names_height(lv_obj_t * calendar)
{
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return lv_font_get_height(ext->style_day_names->text.font) + ext->style_day_names->body.padding.ver * 2;
}
/** /**
* Draw the calendar header with month name and arrows * Draw the calendar header with month name and arrows
* @param calendar point to a calendar * @param calendar point to a calendar