Reworked the watch_face screen and the menu screen so that they can be created and destroyed when needed

This commit is contained in:
Th3maz1ng 2022-12-01 20:34:18 +01:00
parent bfede27653
commit 9bf5c774cb
7 changed files with 299 additions and 278 deletions

View File

@ -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");

View File

@ -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

View File

@ -14,6 +14,7 @@
#include "lv_drivers/win32drv/win32drv.h"
#include <windows.h>
#include <time.h>
#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) {

View File

@ -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;
}

View File

@ -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

View File

@ -1,91 +1,12 @@
#include "lvgl.h"
#include "watch_face.h"
#include "menu_screen.h"
#include <time.h>
#include <stdio.h>
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;
}

View File

@ -4,19 +4,33 @@
#include "lvgl.h"
#include <time.h>
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