feat(calendar): add chinese calendar (#5940)

Signed-off-by: lhdjply <lhdjply@126.com>
This commit is contained in:
lhdjply
2024-04-08 20:06:22 +08:00
committed by GitHub
parent b74d34407f
commit 466e29a1be
19 changed files with 22918 additions and 1200 deletions
+8
View File
@@ -671,6 +671,8 @@ menu "LVGL configuration"
bool "Enable Montserrat 28 compressed"
config LV_FONT_DEJAVU_16_PERSIAN_HEBREW
bool "Enable Dejavu 16 Persian, Hebrew, Arabic letters"
config LV_FONT_SIMSUN_14_CJK
bool "Enable Simsun 14 CJK"
config LV_FONT_SIMSUN_16_CJK
bool "Enable Simsun 16 CJK"
@@ -754,6 +756,9 @@ menu "LVGL configuration"
config LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW
bool "Dejavu 16 Persian, Hebrew, Arabic letters"
select LV_FONT_DEJAVU_16_PERSIAN_HEBREW
config LV_FONT_DEFAULT_SIMSUN_14_CJK
bool "Simsun 14 CJK"
select LV_FONT_SIMSUN_14_CJK
config LV_FONT_DEFAULT_SIMSUN_16_CJK
bool "Simsun 16 CJK"
select LV_FONT_SIMSUN_16_CJK
@@ -879,6 +884,9 @@ menu "LVGL configuration"
bool "Use calendar header dropdown"
depends on LV_USE_CALENDAR
default y
config LV_USE_CALENDAR_CHINESE
bool "Use chinese calendar"
depends on LV_USE_CALENDAR
config LV_USE_CANVAS
bool "Canvas. Requires: lv_image"
imply LV_USE_IMAGE
+15
View File
@@ -125,6 +125,21 @@ Drop-down
:cpp:expr:`lv_calendar_header_dropdown_create(calendar)` creates a header that
contains 2 drop-drown lists: one for the year and another for the month.
Chinese calendar
--------------
The Chinese calendar is a traditional cultural tool that integrates elements
such as the lunar calendar, solar terms, and traditional festivals. It is
widely used in Chinese social life, helping people understand the dates of
the lunar calendar, arrange festival activities, and inherit the excellent
traditional culture of the Chinese nation. Whether in families, businesses,
or education, the Chinese calendar plays an irreplaceable role, enabling
people to better understand and appreciate the charm of Chinese traditional
culture.
If you want to use the Chinese calendar, please
use :cpp:expr:`lv_calendar_set_chinese_mode(calendar, true)` to enable it.
.. _lv_calendar_example:
Example
+5
View File
@@ -5,3 +5,8 @@ Calendar with header
.. lv_example:: widgets/calendar/lv_example_calendar_1
:language: c
Chinese calendar
-------------------------------------
.. lv_example:: widgets/calendar/lv_example_calendar_2
:language: c
@@ -0,0 +1,32 @@
#include "../../lv_examples.h"
#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE && LV_BUILD_EXAMPLES
void lv_example_calendar_2(void)
{
lv_obj_t * calendar = lv_calendar_create(lv_screen_active());
lv_obj_set_size(calendar, 300, 300);
lv_obj_align(calendar, LV_ALIGN_TOP_MID, 0, 0);
lv_calendar_set_today_date(calendar, 2024, 03, 22);
lv_calendar_set_showed_date(calendar, 2024, 03);
#if LV_USE_CALENDAR_HEADER_DROPDOWN
lv_calendar_header_dropdown_create(calendar);
#elif LV_USE_CALENDAR_HEADER_ARROW
lv_calendar_header_arrow_create(calendar);
#endif
lv_calendar_set_chinese_mode(calendar, true);
lv_obj_set_style_text_font(calendar, &lv_font_simsun_14_cjk, LV_PART_MAIN);
}
#else
void lv_example_calendar_2(void)
{
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "chinese calendar is not enabled");
lv_obj_center(label);
}
#endif
+1
View File
@@ -47,6 +47,7 @@ void lv_example_buttonmatrix_2(void);
void lv_example_buttonmatrix_3(void);
void lv_example_calendar_1(void);
void lv_example_calendar_2(void);
void lv_example_canvas_1(void);
void lv_example_canvas_2(void);
+2
View File
@@ -426,6 +426,7 @@
/*Demonstrate special features*/
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/
#define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
/*Pixel perfect monospace fonts*/
@@ -524,6 +525,7 @@
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
#define LV_USE_CALENDAR_HEADER_ARROW 1
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
#define LV_USE_CALENDAR_CHINESE 0
#endif /*LV_USE_CALENDAR*/
#define LV_USE_CANVAS 1
File diff suppressed because one or more lines are too long
+4
View File
@@ -283,6 +283,10 @@ LV_FONT_DECLARE(lv_font_montserrat_28_compressed)
LV_FONT_DECLARE(lv_font_dejavu_16_persian_hebrew)
#endif
#if LV_FONT_SIMSUN_14_CJK
LV_FONT_DECLARE(lv_font_simsun_14_cjk)
#endif
#if LV_FONT_SIMSUN_16_CJK
LV_FONT_DECLARE(lv_font_simsun_16_cjk)
#endif
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+14
View File
@@ -1298,6 +1298,13 @@
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/
#endif
#endif
#ifndef LV_FONT_SIMSUN_14_CJK
#ifdef CONFIG_LV_FONT_SIMSUN_14_CJK
#define LV_FONT_SIMSUN_14_CJK CONFIG_LV_FONT_SIMSUN_14_CJK
#else
#define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/
#endif
#endif
#ifndef LV_FONT_SIMSUN_16_CJK
#ifdef CONFIG_LV_FONT_SIMSUN_16_CJK
#define LV_FONT_SIMSUN_16_CJK CONFIG_LV_FONT_SIMSUN_16_CJK
@@ -1610,6 +1617,13 @@
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
#endif
#endif
#ifndef LV_USE_CALENDAR_CHINESE
#ifdef CONFIG_LV_USE_CALENDAR_CHINESE
#define LV_USE_CALENDAR_CHINESE CONFIG_LV_USE_CALENDAR_CHINESE
#else
#define LV_USE_CALENDAR_CHINESE 0
#endif
#endif
#endif /*LV_USE_CALENDAR*/
#ifndef LV_USE_CANVAS
+2
View File
@@ -194,6 +194,8 @@ extern "C" {
# define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_28_compressed
#elif defined(CONFIG_LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW)
# define CONFIG_LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew
#elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_14_CJK)
# define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_14_cjk
#elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_16_CJK)
# define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_16_cjk
#elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_8)
+93 -3
View File
@@ -35,6 +35,13 @@ static uint8_t get_month_length(int32_t year, int32_t month);
static uint8_t is_leap_year(uint32_t year);
static void highlight_update(lv_obj_t * calendar);
#if LV_USE_CALENDAR_CHINESE
static lv_calendar_date_t gregorian_get_last_month_time(lv_calendar_date_t * time);
static lv_calendar_date_t gregorian_get_next_month_time(lv_calendar_date_t * time);
static void chinese_calendar_set_day_name(lv_obj_t * calendar, uint8_t index, uint8_t day,
lv_calendar_date_t * gregorian_time);
#endif
/**********************
* STATIC VARIABLES
**********************/
@@ -133,18 +140,54 @@ void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month)
uint8_t act_mo_len = get_month_length(d.year, d.month);
uint8_t day_first = get_day_of_week(d.year, d.month, 1);
uint8_t c;
#if LV_USE_CALENDAR_CHINESE
lv_calendar_date_t gregorian_time;
gregorian_time = d;
#endif
for(i = day_first, c = 1; i < act_mo_len + day_first; i++, c++) {
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
#if LV_USE_CALENDAR_CHINESE
if(calendar->use_chinese_calendar) {
gregorian_time.day = c;
chinese_calendar_set_day_name(obj, i, c, &gregorian_time);
}
else
#endif
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
}
uint8_t prev_mo_len = get_month_length(d.year, d.month - 1);
#if LV_USE_CALENDAR_CHINESE
gregorian_time = gregorian_get_last_month_time(&d);
#endif
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);
#if LV_USE_CALENDAR_CHINESE
if(calendar->use_chinese_calendar) {
gregorian_time.day = c;
chinese_calendar_set_day_name(obj, i, c, &gregorian_time);
}
else
#endif
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
lv_buttonmatrix_set_button_ctrl(calendar->btnm, i + 7, LV_BUTTONMATRIX_CTRL_DISABLED);
}
#if LV_USE_CALENDAR_CHINESE
gregorian_time = gregorian_get_next_month_time(&d);
#endif
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);
#if LV_USE_CALENDAR_CHINESE
if(calendar->use_chinese_calendar) {
gregorian_time.day = c;
chinese_calendar_set_day_name(obj, i, c, &gregorian_time);
}
else
#endif
lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c);
lv_buttonmatrix_set_button_ctrl(calendar->btnm, i + 7, LV_BUTTONMATRIX_CTRL_DISABLED);
}
@@ -285,6 +328,8 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_grow(calendar->btnm, 1);
lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
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);
}
@@ -408,4 +453,49 @@ static void highlight_update(lv_obj_t * obj)
}
}
#if LV_USE_CALENDAR_CHINESE
static lv_calendar_date_t gregorian_get_last_month_time(lv_calendar_date_t * time)
{
lv_calendar_date_t last_month_time;
if(time->month == 1) {
last_month_time.month = 12;
last_month_time.year = time->year - 1;
}
else {
last_month_time.month = time->month - 1;
last_month_time.year = time->year;
}
return last_month_time;
}
static lv_calendar_date_t gregorian_get_next_month_time(lv_calendar_date_t * time)
{
lv_calendar_date_t next_month_time;
if(time->month == 12) {
next_month_time.month = 1;
next_month_time.year = time->year + 1;
}
else {
next_month_time.month = time->month + 1;
next_month_time.year = time->year;
}
return next_month_time;
}
static void chinese_calendar_set_day_name(lv_obj_t * obj, uint8_t index, uint8_t day,
lv_calendar_date_t * gregorian_time)
{
lv_calendar_t * calendar = (lv_calendar_t *)obj;
const char * day_name = lv_calendar_get_day_name(gregorian_time);
if(day_name != NULL)
lv_snprintf(calendar->nums[index], sizeof(calendar->nums[0]),
"%d\n%s",
day,
day_name);
else
lv_snprintf(calendar->nums[index], sizeof(calendar->nums[0]), "%d", day);
}
#endif
#endif /*LV_USE_CALENDAR*/
+13
View File
@@ -44,7 +44,19 @@ typedef struct {
lv_calendar_date_t * highlighted_dates; /**< Apply different style on these days (pointer to user-defined array)*/
size_t highlighted_dates_num; /**< Number of elements in `highlighted_days`*/
const char * map[8 * 7];
#ifdef LV_USE_CALENDAR_CHINESE
bool use_chinese_calendar;
/* 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total.
20: Including the number of dates, line breaks, names for each day,
and reserving several spaces for addresses.*/
char nums [7 * 6][20];
#else
/* 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total.
6: Including the number of dates, and reserving several spaces for
addresses.*/
char nums [7 * 6][4];
#endif
} lv_calendar_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_class;
@@ -162,6 +174,7 @@ lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_
#include "lv_calendar_header_arrow.h"
#include "lv_calendar_header_dropdown.h"
#include "lv_calendar_chinese.h"
#endif /*LV_USE_CALENDAR*/
+287
View File
@@ -0,0 +1,287 @@
/**
* @file lv_calendar_chinese.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_calendar.h"
#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
const char festival_name[20];
uint8_t month;
uint8_t day;
} lv_calendar_festival_t;
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static const uint32_t calendar_chinese_table[199] = {/*1901-2099*/
0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, /*1901-1910*/
0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, /*1911-1920*/
0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, /*1921-1930*/
0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, /*1931-1940*/
0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, /*1941-1950*/
0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C, /*1951-1960*/
0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, /*1961-1970*/
0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, /*1971-1980*/
0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x093746, 0x5497BB, /*1981-1990*/
0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, /*1991-2000*/
0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, /*2001-2010*/
0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, /*2011-2020*/
0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x69573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, /*2021-2030*/
0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, /*2031-2040*/
0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, /*2041-2050*/
0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06B244, 0x4AB638, 0x0AAE4C, 0x092E42, /*2051-2060*/
0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, /*2061-2070*/
0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, /*2071-2080*/
0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, /*2081-2090*/
0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 /*2091-2099*/
};
static const uint16_t month_total_day[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
static const char * chinese_calendar_month_name[] = {"正月", "二月", "三月", "四月", "五月", "六月",
"七月", "八月", "九月", "十月", "十一月", "腊月"
};
static const char * chinese_calendar_leep_month_name[] = {"闰正月", "闰二月", "闰三月", "闰四月", "闰五月", "闰六月",
"闰七月", "闰八月", "闰九月", "闰十月", "闰十一月", "闰腊月"
};
static const char * chinese_calendar_day_name[] = {"初一", "初二", "初三", "初四", "初五",
"初六", "初七", "初八", "初九", "初十",
"十一", "十二", "十三", "十四", "十五",
"十六", "十七", "十八", "十九", "二十",
"廿一", "廿二", "廿三", "廿四", "廿五",
"廿六", "廿七", "廿八", "廿九", "三十"
};
static const lv_calendar_festival_t festivals_base_chinese[] = {
{"春节", 1, 1},
{"元宵节", 1, 15},
{"端午节", 5, 5},
{"七夕节", 7, 7},
{"中元节", 7, 15},
{"中秋节", 8, 15},
{"重阳节", 9, 9},
{"腊八节", 12, 8},
{"除夕", 12, 29},/* To determine whether it is 12.29 or 12.30. */
{"除夕", 12, 30},/* To determine whether it is 12.29 or 12.30. */
};
static const lv_calendar_festival_t festivals_base_gregorian[] = {
{"元旦", 1, 1},
{"情人节", 2, 14},
{"妇女节", 3, 8},
{"植树节", 3, 12},
{"消费节", 3, 15},
{"愚人节", 4, 1},
{"劳动节", 5, 1},
{"青年节", 5, 4},
{"儿童节", 6, 1},
{"建党节", 7, 1},
{"建军节", 8, 1},
{"教师节", 9, 10},
{"国庆节", 10, 1},
{"万圣节", 10, 31},
{"平安夜", 12, 24},
{"圣诞节", 12, 25},
};
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en)
{
lv_calendar_t * calendar = (lv_calendar_t *)obj;
calendar->use_chinese_calendar = en;
lv_calendar_set_showed_date(obj, calendar->today.year, calendar->today.month);
}
const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian)
{
uint16_t i, len;
lv_calendar_chinese_t chinese_calendar;
chinese_calendar = lv_calendar_gregorian_to_chinese(gregorian);
if(gregorian->year > 2099 || gregorian->year < 1901)
return NULL;
len = sizeof(festivals_base_chinese) / sizeof(lv_calendar_festival_t);
for(i = 0; i < len; i++) {
if((chinese_calendar.today.month == festivals_base_chinese[i].month) &&
(chinese_calendar.today.day == festivals_base_chinese[i].day) &&
chinese_calendar.leep_month == false) {
if(chinese_calendar.today.month == 12 && chinese_calendar.today.day == 29) {
if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0xf00000) != 0) {
if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0x000080) == 0) {
return festivals_base_chinese[i].festival_name;
}
}
else {
if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0x000100) == 0) {
return festivals_base_chinese[i].festival_name;
}
}
}
else {
return festivals_base_chinese[i].festival_name;
}
}
}
len = sizeof(festivals_base_gregorian) / sizeof(lv_calendar_festival_t);
for(i = 0; i < len; i++) {
if((gregorian->month == festivals_base_gregorian[i].month) &&
(gregorian->day == festivals_base_gregorian[i].day))
return festivals_base_gregorian[i].festival_name;
}
if(chinese_calendar.today.day == 1) {
if(chinese_calendar.leep_month == false)
return chinese_calendar_month_name[chinese_calendar.today.month - 1];
else {
return chinese_calendar_leep_month_name[chinese_calendar.today.month - 1];
}
}
return (char *)chinese_calendar_day_name[chinese_calendar.today.day - 1];
}
lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian)
{
uint16_t year = gregorian->year;
uint8_t month = gregorian->month;
uint8_t day = gregorian->day;
/*Record the number of days between the Spring Festival
and the New Year's Day of that year.*/
uint16_t by_spring;
/*Record the number of days from the gregorian calendar
to the New Year's Day of that year.*/
uint16_t by_gregorian;
/*Record the number of days in that month*/
uint8_t days_per_month;
/*Record from which month the calculation starts.*/
uint8_t index;
bool leep_month;
lv_calendar_chinese_t chinese_calendar;
if(year < 1901 || year > 2099) {
chinese_calendar.leep_month = 0;
chinese_calendar.today.year = 2000;
chinese_calendar.today.month = 1;
chinese_calendar.today.day = 1;
return chinese_calendar;
}
if(((calendar_chinese_table[year - 1901] & 0x0060) >> 5) == 1)
by_spring = (calendar_chinese_table[year - 1901] & 0x001F) - 1;
else
by_spring = (calendar_chinese_table[year - 1901] & 0x001F) - 1 + 31;
by_gregorian = month_total_day[month - 1] + day - 1;
if((!(year % 4)) && (month > 2))
by_gregorian++;
if(by_gregorian >= by_spring) {/*Gregorian calendar days after the Spring Festival*/
by_gregorian -= by_spring;
month = 1;
index = 1;
leep_month = false;
if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0)
days_per_month = 29;
else
days_per_month = 30;
while(by_gregorian >= days_per_month) {
by_gregorian -= days_per_month;
index++;
if(month == ((calendar_chinese_table[year - 1901] & 0xF00000) >> 20)) {
leep_month = !leep_month;
if(leep_month == false)
month++;
}
else
month++;
if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0)
days_per_month = 29;
else
days_per_month = 30;
}
day = by_gregorian + 1;
}
else {/*Solar day before the Spring Festival*/
by_spring -= by_gregorian;
year--;
month = 12;
if(((calendar_chinese_table[year - 1901] & 0xF00000) >> 20) == 0)
index = 12;
else
index = 13;
leep_month = false;
if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0)
days_per_month = 29;
else
days_per_month = 30;
while(by_spring > days_per_month) {
by_spring -= days_per_month;
index--;
if(leep_month == false)
month--;
if(month == ((calendar_chinese_table[year - 1901] & 0xF00000) >> 20))
leep_month = !leep_month;
if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0)
days_per_month = 29;
else
days_per_month = 30;
}
day = days_per_month - by_spring + 1;
}
chinese_calendar.today.day = day;
chinese_calendar.today.month = month;
chinese_calendar.today.year = year;
chinese_calendar.leep_month = leep_month;
return chinese_calendar;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_USE_CALENDAR_CHINESE*/
@@ -0,0 +1,67 @@
/**
* @file lv_calendar_chinese.h
*
*/
#ifndef LV_CALENDAR_CHINESE_H
#define LV_CALENDAR_CHINESE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../core/lv_obj.h"
#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_calendar_date_t today;
bool leep_month;
} lv_calendar_chinese_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Enable the chinese calendar.
* @param obj pointer to a calendar object.
* @param en true: enable chinese calendar; false: disable
*/
void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en);
/**
* Get the name of the day
* @param gregorian to obtain the gregorian time for the name
* @return return the name of the day
*/
const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian);
/**
* Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html)
* @param gregorian need to convert to chinese time in gregorian time
* @return return the chinese time of the gregorian time
*/
lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian);
/**********************
* MACROS
**********************/
#endif /*LV_USE_CALENDAR_CHINESE*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_CALENDAR_CHINESE_H*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+3
View File
@@ -34,6 +34,7 @@
#define LV_FONT_MONTSERRAT_48 1
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1
#define LV_FONT_SIMSUN_14_CJK 1
#define LV_FONT_SIMSUN_16_CJK 1
#define LV_FONT_UNSCII_8 1
#define LV_FONT_UNSCII_16 1
@@ -46,6 +47,8 @@
#define LV_USE_MEM_MONITOR 1
#define LV_LABEL_TEXT_SELECTION 1
#define LV_USE_CALENDAR_CHINESE 1
#define LV_USE_FLEX 1
#define LV_USE_GRID 1
@@ -220,4 +220,17 @@ void test_calendar_custom_year_list(void)
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/calendar_08.png");
}
void test_calendar_chinese_calendar(void)
{
lv_obj_set_size(g_calendar, 400, 350);
lv_obj_center(g_calendar);
lv_calendar_set_today_date(g_calendar, 2024, 03, 22);
lv_calendar_set_showed_date(g_calendar, 2024, 03);
lv_obj_set_style_text_font(g_calendar, &lv_font_simsun_14_cjk, LV_PART_MAIN);
lv_calendar_set_chinese_mode(g_calendar, true);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/calendar_09.png");
}
#endif