From 9bf5c774cb32493ec43962654a41e4e9b8ca677f Mon Sep 17 00:00:00 2001 From: Th3maz1ng Date: Thu, 1 Dec 2022 20:34:18 +0100 Subject: [PATCH] Reworked the watch_face screen and the menu screen so that they can be created and destroyed when needed --- .../lv_port_win_codeblocks/config_screen.c | 4 +- .../lv_port_win_codeblocks/lv_conf.h | 6 +- .../lv_port_win_codeblocks/main.c | 26 +- .../lv_port_win_codeblocks/menu_screen.c | 158 +++++---- .../lv_port_win_codeblocks/menu_screen.h | 16 +- .../lv_port_win_codeblocks/watch_face.c | 330 +++++++----------- .../lv_port_win_codeblocks/watch_face.h | 37 +- 7 files changed, 299 insertions(+), 278 deletions(-) diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/config_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/config_screen.c index cd33fa4..930b112 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/config_screen.c +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/config_screen.c @@ -13,9 +13,9 @@ static void event_cb(lv_event_t * e) break; case LV_DIR_RIGHT: LV_LOG_USER("GESTURE : RIGHT"); - extern lv_obj_t *men_screen; + /*extern lv_obj_t *men_screen; //menu_screen(); - lv_scr_load_anim(men_screen, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 400, 0, false); + lv_scr_load_anim(men_screen, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 400, 0, false);*/ break; case LV_DIR_TOP: LV_LOG_USER("GESTURE : TOP"); diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/lv_conf.h b/src/lvgl_win_sim/lv_port_win_codeblocks/lv_conf.h index 36f205d..859ea14 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/lv_conf.h +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/lv_conf.h @@ -36,7 +36,7 @@ #define LV_USE_BUILTIN_MALLOC 1 #if LV_USE_BUILTIN_MALLOC /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (128U * 1024U) /*[bytes]*/ + #define LV_MEM_SIZE (70U * 1024U) /*[bytes]*/ /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ #define LV_MEM_ADR 0 /*0: unused*/ @@ -256,7 +256,7 @@ /*1: Show the used memory and the memory fragmentation * Requires `LV_USE_BUILTIN_MALLOC = 1`*/ -#define LV_USE_MEM_MONITOR 0 +#define LV_USE_MEM_MONITOR 1 #if LV_USE_MEM_MONITOR #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT #endif @@ -706,7 +706,7 @@ ====================*/ /*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#define LV_USE_DEMO_WIDGETS 1 +#define LV_USE_DEMO_WIDGETS 0 #if LV_USE_DEMO_WIDGETS #define LV_DEMO_WIDGETS_SLIDESHOW 0 #endif diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/main.c b/src/lvgl_win_sim/lv_port_win_codeblocks/main.c index 179f13e..c38b95b 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/main.c +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/main.c @@ -14,6 +14,7 @@ #include "lv_drivers/win32drv/win32drv.h" #include +#include #include "watch_face.h" #include "config_screen.h" #include "menu_screen.h" @@ -44,6 +45,20 @@ static int tick_thread(void *data); /********************** * GLOBAL FUNCTIONS **********************/ + +static void date_time_cb(struct tm * const dateTime) +{ + if(!dateTime)return; + + time_t time_type = time(NULL); + struct tm *tm = localtime(&time_type); + LV_LOG_USER("Time is : %llu, Time : %d:%d:%d", time_type, tm->tm_hour, tm->tm_min, tm->tm_sec); + *dateTime = *tm; +} + +WatchFace_t watchFace; +MenuScreen_t menuScreen; + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow) { /*Initialize LittlevGL*/ @@ -63,13 +78,16 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLi lv_obj_t *screen_mask = lv_img_create(top_layer); lv_img_set_src(screen_mask, &watch_mask); - WatchFace_t watchFace; watch_face_init(&watchFace); - lv_obj_t *watchFaceObj = watch_face_create(&watchFace); - lv_scr_load(watchFaceObj); + menu_screen_init(&menuScreen); + + watch_face_register_cb(&watchFace, &(date_time_cb)); + watch_face_create(&watchFace); + + lv_scr_load(watchFace.display); + //config_screen(); - //menu_screen(); //watch_face(); while(!lv_win32_quit_signal) { diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c index 1c66ab4..0ebf14d 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c @@ -1,22 +1,20 @@ +#include "lvgl.h" #include "menu_screen.h" #include "config_screen.h" #include "watch_face.h" -#include "lvgl.h" #define array_size(array) (sizeof(array)/sizeof(array[0])) -lv_obj_t *men_screen = NULL; - -void watch_btn_cb(lv_event_t *e) +void watch_item_cb(lv_event_t *e) { LV_LOG_USER("Watch btn pressed"); - extern lv_obj_t *watch_screen; - //watch_face(); - lv_scr_load_anim(watch_screen, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, false); + extern WatchFace_t watchFace; + watch_face_create(&watchFace); + lv_scr_load_anim(watchFace.display, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, true); } -void settings_btn_cb(lv_event_t *e) +void settings_item_cb(lv_event_t *e) { LV_LOG_USER("Settings btn pressed"); @@ -25,15 +23,66 @@ void settings_btn_cb(lv_event_t *e) lv_scr_load_anim(conf_screen, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, false); } -typedef struct +static void cleanup_event_cb(lv_event_t * e) { - const lv_img_dsc_t *img; - const char *text; - lv_event_cb_t event_cb; -} IconItem; + MenuScreen_t *menuScreen = e->user_data; + menu_screen_destroy(menuScreen); + LV_LOG_USER("cleanup"); +} -void menu_screen(void) +void menu_screen_init(MenuScreen_t * const menuScreen) { + if(!menuScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + memset(menuScreen, 0, sizeof(MenuScreen_t)); +} + +static void screen_create_header(MenuScreen_t * const menuScreen, const char *title) +{ + lv_obj_t *header = lv_obj_create(menuScreen->display); + lv_obj_set_style_bg_color(header, lv_color_make(129, 141,181), LV_PART_MAIN); + lv_obj_set_size(header, 240, 65); + lv_obj_set_style_radius(header, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(header, 0, LV_PART_MAIN); + + lv_obj_t *header_title = lv_label_create(header); + lv_label_set_text_static(header_title, title); + lv_obj_set_style_text_color(header_title, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_font(header_title, &lv_font_montserrat_30, LV_PART_MAIN); + lv_obj_set_align(header_title, LV_ALIGN_CENTER); +} + +static void menu_screen_add_item(lv_obj_t *scroll_item_container, uint8_t position, const lv_img_dsc_t *itemImg,const char *itemTitle, lv_event_cb_t itemClickEventCb) +{ + //We add the image button with the icon of the item + lv_obj_t *item_btn = lv_imgbtn_create(scroll_item_container); + lv_obj_set_size(item_btn, itemImg->header.w, itemImg->header.h); + lv_obj_set_pos(item_btn, 42, 52 * position); + lv_imgbtn_set_src(item_btn, LV_IMGBTN_STATE_RELEASED, NULL, itemImg, NULL); + lv_obj_add_event_cb(item_btn, itemClickEventCb, LV_EVENT_CLICKED, NULL); + + //We add the click-able label with the title of the item + lv_obj_t *item_label = lv_label_create(scroll_item_container); + lv_label_set_text_static(item_label, itemTitle); + lv_obj_set_style_text_font(item_label, &lv_font_montserrat_16, LV_PART_MAIN); + lv_obj_set_pos(item_label, 84+12, 15 + 52 * position); + lv_obj_set_style_text_color(item_label, lv_color_make(145, 145, 145), LV_PART_MAIN); + lv_obj_set_ext_click_area(item_label, 10); + lv_obj_add_flag(item_label, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(item_label, itemClickEventCb, LV_EVENT_CLICKED , NULL); +} + +void menu_screen_create(MenuScreen_t * const menuScreen) +{ + if(!menuScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + //We declare all the needed assets by the menu screen: LV_IMG_DECLARE(watch_menu_clock_icon) LV_IMG_DECLARE(watch_menu_dialer_icon) LV_IMG_DECLARE(watch_menu_mail_icon) @@ -42,60 +91,47 @@ void menu_screen(void) LV_IMG_DECLARE(watch_menu_settings_icon) LV_IMG_DECLARE(watch_menu_messages_icon) - IconItem iconItems[] = + //We create our parent screen : + if(menuScreen->display) { - {&watch_menu_clock_icon, "Clock", &(watch_btn_cb)}, - {&watch_menu_alarm_icon, "Alarm", NULL}, - {&watch_menu_messages_icon, "Text messages", NULL}, - {&watch_menu_mail_icon, "Mails", NULL}, - {&watch_menu_dialer_icon, "Phone", NULL}, - {&watch_menu_contacts_icon, "Contacts", NULL}, - {&watch_menu_settings_icon, "Settings", &(settings_btn_cb)}, - }; + LV_LOG_ERROR("display should be NULL here !"); + lv_obj_del(menuScreen->display); + menuScreen->display = NULL; + } + menuScreen->display = lv_obj_create(NULL); - men_screen = lv_obj_create(NULL); - lv_obj_set_style_bg_color(men_screen, lv_color_make(0,0,0), LV_PART_MAIN); + screen_create_header(menuScreen, "Menu"); - lv_obj_t *menu_bar = lv_obj_create(men_screen); - lv_obj_set_style_bg_color(menu_bar, lv_color_make(129, 141,181), LV_PART_MAIN); - lv_obj_set_size(menu_bar, 240, 65); - lv_obj_set_style_radius(menu_bar, 0, LV_PART_MAIN); - lv_obj_set_style_border_width(menu_bar, 0, LV_PART_MAIN); + lv_obj_t *scroll_item_container = lv_obj_create(menuScreen->display); + lv_obj_set_style_bg_color(scroll_item_container, lv_color_make(0xFF,0xFF,0xFF), LV_PART_MAIN); + lv_obj_set_size(scroll_item_container, lv_pct(100), 240-65); + lv_obj_set_pos(scroll_item_container, 0, 65); + lv_obj_set_style_pad_all(scroll_item_container, 0, LV_PART_MAIN); + lv_obj_set_style_pad_top(scroll_item_container, 10, LV_PART_MAIN); + lv_obj_set_style_pad_bottom(scroll_item_container, 20, LV_PART_MAIN); + lv_obj_set_style_radius(scroll_item_container, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(scroll_item_container, 0, LV_PART_MAIN); + lv_obj_set_style_pad_right(scroll_item_container, 15, LV_PART_SCROLLBAR); - lv_obj_t *menu_label = lv_label_create(menu_bar); - lv_label_set_text_static(menu_label, "Menu"); - lv_obj_set_style_text_color(menu_label, lv_color_white(), LV_PART_MAIN); - lv_obj_set_style_text_font(menu_label, &lv_font_montserrat_30, LV_PART_MAIN); - lv_obj_set_align(menu_label, LV_ALIGN_CENTER); + menu_screen_add_item(scroll_item_container, 0, &watch_menu_clock_icon, "Watch", &(watch_item_cb)); + menu_screen_add_item(scroll_item_container, 1, &watch_menu_alarm_icon, "Alarm", NULL); + menu_screen_add_item(scroll_item_container, 2, &watch_menu_messages_icon, "Text messages", NULL); + menu_screen_add_item(scroll_item_container, 3, &watch_menu_mail_icon, "Mails", NULL); + menu_screen_add_item(scroll_item_container, 4, &watch_menu_dialer_icon, "Phone", NULL); + menu_screen_add_item(scroll_item_container, 5,&watch_menu_contacts_icon, "Contacts", NULL); + menu_screen_add_item(scroll_item_container, 6,&watch_menu_settings_icon, "Contacts", &(settings_item_cb)); - lv_obj_t *scroll_area = lv_obj_create(men_screen); - lv_obj_set_style_bg_color(scroll_area, lv_color_make(0xFF,0xFF,0xFF), LV_PART_MAIN); - lv_obj_set_size(scroll_area, lv_pct(100), 240-65); - lv_obj_set_pos(scroll_area, 0, 65); - lv_obj_set_style_pad_all(scroll_area, 0, LV_PART_MAIN); - lv_obj_set_style_pad_top(scroll_area, 10, LV_PART_MAIN); - lv_obj_set_style_pad_bottom(scroll_area, 20, LV_PART_MAIN); - lv_obj_set_style_radius(scroll_area, 0, LV_PART_MAIN); - lv_obj_set_style_border_width(scroll_area, 0, LV_PART_MAIN); + //We register the event callback to handle the cleanup + lv_obj_add_event_cb(menuScreen->display, &(cleanup_event_cb), LV_EVENT_DELETE, menuScreen); +} - lv_obj_set_style_pad_right(scroll_area, 15, LV_PART_SCROLLBAR); - - for(uint8_t i = 0; i < array_size(iconItems); i++) +void menu_screen_destroy(MenuScreen_t * const menuScreen) +{ + if(!menuScreen) { - lv_obj_t *btn = lv_imgbtn_create(scroll_area); - lv_obj_set_size(btn, 42, 42); - lv_obj_set_pos(btn, 42, 52 * i); - lv_obj_add_event_cb(btn, iconItems[i].event_cb, LV_EVENT_PRESSED, NULL); - lv_imgbtn_set_src(btn, LV_IMGBTN_STATE_RELEASED, NULL, iconItems[i].img, NULL); - - lv_obj_t *label = lv_label_create(scroll_area); - lv_label_set_text_static(label, iconItems[i].text); - lv_obj_set_style_text_font(label, &lv_font_montserrat_16, LV_PART_MAIN); - lv_obj_set_pos(label, 84+12,15 + 52 * i); - lv_obj_set_style_text_color(label, lv_color_make(145, 145, 145), LV_PART_MAIN); - lv_obj_set_ext_click_area(label, 10); - lv_obj_add_flag(label, LV_OBJ_FLAG_CLICKABLE); - lv_obj_add_event_cb(label, iconItems[i].event_cb, LV_EVENT_PRESSED , NULL); + LV_LOG_ERROR("NULL pointer given !"); + return; } + menuScreen->display = NULL; } diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.h b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.h index 7105f42..07ea1b2 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.h +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.h @@ -1,6 +1,20 @@ #ifndef MENU_SCREEN_H #define MENU_SCREEN_H -void menu_screen(void); +#include "lvgl.h" + +typedef struct MenuScreen +{ + lv_obj_t *display; +} MenuScreen_t; + +/* Initializes the menu screen context object */ +void menu_screen_init(MenuScreen_t * const menuScreen); + +/* Builds the menu screen graphically */ +void menu_screen_create(MenuScreen_t * const menuScreen); + +/* Frees all resources used by the MenuScreen object */ +void menu_screen_destroy(MenuScreen_t * const menuScreen); #endif //MENU_SCREEN_H diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.c b/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.c index 6b81234..903f21d 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.c +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.c @@ -1,91 +1,12 @@ #include "lvgl.h" #include "watch_face.h" #include "menu_screen.h" -#include #include -lv_obj_t *hour_hand_img = NULL; -lv_obj_t *minute_hand_img = NULL; -lv_obj_t *second_hand_img = NULL; -lv_obj_t *small_hand_img = NULL; -lv_obj_t *medium_hand_24h_img = NULL; -lv_obj_t *medium_hand_chrono_sec_img = NULL; -lv_obj_t *date_roller = NULL; -lv_obj_t *date_label = NULL; - -lv_obj_t *watch_screen = NULL; -lv_timer_t *hand_timer = NULL; - -char date_buffer[] = "12"; -int date = 0; - -float angle = 0, angle_minute = 0, angle_heure = 0; - -void lv_timer_cb(lv_timer_t * timer) +static void gesture_event_cb(lv_event_t * e) { - angle += 12; - if(angle >= 3660) - { - time_t time_type = time(NULL); - struct tm *tm = localtime(&time_type); - LV_LOG_USER("Time is : %llu, Time : %d:%d:%d", time_type, tm->tm_hour, tm->tm_min, tm->tm_sec); + WatchFace_t *watchFace = e->user_data; - angle = 60.0 * (float)tm->tm_sec; - angle_minute = 60.0 * (float)tm->tm_min; - angle_heure = 300.0 * (float)tm->tm_hour; - sprintf(date_buffer, "%d", tm->tm_mday); - - /*angle = 0; - angle_minute += 60;*/ - } - - /*if(angle_minute >= 3600) - { - angle_minute = 0; - angle_heure += 300; - } - - if(angle_heure >= 7200) - { - angle_heure = 0; - - sprintf(date_buffer, "%d", date++); - }*/ - - lv_obj_invalidate(date_label); - - lv_img_set_angle(second_hand_img, (uint16_t)angle % 3600); - float angle_minute_adj = angle_minute + angle/60.0; - lv_img_set_angle(minute_hand_img, (uint16_t)angle_minute_adj % 3600); - float angle_heure_adj = (angle_heure + angle_minute_adj/12.0); - lv_img_set_angle(hour_hand_img, (uint16_t)(angle_heure_adj)%3600); - float medium_hand_angle = (angle_heure/2.0 + angle_minute_adj/24.0); - LV_LOG_USER("Minute angle : %0.f\nHour angle : %0.f\n24 Hour angle : %0.f", angle_minute_adj, angle_heure_adj, medium_hand_angle); - lv_img_set_angle(medium_hand_24h_img, (uint16_t)medium_hand_angle%3600); -} - -void lv_timer_cb2(lv_timer_t * timer) -{ - - time_t time_type = time(NULL); - struct tm *tm = localtime(&time_type); - LV_LOG_USER("Time is : %llu, Time : %d:%d:%d", time_type, tm->tm_hour, tm->tm_min, tm->tm_sec); - - angle = 60.0 * tm->tm_sec; - angle_minute = 60.0 * tm->tm_min; - angle_heure = 300.0 * tm->tm_hour; - sprintf(date_buffer, "%d", tm->tm_mday); - - lv_img_set_angle(second_hand_img, (uint16_t)angle % 3600); - lv_img_set_angle(minute_hand_img, (uint16_t)(angle_minute + angle/60) % 3600); - lv_img_set_angle(hour_hand_img, (uint16_t)(angle_heure + angle_minute/12) % 3600); - lv_img_set_angle(medium_hand_24h_img, (uint16_t)(angle_heure/2 + angle_minute/48)%3600); - - lv_obj_invalidate(date_label); -} - -static void event_cb(lv_event_t * e) -{ lv_dir_t gesture; switch(gesture = lv_indev_get_gesture_dir(lv_indev_get_act())) { @@ -94,10 +15,12 @@ static void event_cb(lv_event_t * e) break; case LV_DIR_RIGHT: LV_LOG_USER("GESTURE : RIGHT"); - extern lv_obj_t *men_screen; - //lv_timer_del(hand_timer); - //menu_screen(); - lv_scr_load_anim(men_screen, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 400, 0, false); + // We delete the timer + lv_timer_del(watchFace->handAnimationTimer); + // We create the menu screen and switch to it + extern MenuScreen_t menuScreen; + menu_screen_create(&menuScreen); + lv_scr_load_anim(menuScreen.display, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 400, 0, true); break; case LV_DIR_TOP: LV_LOG_USER("GESTURE : TOP"); @@ -110,79 +33,59 @@ static void event_cb(lv_event_t * e) } } -void watch_face(void) +static void cleanup_event_cb(lv_event_t * e) { - LV_IMG_DECLARE(watch_casio_face_asset) - LV_IMG_DECLARE(watch_casio_hour_hand_asset) - LV_IMG_DECLARE(watch_casio_minute_hand_asset) - LV_IMG_DECLARE(watch_casio_second_hand_asset) - LV_IMG_DECLARE(watch_casio_medium_hand_asset) - LV_IMG_DECLARE(watch_casio_small_hand_asset) + WatchFace_t *watchFace = e->user_data; + watch_face_destroy(watchFace); + LV_LOG_USER("cleanup"); +} - watch_screen = lv_scr_act(); //lv_obj_create(NULL); - lv_scr_load(watch_screen); +static void update_watch_hands_angles(WatchFace_t * const watchFace, uint8_t increment) +{ + if(!watchFace) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } - lv_obj_t *watch_face_img = lv_img_create(watch_screen); - lv_img_set_src(watch_face_img, &watch_casio_face_asset); + //We retrieve the current time: + if(watchFace->dateTimeCb) + { + //We compute each hand angle + if(!increment || watchFace->secondHand.handAngle >= 3660) + { + watchFace->dateTimeCb(&watchFace->dateTime); + watchFace->secondHand.handAngle = 60 * watchFace->dateTime.tm_sec; - small_hand_img = lv_img_create(watch_screen); - lv_img_set_src(small_hand_img, &watch_casio_small_hand_asset); - lv_obj_set_pos(small_hand_img , 69, 98); - lv_img_set_pivot(small_hand_img, 4, 20); + //Don't forget to update the day date window + sprintf(watchFace->dateWindow.dateWindowText, "%s%d", watchFace->dateTime.tm_mday < 10 ? " " : "", watchFace->dateTime.tm_mday); + lv_obj_invalidate(watchFace->dateWindow.dateWindowWidget); + } + else + { + watchFace->secondHand.handAngle += increment; + } + watchFace->minuteHand.handAngle = 60 * watchFace->dateTime.tm_min + watchFace->secondHand.handAngle / 60; + watchFace->hourHand.handAngle = 300 * watchFace->dateTime.tm_hour + watchFace->minuteHand.handAngle / 12; + watchFace->mediumHand24h.handAngle = watchFace->hourHand.handAngle / 2; + LV_LOG_USER("angle : %f", watchFace->secondHand.handAngle); - medium_hand_24h_img = lv_img_create(watch_screen); - lv_img_set_src(medium_hand_24h_img, &watch_casio_medium_hand_asset); - lv_obj_set_pos(medium_hand_24h_img , 115, 48); - lv_img_set_pivot(medium_hand_24h_img, 4, 25); + //We update the angle + lv_img_set_angle(watchFace->secondHand.handImg, (uint16_t) watchFace->secondHand.handAngle % 3600); + lv_img_set_angle(watchFace->minuteHand.handImg, (uint16_t) watchFace->minuteHand.handAngle % 3600); + lv_img_set_angle(watchFace->hourHand.handImg, (uint16_t) watchFace->hourHand.handAngle % 3600); + lv_img_set_angle(watchFace->mediumHand24h.handImg, (uint16_t) watchFace->mediumHand24h.handAngle % 3600); + } + else + { + LV_LOG_USER("DateTimeCb is NULL, be sure to register a callback !"); + } +} - medium_hand_chrono_sec_img = lv_img_create(watch_screen); - lv_img_set_src(medium_hand_chrono_sec_img, &watch_casio_medium_hand_asset); - lv_obj_set_pos(medium_hand_chrono_sec_img , 115, 140); - lv_img_set_pivot(medium_hand_chrono_sec_img, 4, 25); - - date_label = lv_label_create(watch_screen); - lv_label_set_text_static(date_label, date_buffer); - lv_obj_set_pos(date_label, 182,112); - - hour_hand_img = lv_img_create(watch_screen); - lv_img_set_src(hour_hand_img, &watch_casio_hour_hand_asset); - lv_obj_set_pos(hour_hand_img, 112, 60); - lv_img_set_pivot(hour_hand_img, 8,60); - - minute_hand_img = lv_img_create(watch_screen); - lv_img_set_src(minute_hand_img, &watch_casio_minute_hand_asset); - lv_img_set_antialias(minute_hand_img, true); - lv_obj_set_pos(minute_hand_img, 112, 28); - lv_img_set_pivot(minute_hand_img, 7,92); - - second_hand_img = lv_img_create(watch_screen); - lv_img_set_src(second_hand_img, &watch_casio_second_hand_asset); - lv_obj_set_pos(second_hand_img, 115, 28); - lv_img_set_pivot(second_hand_img, 5,92); - - LV_LOG_USER("Adding event to screen"); - lv_obj_add_event_cb(watch_screen, &(event_cb), LV_EVENT_GESTURE, NULL); - - time_t time_type = time(NULL); - struct tm *tm = localtime(&time_type); - LV_LOG_USER("Time is : %llu, Time : %d:%d:%d", time_type, tm->tm_hour, tm->tm_min, tm->tm_sec); - - angle = 60.0 * (float)tm->tm_sec; - angle_minute = 60.0 * (float)tm->tm_min; - angle_heure = 300.0 * (float)tm->tm_hour; - sprintf(date_buffer, "%d", tm->tm_mday); - - lv_img_set_angle(second_hand_img, (uint16_t)angle % 3600); - lv_img_set_angle(minute_hand_img, (uint16_t)(angle_minute + angle/60.0) % 3600); - lv_img_set_angle(hour_hand_img, (uint16_t)(angle_heure + angle_minute/12.0) % 3600); - lv_img_set_angle(medium_hand_24h_img, (uint16_t)(angle_heure/2.0 + angle_minute/24.0)%3600); - - - LV_LOG_USER("Starting watch timer"); - hand_timer = lv_timer_create(&(lv_timer_cb),199,NULL); - //hand_timer = lv_timer_create(&(lv_timer_cb2),1000,NULL); - - //lv_obj_clean(lv_scr_act()); +static void hand_timer_anim_cb(lv_timer_t *timer) +{ + WatchFace_t *watchFace = timer->user_data; + update_watch_hands_angles(watchFace, 12); } void watch_face_init(WatchFace_t * const watchFace) @@ -195,7 +98,7 @@ void watch_face_init(WatchFace_t * const watchFace) memset(watchFace, 0, sizeof(WatchFace_t)); } -void watch_face_register_cb(WatchFace_t * const watchFace, DateTimeCb_t DateTimeCb) +void watch_face_register_cb(WatchFace_t * const watchFace, DateTimeCb_t dateTimeCb) { if(!watchFace) { @@ -203,10 +106,10 @@ void watch_face_register_cb(WatchFace_t * const watchFace, DateTimeCb_t DateTime return; } - watchFace->DateTimeCb = DateTimeCb; + watchFace->dateTimeCb = dateTimeCb; } -lv_obj_t *watch_face_create(WatchFace_t * const watchFace) +void watch_face_create(WatchFace_t * const watchFace) { if(!watchFace) { @@ -223,84 +126,119 @@ lv_obj_t *watch_face_create(WatchFace_t * const watchFace) LV_IMG_DECLARE(watch_casio_small_hand_asset) //We create our parent screen : - lv_obj_t *watchFaceScreen = lv_obj_create(NULL); - + if(watchFace->display) + { + LV_LOG_ERROR("display should be NULL here !"); + lv_obj_del(watchFace->display); + watchFace->display = NULL; + } + watchFace->display = lv_obj_create(NULL); //We load our assets : - lv_obj_t *watchFaceImg = lv_img_create(watchFaceScreen); + lv_obj_t *watchFaceImg = lv_img_create(watchFace->display); lv_img_set_src(watchFaceImg, &watch_casio_face_asset); - lv_obj_t *smallHandImg = lv_img_create(watchFaceScreen); + lv_obj_t *smallHandImg = lv_img_create(watchFace->display); lv_img_set_src(smallHandImg, &watch_casio_small_hand_asset); lv_obj_set_pos(smallHandImg, 69, 98); lv_img_set_pivot(smallHandImg, 4, 20); - if(watchFace->mediumHand24hImg) + if(watchFace->mediumHand24h.handImg) { LV_LOG_ERROR("mediumHand24hImg should be NULL here !"); - lv_obj_del(watchFace->mediumHand24hImg); - watchFace->mediumHand24hImg = NULL; + lv_obj_del(watchFace->mediumHand24h.handImg); + watchFace->mediumHand24h.handImg = NULL; } - watchFace->mediumHand24hImg = lv_img_create(watchFaceScreen); - lv_img_set_src(watchFace->mediumHand24hImg, &watch_casio_medium_hand_asset); - lv_obj_set_pos(watchFace->mediumHand24hImg, 115, 48); - lv_img_set_pivot(watchFace->mediumHand24hImg, 4, 25); + watchFace->mediumHand24h.handImg = lv_img_create(watchFace->display); + lv_img_set_src(watchFace->mediumHand24h.handImg, &watch_casio_medium_hand_asset); + lv_obj_set_pos(watchFace->mediumHand24h.handImg, 115, 48); + lv_img_set_pivot(watchFace->mediumHand24h.handImg, 4, 25); - lv_obj_t *mediumHandChronoImg = lv_img_create(watchFaceScreen); + lv_obj_t *mediumHandChronoImg = lv_img_create(watchFace->display); lv_img_set_src(mediumHandChronoImg, &watch_casio_medium_hand_asset); lv_obj_set_pos(mediumHandChronoImg, 115, 140); lv_img_set_pivot(mediumHandChronoImg, 4, 25); //Date window is created here - if(watchFace->dateWindow) + if(watchFace->dateWindow.dateWindowWidget) { LV_LOG_ERROR("dateWindow should be NULL here !"); - lv_obj_del(watchFace->dateWindow); - watchFace->dateWindow = NULL; + lv_obj_del(watchFace->dateWindow.dateWindowWidget); + watchFace->dateWindow.dateWindowWidget = NULL; } - watchFace->dateWindow = lv_label_create(watchFaceScreen); - lv_label_set_text_static(watchFace->dateWindow, watchFace->dateWindowText); - lv_obj_set_pos(watchFace->dateWindow, 182,112); + watchFace->dateWindow.dateWindowWidget = lv_label_create(watchFace->display); + lv_label_set_text_static(watchFace->dateWindow.dateWindowWidget, watchFace->dateWindow.dateWindowText); + lv_obj_set_pos(watchFace->dateWindow.dateWindowWidget, 182,112); - if(watchFace->hourHandImg) + if(watchFace->hourHand.handImg) { LV_LOG_ERROR("hourHandImg should be NULL here !"); - lv_obj_del(watchFace->hourHandImg); - watchFace->hourHandImg = NULL; + lv_obj_del(watchFace->hourHand.handImg); + watchFace->hourHand.handImg = NULL; } - watchFace->hourHandImg = lv_img_create(watchFaceScreen); - lv_img_set_src(watchFace->hourHandImg, &watch_casio_hour_hand_asset); - lv_obj_set_pos(watchFace->hourHandImg, 112, 60); - lv_img_set_pivot(watchFace->hourHandImg, 8, 60); + watchFace->hourHand.handImg = lv_img_create(watchFace->display); + lv_img_set_src(watchFace->hourHand.handImg, &watch_casio_hour_hand_asset); + lv_obj_set_pos(watchFace->hourHand.handImg, 112, 60); + lv_img_set_pivot(watchFace->hourHand.handImg, 8, 60); - if(watchFace->minuteHandImg) + if(watchFace->minuteHand.handImg) { LV_LOG_ERROR("minuteHandImg should be NULL here !"); - lv_obj_del(watchFace->minuteHandImg); - watchFace->minuteHandImg = NULL; + lv_obj_del(watchFace->minuteHand.handImg); + watchFace->minuteHand.handImg = NULL; } - watchFace->minuteHandImg = lv_img_create(watchFaceScreen); - lv_img_set_src(watchFace->minuteHandImg, &watch_casio_minute_hand_asset); - lv_obj_set_pos(watchFace->minuteHandImg, 112, 28); - lv_img_set_pivot(watchFace->minuteHandImg, 7, 92); + watchFace->minuteHand.handImg = lv_img_create(watchFace->display); + lv_img_set_src(watchFace->minuteHand.handImg, &watch_casio_minute_hand_asset); + lv_obj_set_pos(watchFace->minuteHand.handImg, 112, 28); + lv_img_set_pivot(watchFace->minuteHand.handImg, 7, 92); - if(watchFace->secondHandImg) + if(watchFace->secondHand.handImg) { LV_LOG_ERROR("secondHandImg should be NULL here !"); - lv_obj_del(watchFace->secondHandImg); - watchFace->secondHandImg = NULL; + lv_obj_del(watchFace->secondHand.handImg); + watchFace->secondHand.handImg = NULL; } - watchFace->secondHandImg = lv_img_create(watchFaceScreen); - lv_img_set_src(watchFace->secondHandImg, &watch_casio_second_hand_asset); - lv_obj_set_pos(watchFace->secondHandImg, 115, 28); - lv_img_set_pivot(watchFace->secondHandImg, 5, 92); + watchFace->secondHand.handImg = lv_img_create(watchFace->display); + lv_img_set_src(watchFace->secondHand.handImg, &watch_casio_second_hand_asset); + lv_obj_set_pos(watchFace->secondHand.handImg, 115, 28); + lv_img_set_pivot(watchFace->secondHand.handImg, 5, 92); + + //We set the appropriate angles to each of the hands + update_watch_hands_angles(watchFace, 0); + + //We register the event callback to handle gestures + lv_obj_add_event_cb(watchFace->display, &(gesture_event_cb), LV_EVENT_GESTURE, watchFace); + //We register the event callback to handle the cleanup + lv_obj_add_event_cb(watchFace->display, &(cleanup_event_cb), LV_EVENT_DELETE, watchFace); //We create the timer to run the watch animations + if(watchFace->handAnimationTimer) + { + LV_LOG_ERROR("handAnimationTimer should be NULL here !"); + lv_timer_del(watchFace->handAnimationTimer); + watchFace->handAnimationTimer = NULL; + } - - return watchFaceScreen; + watchFace->handAnimationTimer = lv_timer_create(&(hand_timer_anim_cb), 200, watchFace); +} + +void watch_face_destroy(WatchFace_t * const watchFace) +{ + if(!watchFace) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + watchFace->display = NULL; + watchFace->handAnimationTimer = NULL; + watchFace->dateWindow.dateWindowWidget = NULL; + watchFace->hourHand.handImg = NULL; + watchFace->minuteHand.handImg = NULL; + watchFace->secondHand.handImg = NULL; + watchFace->mediumHand24h.handImg = NULL; } diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.h b/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.h index a41d0d5..104c7fe 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.h +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/watch_face.h @@ -4,19 +4,33 @@ #include "lvgl.h" #include -typedef void (*DateTimeCb_t)(struct tm * const DateTime); +typedef void (*DateTimeCb_t)(struct tm * const dateTime); + +typedef struct DateWindow +{ + lv_obj_t *dateWindowWidget; + char dateWindowText[3]; +} DateWindow_t; + +typedef struct WatchHand +{ + lv_obj_t *handImg; + float handAngle; +}WatchHand_t; /* Watch face context object */ typedef struct WatchFace { - DateTimeCb_t DateTimeCb; //Call back function used to retrieve the date and time needed by the watch face - lv_obj_t *hourHandImg; - lv_obj_t *minuteHandImg; - lv_obj_t *secondHandImg; - lv_obj_t *mediumHand24hImg; - lv_obj_t *dateWindow; + DateTimeCb_t dateTimeCb; //Call back function used to retrieve the date and time needed by the watch face + WatchHand_t hourHand; + WatchHand_t minuteHand; + WatchHand_t secondHand; + WatchHand_t mediumHand24h; lv_timer_t *handAnimationTimer; - char dateWindowText[3]; + lv_obj_t *display; + DateWindow_t dateWindow; + + struct tm dateTime; } WatchFace_t; /* Initializes the watch face context object */ @@ -25,9 +39,10 @@ void watch_face_init(WatchFace_t * const watchFace); /* Registers a call back function to retrieve the time and date */ void watch_face_register_cb(WatchFace_t * const watchFace, DateTimeCb_t DateTimeCb); -/* Builds the watch face graphically and returns it as a lv_obj_t* */ -lv_obj_t *watch_face_create(WatchFace_t * const watchFace); +/* Builds the watch face graphically */ +void watch_face_create(WatchFace_t * const watchFace); -void watch_face(void); +/* Frees all resources used by the WatchFace object */ +void watch_face_destroy(WatchFace_t * const watchFace); #endif // WATCH_FACE_H