mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
feat(calendar): add chinese calendar (#5940)
Signed-off-by: lhdjply <lhdjply@126.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
+1572
-1196
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user