当前位置: 首页 > news >正文

lvgl 实现横向滑动,并且捕获最中间那个元素

在这里插入图片描述
效果如图所示
核心代码为:

data->scroll_page = lv_obj_create(data->bg);lv_obj_set_size(data->scroll_page, 350, 130);// lv_obj_set_scroll_snap_x(data->scroll_page , LV_SCROLL_SNAP_START);lv_obj_set_style_bg_color(data->scroll_page, lv_color_make(0, 0, 0), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->scroll_page,LV_OPA_100,LV_PART_MAIN);lv_obj_clear_flag(data->scroll_page, LV_OBJ_FLAG_SCROLL_MOMENTUM);//去掉抛出效果lv_obj_set_style_pad_right(data->scroll_page, 18, LV_PART_MAIN);lv_obj_align(data->scroll_page, LV_ALIGN_TOP_MID, 10, 108);lv_obj_add_event_cb(data->scroll_page , _scroll_event_cb, LV_EVENT_ALL, data);#define FEMALE_BAR_DISPLAY    7
#define FEMALE_BAR_MAX        13
#define FEMALE_BAR_W    	  32
#define FEMALE_BAR_H    	  114
#define FEMALE_BAR_X    	  18
#define FEMALE_BAR_OFFSET     (FEMALE_BAR_W + FEMALE_BAR_X)
#define HOLE_DAY_RTC				86400
#define START_FEMALE_RTC			29
#define START_FEMALE_OFFSET_RTC		3static void _scroll_event_cb(lv_event_t* e)
{female_health_view_t* data = lv_event_get_user_data(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_SCROLL_END){printf("lv_obj_get_scroll_x(data->scroll_page)  %d %d\r\n",lv_obj_get_scroll_x(data->scroll_page),lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET);if(lv_obj_get_scroll_x(data->scroll_page) > 0){if(data->cur_pos < lv_obj_get_scroll_x(data->scroll_page)){data->move_dir = 1;}else {data->move_dir = 0;}}if(lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET != 0 && lv_obj_get_scroll_x(data->scroll_page) >0 \&& lv_obj_get_scroll_x(data->scroll_page) < (FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1))){if(data->move_dir == 1){if(lv_obj_get_scroll_x(data->scroll_page) > (FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1)))lv_obj_scroll_to_x(data->scroll_page, FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1), LV_ANIM_ON);elselv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)+(FEMALE_BAR_OFFSET-lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET), LV_ANIM_ON);}elselv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)-lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET, LV_ANIM_ON);}printf("LV_EVENT_SCROLL_END %d\r\n",lv_obj_get_scroll_x(data->scroll_page));data->cur_pos = lv_obj_get_scroll_x(data->scroll_page);if(lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET == 0){lv_obj_align_to(data->bar_dot, data->bar[START_FEMALE_OFFSET_RTC+(data->cur_pos/FEMALE_BAR_OFFSET)], LV_ALIGN_BOTTOM_MID, 0, -8);struct rtc_time temp_time = {0};uint16_t move_offset = START_FEMALE_OFFSET_RTC + lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET;uint32_t scroll_rtc = data->start_rtc + move_offset*HOLE_DAY_RTC;rtc_to_time(scroll_rtc,&temp_time);printf("scroll_rtc:%04d%02d%02d\r\n",temp_time.tm_year,temp_time.tm_mon,temp_time.tm_mday);lv_label_set_text_fmt(data->female_date, "%d/%d",temp_time.tm_mon,temp_time.tm_mday);update_female_tips(data);update_female_mark_txt(data);data->is_sliding = false;}}else if(code == LV_EVENT_SCROLL){data->is_sliding = true;}
}

上图所示女性健康UI实现代码如下

#include <stddef.h>
#include <stdint.h>
#include <ui_manager.h>
#include <lvgl/lvgl_res_loader.h>
#include "launcher_app.h"
#include "app_ui.h"
#ifdef CONFIG_PROPERTY
#include <property_manager.h>
#endif
#include "user_ui_common.h"
#include "model.h"
#include "user_file_tim.h"
#include "user_common_struct.h"static const uint32_t female_health_txt_ids[] = {STR_APPLIST_HEALTHY,STR_FEMALE_HEALTH_01,STR_FEMALE_HEALTH_02,STR_FEMALE_HEALTH_03,STR_FEMALE_HEALTH_11,STR_FEMALE_HEALTH_12,STR_FEMALE_HEALTH_04,STR_FEMALE_HEALTH_05,STR_FEMALE_HEALTH_06,STR_FEMALE_HEALTH_07,STR_FEMALE_HEALTH_08,STR_FEMALE_HEALTH_09,};
static const uint32_t female_health_img_ids[] = { A000_001,A000_034,A000_007,A000_014,
};typedef enum{E_FEMALE_TITLE,E_FEMALE_MAKE_BEGIN,E_FEMALE_MAKE_FINISG,E_FEMALE_MAKE_CANCEL,E_FEMALE_INVALID_TXT,E_FEMALE_NO_RECORD,E_FEMALE_FORECAST_MENSTRUAL,E_FEMALE_IN_MENSTRUAL,E_FEMALE_FORECAST_GESTATION,E_FEMALE_IN_GESTATION,E_FEMALE_FORECAST_OVULATION,E_FEMALE_IN_OVULATION,FEMALE_HEALTH_TXT_MAX,
}female_health_id;typedef enum{E_MARK_BEGIN,E_MARK_OVER,E_MARK_CANCEL,E_MARK_MAX,
}female_mark_type_t;#define FEMALE_HEALTH_IMG_MAX 4#define FEMALE_BAR_DISPLAY    7
#define FEMALE_BAR_MAX        13
#define FEMALE_BAR_W    	  32
#define FEMALE_BAR_H    	  114
#define FEMALE_BAR_X    	  18
#define FEMALE_BAR_OFFSET     (FEMALE_BAR_W + FEMALE_BAR_X)
#define HOLE_DAY_RTC				86400
#define START_FEMALE_RTC			29
#define START_FEMALE_OFFSET_RTC		3typedef struct {lv_obj_t* bg;lv_obj_t* invalid_img;lv_obj_t* invalid_txt;lv_obj_t* invalid_back;lv_obj_t* title;lv_obj_t* scroll_page;lv_obj_t* bar_dot;lv_obj_t* female_date;lv_obj_t* right_btn;lv_obj_t* left_btn;lv_obj_t* bar[FEMALE_BAR_DISPLAY*FEMALE_BAR_MAX];lv_obj_t* female_tip;lv_obj_t* mark_btn;lv_obj_t* mark_txt;lv_style_t style;lvgl_res_scene_t res_scene;lvgl_res_string_t res_string[FEMALE_HEALTH_TXT_MAX];lv_img_dsc_t img_dsc[FEMALE_HEALTH_IMG_MAX];female_mark_type_t mark_type;uint8_t mark_id;uint8_t move_dir;bool is_sliding;uint16_t cur_pos;uint32_t start_rtc;
} female_health_view_t;static void init_style(female_health_view_t* data);
static void obj_del(female_health_view_t *data);
static void create_female_bar(female_health_view_t* data,lv_obj_t* par);
static void _scroll_event_cb(lv_event_t* e);
static void invalid_back_event_cb(lv_event_t * e);
static void update_female_tips(female_health_view_t* data);
static void update_female_mark_txt(female_health_view_t* data);
static void update_female_bar(female_health_view_t* data);static void _female_health_unload_resource(female_health_view_t *data)
{lvgl_res_unload_scene(&data->res_scene);lvgl_res_unload_strings(data->res_string, FEMALE_HEALTH_TXT_MAX);lvgl_res_unload_pictures(data->img_dsc, FEMALE_HEALTH_IMG_MAX);
}static int _female_health_load_resource(female_health_view_t *data)
{int ret = 0;/* scene */ret = lvgl_res_load_scene(SCENE_FEMALE_HEALTH_VIEW, &data->res_scene, DEF_STY_FILE,DEF_RES_FILE, DEF_STR_FILE);if (ret < 0) {SYS_LOG_ERR("SCENE_FEMALE_HEALTH_VIEW not found");ret = -ENOENT;goto out_exit;}ret = lvgl_res_load_strings_from_scene(&data->res_scene, female_health_txt_ids,data->res_string, FEMALE_HEALTH_TXT_MAX);if (ret < 0) {goto out_exit;}ret = lvgl_res_load_pictures_from_scene(&data->res_scene, female_health_img_ids, data->img_dsc, NULL, FEMALE_HEALTH_IMG_MAX);if (ret < 0) {goto out_exit;}out_exit:if (ret < 0) {_female_health_unload_resource(data);}return ret;
}static int _female_health_view_preload(view_data_t *view_data)
{return lvgl_res_preload_scene_compact(SCENE_FEMALE_HEALTH_VIEW, NULL, 0,lvgl_res_scene_preload_default_cb_for_view,(void *)FEMALE_HEALTH_VIEW, DEF_STY_FILE, DEF_RES_FILE,DEF_STR_FILE);
}static int _female_health_view_layout(view_data_t *view_data)
{int ret = 0;lv_obj_t *scr = lv_disp_get_scr_act(view_data->display);female_health_view_t *data = NULL;data = app_mem_malloc(sizeof(*data));if (!data) {ret = -ENOMEM;goto out_exit;}view_data->user_data = data;memset(data, 0, sizeof(*data));ret = _female_health_load_resource(data);if (ret < 0) {goto out_exit;}//bg objinit_style(data);data->bg = lv_obj_create(scr);lv_obj_set_size(data->bg, DEF_UI_WIDTH, DEF_UI_HEIGHT);lv_obj_set_pos(data->bg,0,0);lv_obj_set_style_bg_color(data->bg, lv_color_make(0, 0, 0), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->bg,LV_OPA_100,LV_PART_MAIN);female_health_t* female_health = get_female_health_info();if(female_health->have_data == 0){data->invalid_img = lv_img_create(data->bg);lv_img_set_src(data->invalid_img, &data->img_dsc[2]);lv_obj_align(data->invalid_img, LV_ALIGN_TOP_MID, 0, 80);lv_obj_t* invalid_obj = lv_obj_create(data->bg);lv_obj_set_size(invalid_obj, 380, 100);lv_obj_set_style_bg_color(invalid_obj, lv_color_make(0, 0, 0), LV_PART_MAIN);lv_obj_set_style_bg_opa(invalid_obj,LV_OPA_100,LV_PART_MAIN);lv_obj_align_to(invalid_obj, data->invalid_img, LV_ALIGN_OUT_BOTTOM_MID, 0, 2);data->invalid_txt = lv_label_create(invalid_obj);lv_obj_add_style(data->invalid_txt, &data->style, LV_PART_MAIN);lv_obj_set_width(data->invalid_txt,380);lv_label_set_long_mode(data->invalid_txt,LV_LABEL_LONG_WRAP);lv_label_set_text(data->invalid_txt, data->res_string[E_FEMALE_INVALID_TXT].txt);lv_obj_align(data->invalid_txt, LV_ALIGN_TOP_MID, 0, 0);data->invalid_back = lv_img_create(data->bg);lv_img_set_src(data->invalid_back, &data->img_dsc[3]);lv_obj_align(data->invalid_back, LV_ALIGN_BOTTOM_MID, 0, 0);lv_obj_add_flag(data->invalid_back, LV_OBJ_FLAG_CLICKABLE);lv_obj_add_event_cb(data->invalid_back, invalid_back_event_cb, LV_EVENT_ALL, data);return 0;}data->title = lv_label_create(data->bg);lv_obj_add_style(data->title, &data->style, LV_PART_MAIN);lv_obj_set_width(data->title, 300);lv_label_set_long_mode(data->title, LV_LABEL_LONG_SCROLL_CIRCULAR);lv_label_set_text(data->title, data->res_string[E_FEMALE_TITLE].txt);lv_obj_align(data->title, LV_ALIGN_TOP_MID, 0, 50);data->scroll_page = lv_obj_create(data->bg);lv_obj_set_size(data->scroll_page, 350, 130);// lv_obj_set_scroll_snap_x(data->scroll_page , LV_SCROLL_SNAP_START);lv_obj_set_style_bg_color(data->scroll_page, lv_color_make(0, 0, 0), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->scroll_page,LV_OPA_100,LV_PART_MAIN);lv_obj_clear_flag(data->scroll_page, LV_OBJ_FLAG_SCROLL_MOMENTUM);lv_obj_set_style_pad_right(data->scroll_page, 18, LV_PART_MAIN);lv_obj_align(data->scroll_page, LV_ALIGN_TOP_MID, 10, 108);lv_obj_add_event_cb(data->scroll_page , _scroll_event_cb, LV_EVENT_ALL, data);create_female_bar(data,data->scroll_page);out_exit:return ret;
}
static void obj_del(female_health_view_t *data)
{lv_obj_del(data->bg);lv_style_reset(&data->style);}static void init_style(female_health_view_t* data)
{lv_style_init(&data->style);lv_style_set_text_align(&data->style, LV_TEXT_ALIGN_CENTER);lv_style_set_text_color(&data->style, lv_color_make(255, 255, 255));lv_style_set_text_font(&data->style, DEF_REGULAR_FONT38);
}static void invalid_back_event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);female_health_view_t* data = lv_event_get_user_data(e);lv_obj_t *obj = lv_event_get_target(e);if(code == LV_EVENT_CLICKED){if(obj == data->invalid_back){view_stack_pop();}}
}static void _scroll_event_cb(lv_event_t* e)
{female_health_view_t* data = lv_event_get_user_data(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_SCROLL_END){printf("lv_obj_get_scroll_x(data->scroll_page)  %d %d\r\n",lv_obj_get_scroll_x(data->scroll_page),lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET);if(lv_obj_get_scroll_x(data->scroll_page) > 0){if(data->cur_pos < lv_obj_get_scroll_x(data->scroll_page)){data->move_dir = 1;}else {data->move_dir = 0;}}if(lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET != 0 && lv_obj_get_scroll_x(data->scroll_page) >0 \&& lv_obj_get_scroll_x(data->scroll_page) < (FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1))){if(data->move_dir == 1){if(lv_obj_get_scroll_x(data->scroll_page) > (FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1)))lv_obj_scroll_to_x(data->scroll_page, FEMALE_BAR_OFFSET * FEMALE_BAR_DISPLAY * (FEMALE_BAR_MAX-1), LV_ANIM_ON);elselv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)+(FEMALE_BAR_OFFSET-lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET), LV_ANIM_ON);}elselv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)-lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET, LV_ANIM_ON);}printf("LV_EVENT_SCROLL_END %d\r\n",lv_obj_get_scroll_x(data->scroll_page));data->cur_pos = lv_obj_get_scroll_x(data->scroll_page);if(lv_obj_get_scroll_x(data->scroll_page) % FEMALE_BAR_OFFSET == 0){lv_obj_align_to(data->bar_dot, data->bar[START_FEMALE_OFFSET_RTC+(data->cur_pos/FEMALE_BAR_OFFSET)], LV_ALIGN_BOTTOM_MID, 0, -8);struct rtc_time temp_time = {0};uint16_t move_offset = START_FEMALE_OFFSET_RTC + lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET;uint32_t scroll_rtc = data->start_rtc + move_offset*HOLE_DAY_RTC;rtc_to_time(scroll_rtc,&temp_time);printf("scroll_rtc:%04d%02d%02d\r\n",temp_time.tm_year,temp_time.tm_mon,temp_time.tm_mday);lv_label_set_text_fmt(data->female_date, "%d/%d",temp_time.tm_mon,temp_time.tm_mday);update_female_tips(data);update_female_mark_txt(data);data->is_sliding = false;}}else if(code == LV_EVENT_SCROLL){data->is_sliding = true;}
}static void female_mark_begin_event(female_info_t* female_info,uint32_t rtc)
{//1.当前要标记的时间处在 最后标记的五天后 只需更新make_cnt  即可if(rtc > female_info->mark[female_info->mark_cnt-1].mark_finish + 5 * HOLE_DAY_RTC){printf("chen female_mark_begin_event %d\r\n",female_info->mark_cnt);if(female_info->mark_cnt <= FEMALE_MARK_MAX){if(female_info->mark_cnt == FEMALE_MARK_MAX){for(uint8_t j = 0; j < FEMALE_MARK_MAX; j++){memcpy(&female_info->mark[j], &female_info->mark[j+1], sizeof(female_mark_t));}	female_info->mark[female_info->mark_cnt-1].mark_begin = rtc;female_info->mark[female_info->mark_cnt-1].mark_finish = rtc + (female_info->menstrualPeriod - 1)*HOLE_DAY_RTC;}else{female_info->mark[female_info->mark_cnt].mark_begin = rtc;female_info->mark[female_info->mark_cnt].mark_finish = rtc + (female_info->menstrualPeriod - 1)*HOLE_DAY_RTC;female_info->mark_cnt++;}}return;}// //2. 当前要标记的时间是在 第一个标记的的前面 需要判断是否大于五天则设置新标记,小于五天合并两个标记,// if(rtc < female_info->mark[0].mark_begin - 5 * HOLE_DAY_RTC)// {// 	if(female_info->mark_cnt < FEMALE_MARK_MAX)// 	{// 		for (uint8_t i = 1; i < female_info->mark_cnt; i++)// 		{// 			female_info->mark[i+1].mark_begin = female_info->mark[i].mark_begin;// 			female_info->mark[i+1].mark_finish = female_info->mark[i].mark_finish;// 		}// 		female_info->mark_cnt++;// 		female_info->mark_menstrualStartRtc = female_info->mark[female_info->mark_cnt-1].mark_begin;// 	}// 	female_info->mark[0].mark_begin = rtc;// 	female_info->mark[0].mark_finish = rtc + (female_info->menstrualPeriod - 1)*HOLE_DAY_RTC;// 	return;// }// else if(rtc >= female_info->mark[0].mark_begin - 5 * HOLE_DAY_RTC && rtc < female_info->mark[0].mark_finish)// {// 	female_info->mark[0].mark_begin = rtc;// 	return;// }//3. 在中间插入的话,需要判断该日期与上一个日期间隔是否大于5天,如果大于5天则直接插入,如果当前标记已经满了5个就让他取代他的下一个日期//否则合并到他的下一个日期里面for (uint8_t i = 0; i < female_info->mark_cnt; i++){if(rtc < female_info->mark[i].mark_begin - 5 * HOLE_DAY_RTC){if(female_info->mark_cnt == FEMALE_MARK_MAX){female_info->mark[i].mark_begin = rtc;female_info->mark[i].mark_finish = rtc + (female_info->menstrualPeriod - 1)*HOLE_DAY_RTC;;return;}else{for(uint8_t j = i; j< female_info->mark_cnt; j++){female_info->mark[j+1].mark_begin = female_info->mark[j].mark_begin;female_info->mark[j+1].mark_finish = female_info->mark[j].mark_finish;}female_info->mark[i].mark_begin = rtc;female_info->mark[i].mark_finish = rtc + (female_info->menstrualPeriod - 1)*HOLE_DAY_RTC;;female_info->mark_cnt++;return;}}else if(rtc<female_info->mark[i].mark_finish){female_info->mark[i].mark_begin = rtc;return;}}}static void female_mark_over_event(female_info_t* female_info,uint32_t rtc)
{//1.当前要标记的时间处在最后一处标记的时间之后,则直接修改标记结束时间if(rtc > female_info->mark[female_info->mark_cnt-1].mark_finish){female_info->mark[female_info->mark_cnt-1].mark_finish = rtc;return;}//2.若是在中间插入则要判断这个时间是否处在下一个标记时间的五天内如果是则要合并两个标记for(uint8_t i = 0;i < female_info->mark_cnt;i++){if(rtc - female_info->mark[i].mark_finish <= 5 * HOLE_DAY_RTC){female_info->mark[i].mark_finish = rtc;if(female_info->mark_cnt >= 2){if(female_info->mark[i+1].mark_begin - female_info->mark[i].mark_finish <= 5 * HOLE_DAY_RTC){female_info->mark[i].mark_finish = female_info->mark[i+1].mark_finish;female_info->mark[i+1].mark_begin = 0;female_info->mark[i+1].mark_finish = 0;female_info->mark_cnt--;}}return;}}}static void female_mark_cancel_event(female_info_t* female_info,uint32_t rtc)
{uint8_t id_pos = 0xff;for (uint8_t i = 0; i < female_info->mark_cnt; i++){if(rtc >= female_info->mark[i].mark_begin && rtc <= female_info->mark[i].mark_finish){id_pos = i;break;}}if(id_pos!=0xff){if(rtc == female_info->mark[id_pos].mark_begin)//清除该次标记{if(id_pos == female_info->mark_cnt-1)//清楚最后一个{memset(&female_info->mark[id_pos],0,sizeof(female_mark_t));female_info->mark_cnt--;}else{for(uint8_t i = id_pos;i<female_info->mark_cnt-1;i++){memcpy(&female_info->mark[i],&female_info->mark[i+1],sizeof(female_mark_t));}memset(&female_info->mark[female_info->mark_cnt-1],0,sizeof(female_mark_t));female_info->mark_cnt--;}}else{uint8_t delete_day = (female_info->mark[id_pos].mark_finish - rtc)/HOLE_DAY_RTC + 1;female_info->mark[id_pos].mark_finish = female_info->mark[id_pos].mark_finish - delete_day*HOLE_DAY_RTC;}}}static void female_mark_menstrual_day(female_health_view_t* data,uint32_t set_rtc)
{female_info_t female_info = {0};kospet_get_female_info(&female_info);if(female_info.mark_cnt == 0){female_info.mark[female_info.mark_cnt].mark_begin = set_rtc;female_info.mark[female_info.mark_cnt].mark_finish = set_rtc + (female_info.menstrualPeriod - 1)*HOLE_DAY_RTC;female_info.mark_cnt++;}else{if(data->mark_type == E_MARK_BEGIN){female_mark_begin_event(&female_info,set_rtc);}else if(data->mark_type == E_MARK_OVER){female_mark_over_event(&female_info,set_rtc);}else if(data->mark_type == E_MARK_CANCEL){female_mark_cancel_event(&female_info,set_rtc);}}kospet_set_female_info(&female_info);update_female_bar(data);update_female_mark_txt(data);
}static void click_event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);female_health_view_t* data = (female_health_view_t*)lv_event_get_user_data(e);lv_obj_t *obj = lv_event_get_target(e);if (code == LV_EVENT_CLICKED){if(obj == data->right_btn){lv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)+FEMALE_BAR_OFFSET, LV_ANIM_OFF);}else if(obj == data->left_btn){lv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)-FEMALE_BAR_OFFSET, LV_ANIM_OFF);}else if (obj == data->mark_btn){if(get_connection_flag()->app_act == NOT_CONNECTED){send_handle_msgbox_msg(MSGBOX_ID_COMMON_TIPS, E_FEMALE_NO_APP);return;}struct rtc_time temp_time = {0};uint16_t move_offset = START_FEMALE_OFFSET_RTC + lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET;printf("mark btn clicked %d\r\n",move_offset);uint32_t mark_rtc = data->start_rtc + move_offset*HOLE_DAY_RTC;rtc_to_time(mark_rtc,&temp_time);printf("mark_rtc:%04d%02d%02d\r\n",temp_time.tm_year,temp_time.tm_mon,temp_time.tm_mday);/** 设置标记日子*/female_mark_menstrual_day(data,mark_rtc);}}
}static lv_color_t check_female_bar_color(uint32_t rtc)
{female_health_t* female_health = get_female_health_info();bool is_menstrual = false;lv_color_t bar_color = lv_color_make(25, 25, 25);if((female_health->menstrual_start_time_l!=0 && rtc >= female_health->menstrual_start_time_l && rtc <= female_health->menstrual_end_time_l) ||(rtc >= female_health->menstrual_start_time_n && rtc <= female_health->menstrual_end_time_n) ||(rtc >= female_health->menstrual_start_time && rtc <= female_health->menstrual_end_time)){bar_color = lv_color_make(88, 38, 41);is_menstrual = true;}else if((female_health->easy_gestation_start_time_l != 0 && rtc >= female_health->easy_gestation_start_time_l && rtc <= female_health->easy_gestation_end_time_l) ||(rtc >= female_health->easy_gestation_start_time_n && rtc <= female_health->easy_gestation_end_time_n)||(rtc >= female_health->easy_gestation_start_time && rtc <= female_health->easy_gestation_end_time)){if(rtc == female_health->ovulation_time ||  rtc == female_health->ovulation_time_n || rtc == female_health->ovulation_time_l){bar_color = lv_color_make(43, 94, 48);}else{bar_color = lv_color_make(36, 74, 74);}}else{bar_color = lv_color_make(25, 25, 25);}if(female_health->mark_cnt > 0){for (uint8_t i = 0; i < female_health->mark_cnt; i++){if(rtc >= female_health->female_mark[i].mark_begin && rtc <= female_health->female_mark[i].mark_finish){bar_color = lv_color_make(245, 80, 87);}if(is_menstrual){if((female_health->menstrual_start_time_l != 0 && female_health->menstrual_start_time_l == female_health->female_mark[i].mark_begin)|| female_health->menstrual_start_time == female_health->female_mark[i].mark_begin)//|| female_health->menstrual_start_time_n == female_health->female_mark[i].mark_begin{if(((female_health->menstrual_end_time_l != 0 && rtc <= female_health->menstrual_end_time_l)|| (rtc <= female_health->menstrual_end_time))//(rtc <= female_health->menstrual_end_time_n) ||&& (rtc > female_health->female_mark[i].mark_finish)){bar_color = lv_color_make(25, 25, 25);}}}}}return bar_color;
}static void update_female_bar(female_health_view_t* data)
{uint32_t start_rtc = data->start_rtc;for (uint8_t i = 0; i < FEMALE_BAR_DISPLAY*FEMALE_BAR_MAX; i++){lv_obj_set_style_bg_color(data->bar[i], check_female_bar_color(start_rtc), LV_PART_MAIN);start_rtc+=HOLE_DAY_RTC;}
}
/*
* 1.存在标记的时候,在标记的内的日期显示月经第几天,在标记外的显示无记录,直到最后一个标记结束均采用该规则
* 2.标记结束或不存在标记,月经期前显示月经期前几天,处在月经期内显示预测月经第几天,易孕期期也是如此,如果排卵日泽显示排卵日
*/
static void update_female_tips(female_health_view_t* data)
{female_health_t* female_health = get_female_health_info();// struct rtc_time temp_time = {0};uint32_t cur_rtc = data->start_rtc + (lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET+START_FEMALE_OFFSET_RTC)*HOLE_DAY_RTC;// rtc_to_time(cur_rtc,&temp_time);// printf("update_female_tips:%04d%02d%02d\r\n",temp_time.tm_year,temp_time.tm_mon,temp_time.tm_mday);bool is_write = false;if(female_health->mark_cnt > 0){for (uint8_t i = 0; i < female_health->mark_cnt; i++){if(i == 0 && cur_rtc < female_health->female_mark[i].mark_begin){is_write = true;lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_NO_RECORD].txt);break;}else{if(cur_rtc >= female_health->female_mark[i].mark_begin && cur_rtc <= female_health->female_mark[i].mark_finish){is_write = true;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_MENSTRUAL].txt,((cur_rtc-female_health->female_mark[i].mark_begin)/HOLE_DAY_RTC) + 1);break;}else if(cur_rtc > female_health->female_mark[i].mark_finish && cur_rtc < female_health->female_mark[i+1].mark_begin){is_write = true;lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_NO_RECORD].txt);break;}}}}if(!is_write){uint16_t display_day = 0;if(cur_rtc < female_health->menstrual_start_time_l){display_day = (female_health->menstrual_start_time_l - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_MENSTRUAL].txt,display_day);}else if(cur_rtc >= female_health->menstrual_start_time_l && cur_rtc < female_health->menstrual_end_time_l){display_day = (cur_rtc - female_health->menstrual_start_time_l)/HOLE_DAY_RTC + 1;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_MENSTRUAL].txt,display_day);}else if(cur_rtc < female_health->easy_gestation_start_time_l){display_day = (female_health->easy_gestation_start_time_l - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_GESTATION].txt,display_day);}else if(cur_rtc >= female_health->easy_gestation_start_time_l && cur_rtc < female_health->easy_gestation_end_time_l){display_day = (cur_rtc - female_health->easy_gestation_start_time_l)/HOLE_DAY_RTC + 1;if(cur_rtc == female_health->ovulation_time_l)lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_IN_OVULATION].txt);elselv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_GESTATION].txt,display_day);}//当月else if(cur_rtc < female_health->menstrual_start_time){display_day = (female_health->menstrual_start_time - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_MENSTRUAL].txt,display_day);}else if(cur_rtc >= female_health->menstrual_start_time && cur_rtc <= female_health->menstrual_end_time){display_day = (cur_rtc - female_health->menstrual_start_time)/HOLE_DAY_RTC + 1;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_MENSTRUAL].txt,display_day);}else if(cur_rtc < female_health->easy_gestation_start_time){display_day = (female_health->easy_gestation_start_time - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_GESTATION].txt,display_day);}else if(cur_rtc >= female_health->easy_gestation_start_time && cur_rtc <= female_health->easy_gestation_end_time){display_day = (cur_rtc - female_health->easy_gestation_start_time)/HOLE_DAY_RTC + 1;if(cur_rtc == female_health->ovulation_time)lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_IN_OVULATION].txt);elselv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_GESTATION].txt,display_day);}//下月else if(cur_rtc < female_health->menstrual_start_time_n){display_day = (female_health->menstrual_start_time_n - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_MENSTRUAL].txt,display_day);}else if(cur_rtc >= female_health->menstrual_start_time_n && cur_rtc <= female_health->menstrual_end_time_n){display_day = (cur_rtc - female_health->menstrual_start_time_n)/HOLE_DAY_RTC + 1;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_MENSTRUAL].txt,display_day);}else if(cur_rtc < female_health->easy_gestation_start_time_n){display_day = (female_health->easy_gestation_start_time_n - cur_rtc)/HOLE_DAY_RTC;lv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_FORECAST_GESTATION].txt,display_day);}else if(cur_rtc >= female_health->easy_gestation_start_time_n && cur_rtc <= female_health->easy_gestation_end_time_n){display_day = (cur_rtc - female_health->easy_gestation_start_time_n)/HOLE_DAY_RTC + 1;if(cur_rtc == female_health->ovulation_time_n)lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_IN_OVULATION].txt);elselv_label_set_text_fmt(data->female_tip, data->res_string[E_FEMALE_IN_GESTATION].txt,display_day);}elselv_label_set_text(data->female_tip, data->res_string[E_FEMALE_NO_RECORD].txt);}}/*
* 1.在female_mark[i].mark_begin - female_mark[i].mark_finish 显示取消标记
* 2.在female_mark[i].mark_finish 5天内显示标记结束
* 3.在female_mark[i].mark_finish 5天外显示标记开始
* 4.如果读不满足就显示标记开始
*/
static void update_female_mark_txt(female_health_view_t* data)
{female_health_t* female_health = get_female_health_info();bool is_mark = false;// 在当天及以前显示标记按钮,未来就隐藏 
#ifdef CONFIG_SIMULATORuint32_t day_rtc = get_current_rtc();
#elseuint32_t day_rtc = get_day_begin_rtc();
#endifprintf("(lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET)+START_FEMALE_OFFSET_RTC) %d\r\n",(lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET)+START_FEMALE_OFFSET_RTC);uint32_t cur_rtc = data->start_rtc + ((lv_obj_get_scroll_x(data->scroll_page)/FEMALE_BAR_OFFSET)+START_FEMALE_OFFSET_RTC)*HOLE_DAY_RTC;if(cur_rtc <= day_rtc){lv_obj_clear_flag(data->mark_btn,LV_OBJ_FLAG_HIDDEN);}else{lv_obj_add_flag(data->mark_btn,LV_OBJ_FLAG_HIDDEN);}for(uint8_t i=0 ; i<female_health->mark_cnt; i++){if(cur_rtc >= female_health->female_mark[i].mark_begin && cur_rtc <= female_health->female_mark[i].mark_finish){data->mark_type = E_MARK_CANCEL;is_mark = true;lv_label_set_text(data->mark_txt, data->res_string[E_FEMALE_MAKE_CANCEL].txt);}else if(cur_rtc >= female_health->female_mark[i].mark_begin && cur_rtc <= female_health->female_mark[i].mark_finish + 5 * HOLE_DAY_RTC){data->mark_type = E_MARK_OVER;is_mark = true;lv_label_set_text(data->mark_txt, data->res_string[E_FEMALE_MAKE_FINISG].txt);}}printf("is_mark %d\r\n", is_mark);if(!is_mark){data->mark_type = E_MARK_BEGIN;lv_label_set_text(data->mark_txt, data->res_string[E_FEMALE_MAKE_BEGIN].txt);}}static void create_female_bar(female_health_view_t* data,lv_obj_t* par)
{
#ifdef CONFIG_SIMULATORuint32_t start_rtc = get_current_rtc() - START_FEMALE_RTC * HOLE_DAY_RTC;
#elseuint32_t start_rtc = get_day_begin_rtc() - START_FEMALE_RTC * HOLE_DAY_RTC;
#endifdata->start_rtc = start_rtc;struct rtc_time temp_time = {0};rtc_to_time(start_rtc,&temp_time);printf("start_rtc:%04d%02d%02d\r\n",temp_time.tm_year,temp_time.tm_mon,temp_time.tm_mday);// uint32_t end_rtc = cur_rtc - 29 * HOLE_DAY_RTC;for (uint8_t i = 0; i < FEMALE_BAR_DISPLAY*FEMALE_BAR_MAX; i++){rtc_to_time(start_rtc,&temp_time);data->bar[i] = lv_obj_create(par);lv_obj_set_size(data->bar[i], FEMALE_BAR_W, FEMALE_BAR_H);lv_obj_set_style_bg_color(data->bar[i], lv_color_make(25, 25, 25), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->bar[i], LV_OPA_100, LV_PART_MAIN);lv_obj_set_style_radius(data->bar[i], 6, LV_PART_MAIN);if(i == 0)lv_obj_align(data->bar[i], LV_ALIGN_TOP_LEFT, 0, 10);elselv_obj_align_to(data->bar[i], data->bar[i-1], LV_ALIGN_OUT_RIGHT_MID, FEMALE_BAR_X, 0);start_rtc+=HOLE_DAY_RTC;}data->bar_dot = lv_obj_create(par);lv_obj_set_size(data->bar_dot, 15, 15);lv_obj_set_style_bg_color(data->bar_dot, lv_color_make(255, 255, 255), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->bar_dot,LV_OPA_100,LV_PART_MAIN);lv_obj_set_style_radius(data->bar_dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);lv_obj_align_to(data->bar_dot, data->bar[3], LV_ALIGN_BOTTOM_MID, 0, -8);data->female_date = lv_label_create(data->bg);lv_obj_add_style(data->female_date, &data->style, LV_PART_MAIN);lv_label_set_text_fmt(data->female_date, "%d/%d",1,1);lv_obj_align(data->female_date,LV_ALIGN_TOP_MID,0,240);data->right_btn = lv_img_create(data->bg);lv_img_set_src(data->right_btn, &data->img_dsc[0]);lv_obj_align_to(data->right_btn, data->female_date, LV_ALIGN_OUT_RIGHT_MID, 120, 0);lv_obj_add_flag(data->right_btn, LV_OBJ_FLAG_CLICKABLE);lv_obj_set_ext_click_area(data->right_btn, 20);lv_obj_add_event_cb(data->right_btn, click_event_cb, LV_EVENT_ALL, data);data->left_btn = lv_img_create(data->bg);lv_img_set_src(data->left_btn, &data->img_dsc[1]);lv_obj_align_to(data->left_btn, data->female_date, LV_ALIGN_OUT_LEFT_MID, -120, 0);lv_obj_add_flag(data->left_btn, LV_OBJ_FLAG_CLICKABLE);lv_obj_set_ext_click_area(data->left_btn, 20);lv_obj_add_event_cb(data->left_btn, click_event_cb, LV_EVENT_ALL, data);data->mark_btn = lv_obj_create(data->bg);lv_obj_set_size(data->mark_btn, 168, 58);lv_obj_set_style_bg_color(data->mark_btn, lv_color_make(25, 25, 25), LV_PART_MAIN);lv_obj_set_style_bg_opa(data->mark_btn, LV_OPA_COVER, LV_PART_MAIN);lv_obj_set_style_radius(data->mark_btn, LV_RADIUS_CIRCLE, LV_PART_MAIN);lv_obj_align(data->mark_btn, LV_ALIGN_BOTTOM_MID, 0, -30);lv_obj_add_flag(data->mark_btn, LV_OBJ_FLAG_CLICKABLE);lv_obj_add_event_cb(data->mark_btn, click_event_cb, LV_EVENT_ALL, data);data->mark_txt = lv_label_create(data->mark_btn);lv_obj_add_style(data->mark_txt, &data->style, LV_PART_MAIN);lv_obj_set_width(data->mark_txt, 130);lv_label_set_long_mode(data->mark_txt, LV_LABEL_LONG_SCROLL_CIRCULAR);lv_obj_set_style_text_color(data->mark_txt, lv_color_hex(0xf55057), LV_PART_MAIN);lv_obj_set_style_text_font(data->mark_txt, DEF_REGULAR_FONT32, LV_PART_MAIN);lv_label_set_text(data->mark_txt, data->res_string[E_FEMALE_MAKE_BEGIN].txt);lv_obj_center(data->mark_txt);data->female_tip = lv_label_create(data->bg);lv_obj_add_style(data->female_tip, &data->style, LV_PART_MAIN);lv_obj_set_width(data->female_tip, 300);lv_label_set_long_mode(data->female_tip, LV_LABEL_LONG_SCROLL_CIRCULAR);lv_obj_set_style_text_color(data->female_tip, lv_color_hex(0xffffff), LV_PART_MAIN);lv_label_set_text(data->female_tip, data->res_string[E_FEMALE_NO_RECORD].txt);lv_obj_align(data->female_tip, LV_ALIGN_BOTTOM_MID, 0, -130);lv_obj_scroll_to_x(data->scroll_page, lv_obj_get_scroll_x(data->scroll_page)+FEMALE_BAR_OFFSET*(START_FEMALE_RTC - START_FEMALE_OFFSET_RTC), LV_ANIM_OFF);update_female_bar(data);
}static int _female_health_view_delete(view_data_t *view_data)
{female_health_view_t *data = view_data->user_data;if (data) {obj_del(data);_female_health_unload_resource(data);app_mem_free(data);view_data->user_data = NULL;SYS_LOG_INF("ok\n");} else {lvgl_res_preload_cancel_scene(SCENE_FEMALE_HEALTH_VIEW);}lvgl_res_unload_scene_compact(SCENE_FEMALE_HEALTH_VIEW);lvgl_res_cache_clear(0);return 0;
}static int _female_health_view_paint(view_data_t *view_data)
{female_health_view_t *data = view_data->user_data;if(!data)return -1;// female_health_t* female_health = get_female_health_info();// if(1 == female_health->have_data)// {// 	// printf("female_health_view_paint\r\n");// }return 0;
}static int _female_health_proc_key(view_data_t *view_data, ui_key_msg_data_t * key_data)
{female_health_view_t* data = view_data->user_data;if(!data)return -1;female_health_t* female_health = get_female_health_info();if(0 == female_health->have_data)return 0;if (KEY_VALUE(key_data->event) == KEY_GESTURE_RIGHT) {key_data->done = true;if (data->is_sliding == false)view_stack_pop();}return 0;
}int _female_health_view_handler(uint16_t view_id, uint8_t msg_id, void *msg_data)
{view_data_t *view_data = view_get_data(view_id);switch (msg_id) {case MSG_VIEW_PRELOAD:return _female_health_view_preload(view_data);case MSG_VIEW_LAYOUT:return _female_health_view_layout(view_data);case MSG_VIEW_DELETE:return _female_health_view_delete(view_data);case MSG_VIEW_PAINT:return _female_health_view_paint(view_data);case MSG_VIEW_KEY:return _female_health_proc_key(view_data, msg_data);default:return 0;}return 0;
}VIEW_DEFINE(female_health_view, _female_health_view_handler, NULL, NULL, FEMALE_HEALTH_VIEW, NORMAL_ORDER, UI_VIEW_LVGL,DEF_UI_VIEW_WIDTH, DEF_UI_VIEW_HEIGHT);

女性健康计算逻辑

#include <stdlib.h>
#include <os_common_api.h>
#include "app_ui.h"
#ifndef CONFIG_SIMULATOR
#include "user_nvds_define.h"
#include <user_log.h>
#include "user_file_tim.h"
#else
#include <windows.h>
#endif
#include "kospet_nvds.h"
#include "model_female.h"
#include <view_cache.h>
#include "msgbox_handler.h"
#include "view_stack.h"
/*
生理周期:这是一个生理上的循环周期,范围为17-60 天,默认28天。
经期:从月经开始的第一天持续至最后一天,范围为2-15天,默认5天。
排卵日:发生在生理周期的中间阶段,一般为经期开始之后的14天。
易孕期:通常指排卵日前5天至后4天。
安全期:指除了经期、排卵日、易孕期之外的日期。
生理周期中的四种状态:是指经期、排卵日、易孕期和安全期。计算公式:
经期开始时间:A 
经期长度:B(2-15) 
月经周期:C(17-60)经期:
设定的经期的始终为:A ~ A+B-1
下一次经期的始终为:A+C ~ A+C+B-1排卵日:X
当C为60时无排卵日,只显示经期,剩余全为安全期。(异常情况)
当C=19~59时 X=A+C-14
当C=18时, X=A+C-13
当C=17时, X=A+C-12易孕期:Y
当C为60时无排卵日,只显示经期,剩余全为安全期。(异常情况)
否则 Y=X-5~X-1 || X+1~X+4tips:如果同一天,既是经期,又是易孕期或排卵日,则优先认为是经期。
*/#define UTC_TO_DAYS(UTC)  ((uint32_t)(UTC / (60 * 60 * 24)))
#define DAYS_TO_UTC(DAYS) (DAYS * (60 * 60 * 24))#define FH_DEBUG_TEST
#define FH_DEBUG_PRINT
#ifdef FH_DEBUG_PRINT
#define fh_print_log(format, ...) printk(format, ##__VA_ARGS__)
#else
#define fh_print_log(format, ...) ((void)0)
#endifstatic female_health_t g_female_health = {0};static void kospet_female_health_update(female_health_t *p_fh);
static void female_param_default(female_info_t* female);void set_female_health_info(female_health_t* data)
{g_female_health = *data;
}
female_health_t* get_female_health_info(void)
{kospet_female_health_update(&g_female_health);// printf("get_female_health_info %d\r\n",g_female_health.have_data);return &g_female_health;
}void kospet_set_female_info(female_info_t *female_info)
{kospet_nvds_write(NVDS_FEMALE_INFO, female_info);
}void kospet_get_female_info(female_info_t *female_info)
{kospet_nvds_read(NVDS_FEMALE_INFO, female_info);
}static uint32_t get_ovulation_day(uint32_t day,uint8_t cycle)
{uint32_t ovulation_day = 0;if(cycle >= 19 && cycle <= 59)ovulation_day = day + DAYS_TO_UTC(cycle) - DAYS_TO_UTC(14);else if(cycle == 17)ovulation_day = day + DAYS_TO_UTC(cycle) - DAYS_TO_UTC(12);else if(cycle == 18)ovulation_day = day + DAYS_TO_UTC(cycle) - DAYS_TO_UTC(13);elseovulation_day = 0;fh_print_log("FH:get_ovulation_day %d [%d %d]\r\n",ovulation_day,day,cycle);return ovulation_day;
}   static void kospet_female_health_update(female_health_t *p_fh)
{int cur_rmds = 0;uint32_t cur_rtc = 0;uint32_t cur_days = 0;uint32_t start_rtc = 0;uint32_t last_mp_start = 0;  // 上一次月经开始的时间female_health_t fhui_info = {0};female_info_t female_info = {0};kospet_get_female_info(&female_info);
#ifndef CONFIG_SIMULATORuint32_t day_begin_rtc = get_day_begin_rtc();bool is_update = false;for (int8_t i = FEMALE_MARK_MAX-1; i >= 0; i--){if(day_begin_rtc < female_info.mark[i].mark_begin){is_update = true;memset(&female_info.mark[i],0,sizeof(female_mark_t));// if(i != 0)//     female_info.mark_menstrualStartRtc = female_info.mark[i-1].mark_begin;// else//     female_info.mark_menstrualStartRtc = 0;}}if(is_update){kospet_set_female_info(&female_info);kospet_get_female_info(&female_info);}
#endifif(female_info.menstrualCycle < 17  ||female_info.menstrualCycle > 60  ||female_info.menstrualPeriod < 2  ||female_info.menstrualPeriod > 15 ||female_info.menstrualStartRtc == 0 ||female_info.have_data == 0)//数据异常恢复默认值展示{female_param_default(&female_info);// return;}fhui_info.have_data = 1;//female_info.have_data;fhui_info.mark_cnt = female_info.mark_cnt;memcpy(fhui_info.female_mark,female_info.mark,sizeof(female_mark_t)*5);cur_rtc = get_current_rtc();start_rtc = female_info.mark_cnt == 0 ? female_info.menstrualStartRtc : female_info.mark[female_info.mark_cnt-1].mark_begin;cur_days  = UTC_TO_DAYS(cur_rtc) - UTC_TO_DAYS(start_rtc);//当天距离第一次月经开始过了几天fh_print_log("FH:cur_days %d\n",cur_days);cur_rmds  = cur_days % female_info.menstrualCycle;//周期内还剩余几天fh_print_log("FH:cur_rmds %d\n",cur_rmds);last_mp_start = (cur_days / female_info.menstrualCycle == 0) ? 0 : cur_days - cur_rmds;  // Afh_print_log("FH:last_mp_start %d\n",last_mp_start);fhui_info.menstrual_duration = female_info.menstrualPeriod; //Bfh_print_log("FH:menstrual_duration %d\n",fhui_info.menstrual_duration);fhui_info.menstrual_cycle = female_info.menstrualCycle;     //Cfh_print_log("FH:menstrual_cycle %d\n",fhui_info.menstrual_cycle);//当前月经推测 + menstrualCycle 为下月uint32_t menstrual_start = last_mp_start;fh_print_log("FH:menstrual_start %d\n",menstrual_start);uint32_t menstrual_end = (last_mp_start + female_info.menstrualPeriod) - 1;fh_print_log("FH:menstrual_end %d\n",menstrual_end);//下月经推测 + menstrualCycle 为下月// uint32_t menstrual_start_next = last_mp_start + female_info.menstrualCycle;// fh_print_log("FH:menstrual_start_next %d\n",menstrual_start_next);// uint32_t menstrual_end_next = (last_mp_start + female_info.menstrualCycle + female_info.menstrualPeriod) - 1;// fh_print_log("FH:menstrual_end_next %d\n",menstrual_end_next);fhui_info.menstrual_start_time = DAYS_TO_UTC(menstrual_start) + start_rtc;fh_print_log("FH:menstrual_start_time %d\n",fhui_info.menstrual_start_time);fhui_info.menstrual_end_time   = DAYS_TO_UTC(menstrual_end) + start_rtc;fh_print_log("FH:menstrual_end_time %d\n",fhui_info.menstrual_end_time);fhui_info.ovulation_time = get_ovulation_day(fhui_info.menstrual_start_time,fhui_info.menstrual_cycle);fh_print_log("FH:ovulation_time %d\n",fhui_info.ovulation_time);fhui_info.easy_gestation_start_time = fhui_info.ovulation_time - DAYS_TO_UTC(5);fh_print_log("FH:easy_gestation_start_time %d\n",fhui_info.easy_gestation_start_time);fhui_info.easy_gestation_end_time = fhui_info.ovulation_time + DAYS_TO_UTC(4);fh_print_log("FH:easy_gestation_end_time %d\n",fhui_info.easy_gestation_end_time);//下个月fhui_info.menstrual_start_time_n = fhui_info.menstrual_start_time + (female_info.menstrualCycle*86400);fhui_info.menstrual_end_time_n = fhui_info.menstrual_end_time + (female_info.menstrualCycle*86400);if(fhui_info.ovulation_time != 0)fhui_info.ovulation_time_n = fhui_info.ovulation_time + (female_info.menstrualCycle*86400);elsefhui_info.ovulation_time_n = 0;fhui_info.easy_gestation_start_time_n = fhui_info.easy_gestation_start_time + (female_info.menstrualCycle*86400);fhui_info.easy_gestation_end_time_n = fhui_info.easy_gestation_end_time + (female_info.menstrualCycle*86400);//上个月 推测if(cur_rtc >= start_rtc+(female_info.menstrualCycle*86400) || female_info.mark_cnt == 0){fhui_info.menstrual_start_time_l = fhui_info.menstrual_start_time -(female_info.menstrualCycle*86400);fhui_info.menstrual_end_time_l = fhui_info.menstrual_end_time - (female_info.menstrualCycle*86400);if(fhui_info.ovulation_time != 0)fhui_info.ovulation_time_l = fhui_info.ovulation_time - (female_info.menstrualCycle*86400);elsefhui_info.ovulation_time_l = 0;fhui_info.easy_gestation_start_time_l = fhui_info.easy_gestation_start_time - (female_info.menstrualCycle*86400);fhui_info.easy_gestation_end_time_l = fhui_info.easy_gestation_end_time - (female_info.menstrualCycle*86400);}#if 0//def FH_DEBUG_TESTstruct rtc_time cur_time      = {0};rtc_to_time(fhui_info.menstrual_start_time,&cur_time);fh_print_log("FH:menstrual_start %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time(fhui_info.menstrual_end_time,&cur_time);fh_print_log("FH:menstrual_end %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time(fhui_info.ovulation_time,&cur_time);fh_print_log("FH:ovulation_time %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time(fhui_info.easy_gestation_start_time,&cur_time);fh_print_log("FH:easy_gestation_start_time %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time(fhui_info.easy_gestation_end_time,&cur_time);fh_print_log("FH:easy_gestation_end_time %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time((DAYS_TO_UTC(menstrual_start_next) + start_rtc),&cur_time);fh_print_log("FH:menstrual_start_next %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);memset(&cur_time,0,sizeof(struct rtc_time));rtc_to_time((DAYS_TO_UTC(menstrual_end_next) + start_rtc),&cur_time);fh_print_log("FH:menstrual_end_next %d %d %d\r\n",cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday);#endif*p_fh = fhui_info;
}void kospet_female_health_remind(void)
{female_info_t female_info = {0};kospet_get_female_info(&female_info);if (female_info.menstrualCycle < 17  ||female_info.menstrualCycle >60   || female_info.menstrualPeriod < 2  ||female_info.menstrualPeriod > 15 ||female_info.menstrualStartRtc == 0 ||female_info.have_data == 0) {return;}struct rtc_time cur_time = {0};get_rtc_time(&cur_time);fh_print_log("female health remind[%02d:%02d = %02d:%02d]\r\n",cur_time.tm_hour,cur_time.tm_min,female_info.RemindDayofHour,female_info.RemindDayofMin);if(female_info.RemindDayofHour != cur_time.tm_hour || female_info.RemindDayofMin != cur_time.tm_min){return;}//计算当前天处在周期第几天uint32_t cur_days = (UTC_TO_DAYS(get_current_rtc()) - UTC_TO_DAYS(female_info.menstrualStartRtc))% female_info.menstrualCycle;//计算排卵日处在周期第几天uint32_t ovulation = UTC_TO_DAYS(get_ovulation_day(0,female_info.menstrualCycle));fh_print_log("[FH update]:RemindDay = [%d, %d], menstrualCycle = %d, today = %d, ovulation = %d\r\n",female_info.ovulationRemindDay,female_info.menstrualRemindDay,female_info.menstrualCycle,cur_days,ovulation);if(female_info.menstrualRemindDay){if(female_info.menstrualCycle - female_info.menstrualRemindDay == cur_days){printf("FH send menstrualRemindDay period reminder\r\n");send_handle_msgbox_msg(MSGBOX_ID_FEMALE, FEMALE_MENSTRUAL);}}if(ovulation != 0){if(female_info.pregnancyRemindDay){if(ovulation - 5 - female_info.pregnancyRemindDay == cur_days){send_handle_msgbox_msg(MSGBOX_ID_FEMALE, FEMALE_EASY_GESTATION);printf("FH send pregnancyRemindDay period reminder\r\n");}}if(female_info.ovulationRemindDay){if(ovulation - female_info.ovulationRemindDay == cur_days){send_handle_msgbox_msg(MSGBOX_ID_FEMALE, FEMALE_OVULATION);printf("FH send ovulationRemindDay period reminder\r\n");}}}}#ifdef FH_DEBUG_TEST
void kospet_female_health_test(void)
{female_info_t female_info = {0};kospet_get_female_info(&female_info);female_info.menstrualCycle = 28;female_info.menstrualPeriod = 5;female_info.menstrualRemindDay = 3;female_info.ovulationRemindDay = 3;female_info.pregnancyRemindDay = 3;female_info.RemindDayofHour = 9;female_info.RemindDayofMin = 40;female_info.menstrualStartRtc = get_current_rtc();kospet_set_female_info(&female_info);
}
#endifstatic void female_param_default(female_info_t* female)
{// return;struct rtc_time tm;get_rtc_time(&tm);// tm.tm_year = 2025;// tm.tm_mon = 4;// tm.tm_mday = 22;tm.tm_hour = 0;tm.tm_min = 0;tm.tm_sec = 0;
#ifdef CONFIG_SIMULATORuint32_t default_rtc = get_current_rtc();
#elseuint32_t default_rtc = time_to_rtc(&tm);
#endiffemale->menstrualCycle = 28;female->menstrualPeriod = 5;female->menstrualRemindDay = 3;female->ovulationRemindDay = 3;female->pregnancyRemindDay = 3;female->RemindDayofHour = 9;female->RemindDayofMin = 40;female->menstrualStartRtc = default_rtc;female->have_data = 1;kospet_set_female_info(female);
}KOSPET_NVDS_DEFINE(NVDS_FEMALE_INFO, sizeof(female_info_t), NULL, NULL);

相关文章:

  • SpringCloud微服务架构
  • 基于先进MCU的机器人运动控制系统设计:理论、实践与前沿技术
  • VS BUG(6) LINK : fatal error LNK1158: 无法运行“rc.exe”
  • 用 C 语言实现通用的冒泡排序算法
  • UNO Less-to-More Generalization: 通过上下文生成解锁更多可控性
  • 使用UltraSigma给普源RIGOL示波器截图的方法
  • 基于 Python 的自然语言处理系列(86):DPO(Direct Preference Optimization)原理与实战
  • 【信息系统项目管理师】高分论文:论质量管理和进度管理(智慧旅游平台建设项目)
  • HBase协处理器深度解析:原理、实现与最佳实践
  • 基于FFmpeg命令行的实时图像处理与RTSP推流解决方案
  • 使用java代码注册onloyoffice账号 || 注册onloyoffice账号
  • vue中 vue.config.js反向代理
  • 计算机网络 | 应用层(3)-- 因特网中的电子邮件
  • 使用银行卡二要素API让支付更加安心
  • 北斗导航 | Transformer增强BiLSTM网络的GNSS伪距观测量误差探测
  • B. And It‘s Non-Zero
  • 提示词的神奇魔力——如何通过它改变AI的输出
  • 免费送源码:Java+ssm+HTML 三分糖——甜品店网站设计与实现 计算机毕业设计原创定制
  • springboot + mybatis 需要写 .xml吗
  • Java—— 五道算法水题
  • 商务部:入境消费增长潜力巨大,离境退税有助降低境外旅客购物成本
  • 酒店保洁员调包住客港币,海南官方通报:成立调查组赴属地调查
  • 上海虹桥至福建三明直飞航线开通,飞行时间1小时40分
  • 欢迎回家!日本和歌山县4只大熊猫将于6月底送返中国
  • “80后”李岩已任安徽安庆市领导
  • 打破“内卷”与“焦虑”怪圈,在阅读中寻找松弛感