diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.cbp b/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.cbp
index 364f89c..53687bd 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.cbp
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.cbp
@@ -1657,6 +1657,10 @@
+
+
+
+
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.layout b/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.layout
index c390201..68da4bc 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.layout
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/LittlevGL.layout
@@ -2,339 +2,9 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -342,19 +12,44 @@
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -362,9 +57,139 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -376,19 +201,169 @@
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -416,79 +391,24 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
@@ -496,24 +416,114 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 b955f67..1ad164b 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/main.c
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/main.c
@@ -23,6 +23,7 @@
#include "altimeter_screen.h"
#include "find_my_phone_screen.h"
#include "music_player_screen.h"
+#include "notification_screen.h"
/*********************
@@ -97,6 +98,7 @@ SettingsScreen_t settingsScreen;
AltimeterScreen_t altimeterScreen;
FindMyPhoneScreen_t findMyPhoneScreen;
MusicPlayerScreen_t musicPlayerScreen;
+NotificationScreen_t notificationScreen;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
{
@@ -123,6 +125,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLi
compass_screen_init(&compassScreen);
settings_screen_init(&settingsScreen);
altimeter_screen_init(&altimeterScreen);
+ notification_screen_init(¬ificationScreen);
find_my_phone_screen_init(&findMyPhoneScreen);
find_my_phone_screen_register_BLE_command_send_cb(&findMyPhoneScreen, &(sendMyFindPhoneBLECommandCb));
find_my_phone_screen_notify_BLE_connection_state(&findMyPhoneScreen, true);
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/music_player_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/music_player_screen.c
index d3193f4..abd4c93 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/music_player_screen.c
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/music_player_screen.c
@@ -6,7 +6,7 @@
static void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected);
static void _update_playing_track_visuals(MusicPlayerScreen_t * const musicPlayerScreen);
static void _update_playing_track_ref_time(MusicPlayerScreen_t * const musicPlayerScreen);
-static uint16_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs);
+static uint32_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs);
static void gesture_event_cb(lv_event_t *e)
{
@@ -218,6 +218,9 @@ void music_player_screen_set_music_position(MusicPlayerScreen_t * const musicPla
positionInSeconds = positionInSeconds > musicPlayerScreen->currentMusicDuration ? musicPlayerScreen->currentMusicDuration : positionInSeconds;
musicPlayerScreen->currentMusicPosition = positionInSeconds * 1000;
+ //Don't forget to reset the time reference
+ if(musicPlayerScreen->musicPlayerTimeRefmsCb)musicPlayerScreen->playerStartTimeRef = musicPlayerScreen->musicPlayerTimeRefmsCb();
+
//Let's update the current music position visually
if(music_player_screen_is_in_use(musicPlayerScreen))
{
@@ -512,14 +515,14 @@ static void _update_playing_track_ref_time(MusicPlayerScreen_t * const musicPlay
{
//Let's compute the time that has passed and update the current song position
uint32_t currentTimeMs = musicPlayerScreen->musicPlayerTimeRefmsCb ? musicPlayerScreen->musicPlayerTimeRefmsCb() : 0;
- uint16_t timeDifferenceMs = _time_difference_in_ms(musicPlayerScreen->playerStartTimeRef, currentTimeMs);
+ uint32_t timeDifferenceMs = _time_difference_in_ms(musicPlayerScreen->playerStartTimeRef, currentTimeMs);
musicPlayerScreen->playerStartTimeRef = currentTimeMs;
musicPlayerScreen->currentMusicPosition = musicPlayerScreen->currentMusicPosition + timeDifferenceMs > musicPlayerScreen->currentMusicDuration * 1000 ?
musicPlayerScreen->currentMusicDuration * 1000 : musicPlayerScreen->currentMusicPosition + timeDifferenceMs;
}
-static uint16_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs)
+static uint32_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs)
{
return currentTimeMs - referenceTimeMs;
}
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.c
new file mode 100644
index 0000000..e1bc326
--- /dev/null
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.c
@@ -0,0 +1,140 @@
+#include
+#include "notification_screen.h"
+
+bool _notification_list_is_empty(NotificationList_t notificationList);
+
+void _notification_list_add_head(NotificationList_t *notificationList, Notification_t *notification);
+
+Notification_t *_notification_list_remove_tail(NotificationList_t *notificationList);
+
+uint8_t _notification_list_count(NotificationList_t notificationList);
+
+void _notification_list_debug(NotificationList_t notificationList);
+
+void notification_screen_init(NotificationScreen_t * const notificationScreen)
+{
+ if(!notificationScreen)
+ {
+ LV_LOG_ERROR("NULL pointer given !");
+ return;
+ }
+
+ //Let's initialize the list of free notifications from the pool
+ for(uint8_t i = 0; i < MAX_NOTIFICATIONS_COUNT; i++)
+ _notification_list_add_head(¬ificationScreen->freeNotificationList, notificationScreen->notificationPool + i);
+
+ notification_screen_notify(notificationScreen, 42, NOTIFICATION_TYPE_UNKNOWN, NULL, NULL);
+}
+
+void notification_screen_notify(NotificationScreen_t * const notificationScreen, uint32_t handle, NotificationType_e notificationType, char * title, char * body)
+{
+ if(!notificationScreen)
+ {
+ LV_LOG_ERROR("NULL pointer given !");
+ return;
+ }
+
+ Notification_t *notification = NULL;
+
+ //We try to get a notification from the free list.
+ if((notification = _notification_list_remove_tail(¬ificationScreen->freeNotificationList)) == NULL)
+ {
+ //If that fails, we reuse the oldest notification from the used list.
+ if((notification = _notification_list_remove_tail(¬ificationScreen->notificationList)) == NULL)
+ {
+ //That's bad
+ LV_LOG_ERROR("Unable to find a notification to reuse !");
+ return;
+ }
+
+ //Don't forget to free the allocated strings if not already done
+ free(notification->title);
+ free(notification->body);
+ }
+
+ notification->handle = handle;
+ notification->type = notificationType;
+ notification->title = title;
+ notification->body = body;
+
+ _notification_list_add_head(¬ificationScreen->notificationList, notification);
+
+ //Create and display a graphical widget containing the notification
+ lv_obj_t *notification_display = lv_layer_sys();
+
+ if(!notification_display)
+ {
+ LV_LOG_ERROR("Could not retrieve sys layer !");
+ return;
+ }
+ /*lv_obj_t *obj = lv_obj_create(notification_display);
+ lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN);
+ lv_obj_set_height(obj, lv_disp_get_hor_res(NULL)/2);
+ lv_obj_set_style_bg_opa(notification_display, 255, LV_PART_MAIN);*/
+}
+
+bool _notification_list_is_empty(NotificationList_t notificationList)
+{
+ return notificationList == NULL;
+}
+
+void _notification_list_add_head(NotificationList_t *notificationList, Notification_t *notification)
+{
+ if(!notificationList || !notification) return;
+
+ if(_notification_list_is_empty(*notificationList))
+ *notificationList = notification;
+ else
+ {
+ notification->next = *notificationList;
+ *notificationList = notification;
+ }
+}
+
+Notification_t *_notification_list_remove_tail(NotificationList_t *notificationList)
+{
+ if(!notificationList) return NULL;
+
+ if(_notification_list_is_empty(*notificationList)) return NULL;
+
+ Notification_t *toReturn = NULL;
+
+ //There is only one item in the list
+ if((*notificationList)->next == NULL)
+ {
+ toReturn = *notificationList;
+ *notificationList = NULL;
+ return toReturn;
+ }
+
+ NotificationList_t cursor = *notificationList;
+ while(!_notification_list_is_empty(cursor->next->next))
+ {
+ cursor = cursor->next;
+ }
+
+ toReturn = cursor->next;
+ cursor->next = NULL;
+ return toReturn;
+}
+
+uint8_t _notification_list_count(NotificationList_t notificationList)
+{
+ uint8_t count = 0;
+ while(!_notification_list_is_empty(notificationList))
+ {
+ notificationList = notificationList->next;
+ count++;
+ }
+
+ return count;
+}
+
+void _notification_list_debug(NotificationList_t notificationList)
+{
+ while(!_notification_list_is_empty(notificationList))
+ {
+ LV_LOG_USER("Notification handle :%u", notificationList->handle);
+ notificationList = notificationList->next;
+ }
+}
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.h b/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.h
new file mode 100644
index 0000000..a8e75f2
--- /dev/null
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/notification_screen.h
@@ -0,0 +1,45 @@
+#ifndef NOTIFICATION_SCREEN_H
+
+#include "lvgl.h"
+
+#define MAX_NOTIFICATIONS_COUNT (10) //The maximum number of notifications which will be stored before the oldest one gets discarded.
+
+typedef enum NotificationType
+{
+ NOTIFICATION_TYPE_SMS = 0,
+ NOTIFICATION_TYPE_EMAIL,
+ NOTIFICATION_TYPE_WHATSAPP,
+ NOTIFICATION_TYPE_GADGET_BRIDGE,
+ NOTIFICATION_TYPE_UNKNOWN,
+} NotificationType_e;
+
+typedef struct Notification
+{
+ struct Notification *next;
+ uint32_t handle;
+ NotificationType_e type;
+ char *title;
+ char *body;
+} Notification_t, *NotificationList_t;
+
+typedef struct NotificationScreen
+{
+ //Can be erased attributes
+ lv_obj_t *display;
+
+ //Should not be erased attributes
+ Notification_t notificationPool[MAX_NOTIFICATIONS_COUNT];
+ NotificationList_t notificationList; //Actual notifications
+ NotificationList_t freeNotificationList; //Free notiffication object pool
+
+} NotificationScreen_t;
+
+void notification_screen_init(NotificationScreen_t * const notificationScreen);
+
+void notification_screen_notify(NotificationScreen_t * const notificationScreen, uint32_t handle, NotificationType_e notificationType, char * title, char * body);
+
+void notification_screen_create(NotificationScreen_t * const notificationScreen);
+
+void notification_screen_destroy(NotificationScreen_t * const notificationScreen);
+
+#endif // NOTIFICATION_SCREEN_H
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.c
index 08ddda0..b0bf766 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.c
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.c
@@ -582,7 +582,7 @@ void settings_screen_create(SettingsScreen_t * const settingsScreen)
lv_obj_set_style_radius(menu_list, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(menu_list, 0, LV_PART_MAIN);
lv_obj_set_style_pad_right(menu_list, 0, LV_PART_MAIN);
- lv_obj_set_style_pad_left(menu_list, 7, LV_PART_MAIN);
+ lv_obj_set_style_pad_left(menu_list, 0, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(menu_list, 50, LV_PART_MAIN);
//We add the side screen containing the settings
@@ -628,21 +628,25 @@ void settings_screen_destroy(SettingsScreen_t * const settingsScreen)
settingsScreen->year_roller = NULL;
settingsScreen->display = NULL;
settingsScreen->about_refresh_timer = NULL;
+ settingsScreen->last_selected_item = NULL;
}
static void _simulate_side_screen_item_click(SettingsScreen_t * const settingsScreen, lv_obj_t *item)
{
- static lv_obj_t *last_target = NULL;
+ if(settingsScreen->last_selected_item == item) return;
- if(last_target == item) return;
-
- if(last_target == settingsScreen->about_item)
+ if(settingsScreen->last_selected_item == settingsScreen->about_item)
{
lv_timer_del(settingsScreen->about_refresh_timer);
settingsScreen->about_refresh_timer = NULL;
}
- last_target = item;
+ //Updating the background of the selected category
+ lv_obj_set_style_bg_color(item, lv_color_make(178, 223, 219), LV_PART_MAIN);
+ if(settingsScreen->last_selected_item)
+ lv_obj_set_style_bg_color(settingsScreen->last_selected_item, lv_color_white(), LV_PART_MAIN);
+
+ settingsScreen->last_selected_item = item;
if(item == settingsScreen->time_and_date_item)
{
@@ -712,8 +716,9 @@ static lv_obj_t *add_menu_list_item(lv_obj_t *list, const char *text, lv_event_c
lv_obj_t *label = lv_obj_get_child(btn, 0);
if(label)
{
- lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_set_style_pad_right(btn, 0, LV_PART_MAIN);
+ lv_obj_set_style_pad_left(label, 7, LV_PART_MAIN);
+ lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
}
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, user_data);
diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.h b/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.h
index ab7053b..6d4dd79 100644
--- a/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.h
+++ b/src/lvgl_win_sim/lv_port_win_codeblocks/settings_screen.h
@@ -18,6 +18,8 @@ typedef struct SettingsScreen
lv_obj_t *connectivity_item;
lv_obj_t *language_item;
lv_obj_t *about_item;
+ /* Remember the last clicked item needed for the background color logic */
+ lv_obj_t *last_selected_item;
lv_obj_t *side_screen;