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:
parent
a482132652
commit
def0169dda
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user