Refactored the watch faces to only have one source file, added the possibility to choose which watch face to use when compiling
This commit is contained in:
parent
f78a1f3a1a
commit
53519391ef
@ -22,6 +22,19 @@
|
||||
|
||||
#define HARDWARE_PLATFORM SMART_WATCH_PCB_RELEASE
|
||||
|
||||
/**
|
||||
* @brief Defines which watch face to use :
|
||||
*
|
||||
* SMART_WATCH_CASIO_FACE : this is the first watch face ported to the watch based on a casio edifice watch.
|
||||
* SMART_WATCH_CARBON_FACE : a watch face designed from the ground up using a carbon fiber vibe.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SMART_WATCH_CASIO_FACE (0)
|
||||
#define SMART_WATCH_CARBON_FACE (1)
|
||||
|
||||
#define SMART_WATCH_FACE SMART_WATCH_CARBON_FACE
|
||||
|
||||
/**
|
||||
* @brief Define which kind of logs to display :
|
||||
*
|
||||
|
@ -3,11 +3,70 @@
|
||||
#include "menu_screen.h"
|
||||
#include <stdio.h>
|
||||
#include "app_log.h"
|
||||
#include "app_config.h"
|
||||
|
||||
LV_IMG_DECLARE(battery_low_icon)
|
||||
LV_IMG_DECLARE(battery_charging_icon)
|
||||
LV_IMG_DECLARE(battery_charged_icon)
|
||||
|
||||
#if SMART_WATCH_FACE == SMART_WATCH_CASIO_FACE
|
||||
//We declare the needed assets for the casio watch face:
|
||||
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)
|
||||
|
||||
static const void *watch_face_img = &watch_casio_face_asset;
|
||||
static const void *watch_hour_hand_img = &watch_casio_hour_hand_asset;
|
||||
#define HOUR_HAND_POS 112, 60
|
||||
#define HOUR_HAND_PIVOT 8, 60
|
||||
static const void *watch_minute_hand_img = &watch_casio_minute_hand_asset;
|
||||
#define MINUTE_HAND_POS 112, 28
|
||||
#define MINUTE_HAND_PIVOT 7, 92
|
||||
static const void *watch_second_hand_img = &watch_casio_second_hand_asset;
|
||||
#define SECOND_HAND_POS 115, 28
|
||||
#define SECOND_HAND_PIVOT 5, 92
|
||||
static const void *watch_medium_hand_img = &watch_casio_medium_hand_asset;
|
||||
#define MEDIUM_HAND_POS 115, 48
|
||||
#define MEDIUM_HAND_PIVOT 4, 25
|
||||
|
||||
#define BATTERY_ARC_OFFSETS -1, 45
|
||||
#define BATTERY_ICON_OFFSETS 0, -9
|
||||
#define STEP_COUNTER_LABEL_POS 63, 111
|
||||
#define DATE_WINDOW_POS 180, 111
|
||||
#define DATE_LABEL_COLOR lv_color_black()
|
||||
#elif SMART_WATCH_FACE == SMART_WATCH_CARBON_FACE
|
||||
//We declare the needed assets for the carbon watch face:
|
||||
LV_IMG_DECLARE(watch_carbon_face_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_hour_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_minute_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_second_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_medium_hand_asset)
|
||||
|
||||
static const void *watch_face_img = &watch_carbon_face_asset;
|
||||
static const void *watch_hour_hand_img = &watch_carbon_hour_hand_asset;
|
||||
#define HOUR_HAND_POS 113, 57
|
||||
#define HOUR_HAND_PIVOT 6, 62
|
||||
static const void *watch_minute_hand_img = &watch_carbon_minute_hand_asset;
|
||||
#define MINUTE_HAND_POS 113, 14
|
||||
#define MINUTE_HAND_PIVOT 6, 105
|
||||
static const void *watch_second_hand_img = &watch_carbon_second_hand_asset;
|
||||
#define SECOND_HAND_POS 115, -1
|
||||
#define SECOND_HAND_PIVOT 4, 120
|
||||
static const void *watch_medium_hand_img = &watch_carbon_medium_hand_asset;
|
||||
#define MEDIUM_HAND_POS 115, 50
|
||||
#define MEDIUM_HAND_PIVOT 4, 26
|
||||
|
||||
#define BATTERY_ARC_OFFSETS 0, 44
|
||||
#define BATTERY_ICON_OFFSETS 0, -12
|
||||
#define STEP_COUNTER_LABEL_POS 50, 111
|
||||
#define DATE_WINDOW_POS 168, 111
|
||||
#define DATE_LABEL_COLOR lv_color_white()
|
||||
#else
|
||||
#error "Bad app_config.h configuration for the selected watch face"
|
||||
#endif //SMART_WATCH_FACE
|
||||
|
||||
static void _set_bluetooth_indicator(WatchFace_t * const watchFace)
|
||||
{
|
||||
switch(watchFace->bluetoothIndicator.bluetoothState)
|
||||
@ -238,11 +297,6 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
|
||||
//We declare the needed assets for the watch face:
|
||||
LV_IMG_DECLARE(watch_carbon_face_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_hour_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_minute_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_second_hand_asset)
|
||||
LV_IMG_DECLARE(watch_carbon_medium_hand_asset)
|
||||
LV_IMG_DECLARE(bluetooth_icon)
|
||||
|
||||
//We create our parent screen :
|
||||
@ -254,16 +308,10 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
//Our display is the watch face image :
|
||||
watchFace->display = lv_img_create(NULL);
|
||||
lv_img_set_src(watchFace->display, &watch_carbon_face_asset);
|
||||
lv_img_set_src(watchFace->display, watch_face_img);
|
||||
lv_obj_set_style_bg_color(watchFace->display, lv_color_black(), LV_PART_MAIN);
|
||||
lv_obj_add_event_cb(watchFace->display, &(hide_hour_and_minutes_hand_cb), LV_EVENT_LONG_PRESSED, watchFace);
|
||||
|
||||
//We load our other assets :
|
||||
/*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);*/
|
||||
|
||||
//Battery arc is created here
|
||||
if(watchFace->batteryIndicator.batteryArc)
|
||||
{
|
||||
@ -276,7 +324,7 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
lv_obj_remove_style(watchFace->batteryIndicator.batteryArc, NULL, LV_PART_KNOB);
|
||||
lv_obj_clear_flag(watchFace->batteryIndicator.batteryArc, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_size(watchFace->batteryIndicator.batteryArc, 60, 60);
|
||||
lv_obj_align(watchFace->batteryIndicator.batteryArc, LV_ALIGN_CENTER, 0, 44);
|
||||
lv_obj_align(watchFace->batteryIndicator.batteryArc, LV_ALIGN_CENTER, BATTERY_ARC_OFFSETS);
|
||||
lv_obj_set_style_arc_width(watchFace->batteryIndicator.batteryArc, 5, LV_PART_INDICATOR);
|
||||
lv_obj_set_style_arc_width(watchFace->batteryIndicator.batteryArc, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_arc_color(watchFace->batteryIndicator.batteryArc, lv_color_make(228, 233, 236), LV_PART_INDICATOR);
|
||||
@ -317,7 +365,7 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
// this is why we call the function after the timer has been created
|
||||
set_battery_state_icon(watchFace);
|
||||
lv_img_set_zoom(watchFace->batteryIndicator.batteryIcon, 141);
|
||||
lv_obj_align_to(watchFace->batteryIndicator.batteryIcon, watchFace->batteryIndicator.label, LV_ALIGN_OUT_BOTTOM_MID, 0, -12);
|
||||
lv_obj_align_to(watchFace->batteryIndicator.batteryIcon, watchFace->batteryIndicator.label, LV_ALIGN_OUT_BOTTOM_MID, BATTERY_ICON_OFFSETS);
|
||||
|
||||
// Bluetooth status icon is created here
|
||||
if(watchFace->bluetoothIndicator.bluetoothIcon)
|
||||
@ -345,7 +393,7 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
watchFace->stepCounter.label = lv_label_create(watchFace->display);
|
||||
lv_label_set_text_static(watchFace->stepCounter.label, watchFace->stepCounter.text);
|
||||
lv_obj_set_style_text_color(watchFace->stepCounter.label, lv_color_white(), LV_PART_MAIN);
|
||||
lv_obj_set_pos(watchFace->stepCounter.label, 50, 111);
|
||||
lv_obj_set_pos(watchFace->stepCounter.label, STEP_COUNTER_LABEL_POS);
|
||||
|
||||
if(watchFace->mediumHand24h.handImg)
|
||||
{
|
||||
@ -355,9 +403,9 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
|
||||
watchFace->mediumHand24h.handImg = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(watchFace->mediumHand24h.handImg, &watch_carbon_medium_hand_asset);
|
||||
lv_obj_set_pos(watchFace->mediumHand24h.handImg, 115, 50);
|
||||
lv_img_set_pivot(watchFace->mediumHand24h.handImg, 4, 26);
|
||||
lv_img_set_src(watchFace->mediumHand24h.handImg, watch_medium_hand_img);
|
||||
lv_obj_set_pos(watchFace->mediumHand24h.handImg, MEDIUM_HAND_POS);
|
||||
lv_img_set_pivot(watchFace->mediumHand24h.handImg, MEDIUM_HAND_PIVOT);
|
||||
|
||||
/*lv_obj_t *mediumHandChronoImg = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(mediumHandChronoImg, &watch_casio_medium_hand_asset);
|
||||
@ -373,10 +421,10 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
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, 168,111);
|
||||
lv_obj_set_pos(watchFace->dateWindow.dateWindowWidget, DATE_WINDOW_POS);
|
||||
lv_obj_set_width(watchFace->dateWindow.dateWindowWidget, 20);
|
||||
lv_obj_set_style_text_align(watchFace->dateWindow.dateWindowWidget, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(watchFace->dateWindow.dateWindowWidget, lv_color_white(), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(watchFace->dateWindow.dateWindowWidget, DATE_LABEL_COLOR, LV_PART_MAIN);
|
||||
|
||||
if(watchFace->hourHand.handImg)
|
||||
{
|
||||
@ -386,9 +434,9 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
|
||||
watchFace->hourHand.handImg = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(watchFace->hourHand.handImg, &watch_carbon_hour_hand_asset);
|
||||
lv_obj_set_pos(watchFace->hourHand.handImg, 113, 57);
|
||||
lv_img_set_pivot(watchFace->hourHand.handImg, 6, 62);
|
||||
lv_img_set_src(watchFace->hourHand.handImg, watch_hour_hand_img);
|
||||
lv_obj_set_pos(watchFace->hourHand.handImg, HOUR_HAND_POS);
|
||||
lv_img_set_pivot(watchFace->hourHand.handImg, HOUR_HAND_PIVOT);
|
||||
|
||||
if(watchFace->minuteHand.handImg)
|
||||
{
|
||||
@ -398,9 +446,9 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
|
||||
watchFace->minuteHand.handImg = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(watchFace->minuteHand.handImg, &watch_carbon_minute_hand_asset);
|
||||
lv_obj_set_pos(watchFace->minuteHand.handImg, 113, 14);
|
||||
lv_img_set_pivot(watchFace->minuteHand.handImg, 6, 105);
|
||||
lv_img_set_src(watchFace->minuteHand.handImg, watch_minute_hand_img);
|
||||
lv_obj_set_pos(watchFace->minuteHand.handImg, MINUTE_HAND_POS);
|
||||
lv_img_set_pivot(watchFace->minuteHand.handImg, MINUTE_HAND_PIVOT);
|
||||
|
||||
if(watchFace->secondHand.handImg)
|
||||
{
|
||||
@ -410,9 +458,9 @@ void watch_face_create(WatchFace_t * const watchFace)
|
||||
}
|
||||
|
||||
watchFace->secondHand.handImg = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(watchFace->secondHand.handImg, &watch_carbon_second_hand_asset);
|
||||
lv_obj_set_pos(watchFace->secondHand.handImg, 115, -1);
|
||||
lv_img_set_pivot(watchFace->secondHand.handImg, 4, 120);
|
||||
lv_img_set_src(watchFace->secondHand.handImg, watch_second_hand_img);
|
||||
lv_obj_set_pos(watchFace->secondHand.handImg, SECOND_HAND_POS);
|
||||
lv_img_set_pivot(watchFace->secondHand.handImg, SECOND_HAND_PIVOT);
|
||||
|
||||
//We set the appropriate angles to each of the hands
|
||||
update_watch_hands_angles(watchFace, 0);
|
@ -1,575 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "watch_face.h"
|
||||
#include "menu_screen.h"
|
||||
#include <stdio.h>
|
||||
#include "app_log.h"
|
||||
|
||||
LV_IMG_DECLARE(battery_low_icon)
|
||||
LV_IMG_DECLARE(battery_charging_icon)
|
||||
LV_IMG_DECLARE(battery_charged_icon)
|
||||
|
||||
static void _set_bluetooth_indicator(WatchFace_t * const watchFace)
|
||||
{
|
||||
switch(watchFace->bluetoothIndicator.bluetoothState)
|
||||
{
|
||||
case BLUETOOTH_STATE_ON:
|
||||
lv_obj_set_style_img_recolor_opa(watchFace->bluetoothIndicator.bluetoothIcon, 185, LV_PART_MAIN);
|
||||
lv_obj_clear_flag(watchFace->bluetoothIndicator.bluetoothIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
break;
|
||||
case BLUETOOTH_STATE_CONNECTED:
|
||||
lv_obj_set_style_img_recolor_opa(watchFace->bluetoothIndicator.bluetoothIcon, 0, LV_PART_MAIN);
|
||||
lv_obj_clear_flag(watchFace->bluetoothIndicator.bluetoothIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
break;
|
||||
default:
|
||||
lv_obj_add_flag(watchFace->bluetoothIndicator.bluetoothIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void gesture_event_cb(lv_event_t *e)
|
||||
{
|
||||
WatchFace_t *watchFace = lv_event_get_user_data(e);
|
||||
|
||||
lv_dir_t gesture;
|
||||
switch(gesture = lv_indev_get_gesture_dir(lv_indev_get_act()))
|
||||
{
|
||||
case LV_DIR_LEFT:
|
||||
LV_LOG_USER("GESTURE : LEFT");
|
||||
break;
|
||||
case LV_DIR_RIGHT:
|
||||
LV_LOG_USER("GESTURE : RIGHT");
|
||||
// We delete the timer
|
||||
lv_timer_del(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
lv_timer_del(watchFace->handAnimationTimer);
|
||||
lv_timer_del(watchFace->stepCounterRefreshTimer);
|
||||
// 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");
|
||||
break;
|
||||
case LV_DIR_BOTTOM:
|
||||
LV_LOG_USER("GESTURE : BOTTOM");
|
||||
break;
|
||||
default:
|
||||
LV_LOG_USER("GESTURE : %u", gesture);
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup_event_cb(lv_event_t *e)
|
||||
{
|
||||
WatchFace_t *watchFace = lv_event_get_user_data(e);
|
||||
watch_face_destroy(watchFace);
|
||||
LV_LOG_USER("cleanup");
|
||||
}
|
||||
|
||||
static void update_watch_hands_angles(WatchFace_t * const watchFace, uint8_t increment)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
//Don't forget to update the day date window
|
||||
sprintf(watchFace->dateWindow.dateWindowText, "%d", watchFace->dateTime.tm_mday);
|
||||
lv_label_set_text_static(watchFace->dateWindow.dateWindowWidget, watchFace->dateWindow.dateWindowText);
|
||||
|
||||
APP_LOG_DEBUG("Syncing time");
|
||||
|
||||
if(watchFace->batteryIndicatorCb)
|
||||
{
|
||||
uint8_t levelInPercent = 0;
|
||||
BatteryState_e batteryState = BATTERY_STATE_DISCHARGING;
|
||||
watchFace->batteryIndicatorCb(&levelInPercent, &batteryState);
|
||||
watch_face_set_battery_indicator(watchFace, levelInPercent, batteryState);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
//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 !");
|
||||
}
|
||||
}
|
||||
|
||||
static void hand_timer_anim_cb(lv_timer_t *timer)
|
||||
{
|
||||
WatchFace_t *watchFace = timer->user_data;
|
||||
update_watch_hands_angles(watchFace, 12);
|
||||
}
|
||||
|
||||
static void battery_timer_anim_cb(lv_timer_t *timer)
|
||||
{
|
||||
WatchFace_t *watchFace = timer->user_data;
|
||||
|
||||
if(lv_obj_has_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN))
|
||||
{
|
||||
lv_obj_clear_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_obj_add_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void step_counter_refresh_cb(lv_timer_t *timer)
|
||||
{
|
||||
WatchFace_t *watchFace = timer->user_data;
|
||||
|
||||
if(watchFace->stepCounterIndicatorCb)
|
||||
{
|
||||
uint32_t steps = 0;
|
||||
watchFace->stepCounterIndicatorCb(&steps);
|
||||
watch_face_set_step_count_indicator(watchFace, steps);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_battery_state_icon(WatchFace_t * const watchFace)
|
||||
{
|
||||
switch(watchFace->batteryIndicator.batteryState)
|
||||
{
|
||||
case BATTERY_STATE_CHARGING:
|
||||
lv_timer_pause(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
lv_obj_clear_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_img_set_src(watchFace->batteryIndicator.batteryIcon, &battery_charging_icon);
|
||||
break;
|
||||
case BATTERY_STATE_CHARGED:
|
||||
lv_timer_pause(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
lv_obj_clear_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_img_set_src(watchFace->batteryIndicator.batteryIcon, &battery_charged_icon);
|
||||
break;
|
||||
default:
|
||||
lv_obj_add_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_img_set_src(watchFace->batteryIndicator.batteryIcon, &battery_low_icon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hide_hour_and_minutes_hand_cb(lv_event_t *e)
|
||||
{
|
||||
WatchFace_t *watchFace = lv_event_get_user_data(e);
|
||||
|
||||
if(lv_obj_has_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN))
|
||||
{
|
||||
lv_obj_clear_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_clear_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_obj_add_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_add_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
void watch_face_init(WatchFace_t * const watchFace)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
memset(watchFace, 0, sizeof(WatchFace_t));
|
||||
strcpy(watchFace->stepCounter.text, "0");
|
||||
}
|
||||
|
||||
void watch_face_register_date_time_cb(WatchFace_t * const watchFace, DateTimeCb_t dateTimeCb)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
watchFace->dateTimeCb = dateTimeCb;
|
||||
}
|
||||
|
||||
void watch_face_register_battery_indicator_cb(WatchFace_t *const watchFace, BatteryIndicatorCb_t batteryIndicatorCb)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
watchFace->batteryIndicatorCb = batteryIndicatorCb;
|
||||
}
|
||||
|
||||
void watch_face_register_step_counter_indicator_cb(WatchFace_t * const watchFace, StepCounterIndicatorCb_t stepCounterIndicatorCb)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
watchFace->stepCounterIndicatorCb = stepCounterIndicatorCb;
|
||||
}
|
||||
|
||||
void watch_face_create(WatchFace_t * const watchFace)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
//We declare the needed assets for the watch face:
|
||||
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)
|
||||
LV_IMG_DECLARE(bluetooth_icon)
|
||||
|
||||
//We create our parent screen :
|
||||
if(watchFace->display)
|
||||
{
|
||||
LV_LOG_ERROR("display should be NULL here !");
|
||||
lv_obj_del(watchFace->display);
|
||||
watchFace->display = NULL;
|
||||
}
|
||||
//Our display is the watch face image :
|
||||
watchFace->display = lv_img_create(NULL);
|
||||
lv_img_set_src(watchFace->display, &watch_casio_face_asset);
|
||||
lv_obj_set_style_bg_color(watchFace->display, lv_color_black(), LV_PART_MAIN);
|
||||
lv_obj_add_event_cb(watchFace->display, &(hide_hour_and_minutes_hand_cb), LV_EVENT_LONG_PRESSED, watchFace);
|
||||
|
||||
//We load our other assets :
|
||||
/*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);*/
|
||||
|
||||
//Battery arc is created here
|
||||
if(watchFace->batteryIndicator.batteryArc)
|
||||
{
|
||||
LV_LOG_ERROR("batteryArc should be NULL here !");
|
||||
lv_obj_del(watchFace->batteryIndicator.batteryArc);
|
||||
watchFace->batteryIndicator.batteryArc = NULL;
|
||||
}
|
||||
|
||||
watchFace->batteryIndicator.batteryArc = lv_arc_create(watchFace->display);
|
||||
lv_obj_remove_style(watchFace->batteryIndicator.batteryArc, NULL, LV_PART_KNOB);
|
||||
lv_obj_clear_flag(watchFace->batteryIndicator.batteryArc, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_size(watchFace->batteryIndicator.batteryArc, 60, 60);
|
||||
lv_obj_align(watchFace->batteryIndicator.batteryArc, LV_ALIGN_CENTER, -1, 45);
|
||||
lv_obj_set_style_arc_width(watchFace->batteryIndicator.batteryArc, 5, LV_PART_INDICATOR);
|
||||
lv_obj_set_style_arc_width(watchFace->batteryIndicator.batteryArc, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_arc_color(watchFace->batteryIndicator.batteryArc, lv_color_make(228, 233, 236), LV_PART_INDICATOR);
|
||||
lv_arc_set_value(watchFace->batteryIndicator.batteryArc, 100);
|
||||
|
||||
if(watchFace->batteryIndicator.label)
|
||||
{
|
||||
LV_LOG_ERROR("battery_label should be NULL here !");
|
||||
lv_obj_del(watchFace->batteryIndicator.label);
|
||||
watchFace->batteryIndicator.label = NULL;
|
||||
}
|
||||
|
||||
watchFace->batteryIndicator.label = lv_label_create(watchFace->display);
|
||||
strcpy(watchFace->batteryIndicator.text, "100 %");
|
||||
lv_label_set_text_static(watchFace->batteryIndicator.label, watchFace->batteryIndicator.text);
|
||||
lv_obj_set_style_text_color(watchFace->batteryIndicator.label, lv_color_white(), LV_PART_MAIN);
|
||||
lv_obj_align_to(watchFace->batteryIndicator.label, watchFace->batteryIndicator.batteryArc, LV_ALIGN_CENTER, 0, -5);
|
||||
|
||||
// Battery icon is created here
|
||||
if(watchFace->batteryIndicator.batteryIcon)
|
||||
{
|
||||
LV_LOG_ERROR("batteryIcon should be NULL here !");
|
||||
lv_obj_del(watchFace->batteryIndicator.batteryIcon);
|
||||
watchFace->batteryIndicator.batteryIcon = NULL;
|
||||
}
|
||||
watchFace->batteryIndicator.batteryIcon = lv_img_create(watchFace->display);
|
||||
|
||||
if(watchFace->batteryIndicator.lowBatteryAnimationTimer)
|
||||
{
|
||||
LV_LOG_ERROR("battery animation timer should be NULL here !");
|
||||
lv_timer_del(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
watchFace->batteryIndicator.lowBatteryAnimationTimer = NULL;
|
||||
}
|
||||
watchFace->batteryIndicator.lowBatteryAnimationTimer = lv_timer_create(&(battery_timer_anim_cb), 500, watchFace);
|
||||
lv_timer_pause(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
|
||||
// set_battery_state_icon internally needs to interact with the lowBatteryAnimationTimer,
|
||||
// this is why we call the function after the timer has been created
|
||||
set_battery_state_icon(watchFace);
|
||||
lv_img_set_zoom(watchFace->batteryIndicator.batteryIcon, 141);
|
||||
lv_obj_align_to(watchFace->batteryIndicator.batteryIcon, watchFace->batteryIndicator.label, LV_ALIGN_OUT_BOTTOM_MID, 0, -9);
|
||||
|
||||
// Bluetooth status icon is created here
|
||||
if(watchFace->bluetoothIndicator.bluetoothIcon)
|
||||
{
|
||||
LV_LOG_ERROR("bluetoothIcon be NULL here !");
|
||||
lv_obj_del(watchFace->bluetoothIndicator.bluetoothIcon);
|
||||
watchFace->bluetoothIndicator.bluetoothIcon = NULL;
|
||||
}
|
||||
watchFace->bluetoothIndicator.bluetoothIcon = lv_img_create(watchFace->display);
|
||||
lv_img_set_src(watchFace->bluetoothIndicator.bluetoothIcon, &bluetooth_icon);
|
||||
lv_img_set_zoom(watchFace->bluetoothIndicator.bluetoothIcon, 128);
|
||||
lv_obj_add_flag(watchFace->bluetoothIndicator.bluetoothIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_set_style_img_recolor(watchFace->bluetoothIndicator.bluetoothIcon, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
|
||||
lv_obj_align_to(watchFace->bluetoothIndicator.bluetoothIcon, watchFace->batteryIndicator.batteryArc, LV_ALIGN_OUT_LEFT_BOTTOM, -9, 0);
|
||||
_set_bluetooth_indicator(watchFace);
|
||||
|
||||
// StepCounter label is created here
|
||||
if(watchFace->stepCounter.label)
|
||||
{
|
||||
LV_LOG_ERROR("stepCounter should be NULL here !");
|
||||
lv_obj_del(watchFace->stepCounter.label);
|
||||
watchFace->stepCounter.label = NULL;
|
||||
}
|
||||
|
||||
watchFace->stepCounter.label = lv_label_create(watchFace->display);
|
||||
lv_label_set_text_static(watchFace->stepCounter.label, watchFace->stepCounter.text);
|
||||
lv_obj_set_style_text_color(watchFace->stepCounter.label, lv_color_white(), LV_PART_MAIN);
|
||||
lv_obj_set_pos(watchFace->stepCounter.label, 63, 111);
|
||||
|
||||
if(watchFace->mediumHand24h.handImg)
|
||||
{
|
||||
LV_LOG_ERROR("mediumHand24hImg should be NULL here !");
|
||||
lv_obj_del(watchFace->mediumHand24h.handImg);
|
||||
watchFace->mediumHand24h.handImg = NULL;
|
||||
}
|
||||
|
||||
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(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.dateWindowWidget)
|
||||
{
|
||||
LV_LOG_ERROR("dateWindowWidget should be NULL here !");
|
||||
lv_obj_del(watchFace->dateWindow.dateWindowWidget);
|
||||
watchFace->dateWindow.dateWindowWidget = NULL;
|
||||
}
|
||||
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, 180,111);
|
||||
lv_obj_set_width(watchFace->dateWindow.dateWindowWidget, 20);
|
||||
lv_obj_set_style_text_align(watchFace->dateWindow.dateWindowWidget, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
|
||||
if(watchFace->hourHand.handImg)
|
||||
{
|
||||
LV_LOG_ERROR("hourHandImg should be NULL here !");
|
||||
lv_obj_del(watchFace->hourHand.handImg);
|
||||
watchFace->hourHand.handImg = NULL;
|
||||
}
|
||||
|
||||
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->minuteHand.handImg)
|
||||
{
|
||||
LV_LOG_ERROR("minuteHandImg should be NULL here !");
|
||||
lv_obj_del(watchFace->minuteHand.handImg);
|
||||
watchFace->minuteHand.handImg = NULL;
|
||||
}
|
||||
|
||||
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->secondHand.handImg)
|
||||
{
|
||||
LV_LOG_ERROR("secondHandImg should be NULL here !");
|
||||
lv_obj_del(watchFace->secondHand.handImg);
|
||||
watchFace->secondHand.handImg = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//Don't forget to make the background image clickable to be able to use gestures on it.
|
||||
lv_obj_add_flag(watchFace->display, LV_OBJ_FLAG_CLICKABLE);
|
||||
|
||||
//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;
|
||||
}
|
||||
watchFace->handAnimationTimer = lv_timer_create(&(hand_timer_anim_cb), 199, watchFace);
|
||||
|
||||
//We create the timer which refreshes the step counter indicator
|
||||
if(watchFace->stepCounterRefreshTimer)
|
||||
{
|
||||
LV_LOG_ERROR("stepCounterRefreshTimer should be NULL here !");
|
||||
lv_timer_del(watchFace->stepCounterRefreshTimer);
|
||||
watchFace->stepCounterRefreshTimer = NULL;
|
||||
}
|
||||
|
||||
watchFace->stepCounterRefreshTimer = lv_timer_create(&(step_counter_refresh_cb), 300, watchFace);
|
||||
}
|
||||
|
||||
void watch_face_set_battery_indicator(WatchFace_t * const watchFace, uint8_t levelInPercent, BatteryState_e batteryState)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!watchFace->display) return;
|
||||
|
||||
lv_color_t arc_color = lv_color_make(228, 233, 236);
|
||||
|
||||
if(levelInPercent <= 10)
|
||||
arc_color = lv_color_make(228, 33, 81);
|
||||
else if(levelInPercent <= 30)
|
||||
arc_color = lv_color_make(247, 148, 29);
|
||||
else if(levelInPercent <= 50)
|
||||
arc_color = lv_color_make(226, 175, 58);
|
||||
|
||||
lv_arc_set_value(watchFace->batteryIndicator.batteryArc, levelInPercent);
|
||||
lv_obj_set_style_arc_color(watchFace->batteryIndicator.batteryArc, arc_color, LV_PART_INDICATOR);
|
||||
sprintf(watchFace->batteryIndicator.text, "%u %%", levelInPercent);
|
||||
lv_label_set_text_static(watchFace->batteryIndicator.label, watchFace->batteryIndicator.text);
|
||||
lv_obj_align_to(watchFace->batteryIndicator.label, watchFace->batteryIndicator.batteryArc, LV_ALIGN_CENTER, 0, -5);
|
||||
|
||||
//We save the new battery state only if it's different, this allows to have a trigger when it changes :
|
||||
if(watchFace->batteryIndicator.batteryState != batteryState)
|
||||
{
|
||||
watchFace->batteryIndicator.batteryState = batteryState;
|
||||
set_battery_state_icon(watchFace);
|
||||
}
|
||||
|
||||
//Finally we check if it's time to show the battery low indicator by enabling it's timer
|
||||
if(levelInPercent <= 10 && watchFace->batteryIndicator.batteryState == BATTERY_STATE_DISCHARGING)
|
||||
{
|
||||
lv_timer_resume(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
}
|
||||
else if(watchFace->batteryIndicator.batteryState == BATTERY_STATE_DISCHARGING)
|
||||
{
|
||||
lv_timer_pause(watchFace->batteryIndicator.lowBatteryAnimationTimer);
|
||||
lv_obj_add_flag(watchFace->batteryIndicator.batteryIcon, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
void watch_face_set_bluetooth_indicator(WatchFace_t * const watchFace, BluetoothState_e bluetoothState)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
if(watchFace->bluetoothIndicator.bluetoothState == bluetoothState) return;
|
||||
|
||||
watchFace->bluetoothIndicator.bluetoothState = bluetoothState;
|
||||
|
||||
if(!watchFace->display) return;
|
||||
|
||||
_set_bluetooth_indicator(watchFace);
|
||||
}
|
||||
|
||||
void watch_face_set_step_count_indicator(WatchFace_t * const watchFace, uint32_t stepCount)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
if(stepCount < 1000)
|
||||
sprintf(watchFace->stepCounter.text, "%u", stepCount);
|
||||
else if(stepCount < 9996)
|
||||
sprintf(watchFace->stepCounter.text, "%.2fk", stepCount/1000.0);
|
||||
else
|
||||
sprintf(watchFace->stepCounter.text, "%.1fk", stepCount/1000.0);
|
||||
|
||||
if(!watchFace->display) return;
|
||||
|
||||
lv_label_set_text_static(watchFace->stepCounter.label, watchFace->stepCounter.text);
|
||||
}
|
||||
|
||||
void watch_face_destroy(WatchFace_t * const watchFace)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
watchFace->display = NULL;
|
||||
watchFace->handAnimationTimer = NULL;
|
||||
watchFace->stepCounterRefreshTimer = NULL;
|
||||
watchFace->dateWindow.dateWindowWidget = NULL;
|
||||
watchFace->hourHand.handImg = NULL;
|
||||
watchFace->minuteHand.handImg = NULL;
|
||||
watchFace->secondHand.handImg = NULL;
|
||||
watchFace->mediumHand24h.handImg = NULL;
|
||||
watchFace->batteryIndicator.batteryArc = NULL;
|
||||
watchFace->batteryIndicator.label = NULL;
|
||||
watchFace->batteryIndicator.batteryIcon = NULL;
|
||||
watchFace->batteryIndicator.lowBatteryAnimationTimer = NULL;
|
||||
watchFace->stepCounter.label = NULL;
|
||||
watchFace->bluetoothIndicator.bluetoothIcon = NULL;
|
||||
}
|
||||
|
||||
void watch_face_force_sync(WatchFace_t *const watchFace)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!watchFace->display) return;
|
||||
|
||||
update_watch_hands_angles(watchFace, 0);
|
||||
}
|
||||
|
||||
bool watch_face_is_in_use(WatchFace_t * const watchFace)
|
||||
{
|
||||
if(!watchFace)
|
||||
{
|
||||
LV_LOG_ERROR("NULL pointer given !");
|
||||
return false;
|
||||
}
|
||||
|
||||
return watchFace->display != NULL;
|
||||
}
|
Loading…
Reference in New Issue
Block a user