From 23f592bcc1d9a83bfb9e35ee16fdbedd4c4887b7 Mon Sep 17 00:00:00 2001 From: Th3maz1ng Date: Sun, 14 May 2023 22:09:43 +0200 Subject: [PATCH] Finally added the music player used to control the music playback of the phone through the BLE connection. It works great, some minor adjustements to do though. --- .../app/gfx/music_player_screen.c | 436 ++++++++++++++++++ .../app/gfx/music_player_screen.h | 78 ++++ 2 files changed, 514 insertions(+) create mode 100644 src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c create mode 100644 src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h diff --git a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c new file mode 100644 index 0000000..457d468 --- /dev/null +++ b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c @@ -0,0 +1,436 @@ +#include +#include +#include "music_player_screen.h" +#include "menu_screen.h" +#include "translation.h" + +void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected); + +static void gesture_event_cb(lv_event_t *e) +{ + MusicPlayerScreen_t *musicPlayerScreen = e->user_data; + + 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 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) +{ + MusicPlayerScreen_t *musicPlayerScreen = e->user_data; + music_player_screen_destroy(musicPlayerScreen); + LV_LOG_USER("cleanup"); +} + +static void music_player_button_click_event_cb(lv_event_t *e) +{ + MusicPlayerScreen_t *musicPlayerScreen = e->user_data; + MusicPlaybackCtrlAction_e action = (MusicPlaybackCtrlAction_e)lv_obj_get_user_data(e->target); + + LV_LOG_USER("Action is : %u, code is : %u", action, e->code); + if(musicPlayerScreen->musicPlaybackCtrlCb) + { + if(action == MUSIC_CONTROL_PLAY) + { + MusicPlaybackCtrlAction_e stateToApply = musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY ? MUSIC_CONTROL_PAUSE : MUSIC_CONTROL_PLAY; + musicPlayerScreen->musicPlaybackCtrlCb(stateToApply); + music_player_screen_set_music_playing_state(musicPlayerScreen, stateToApply); + } + else if(action == MUSIC_CONTROL_NEXT) + { + musicPlayerScreen->musicPlaybackCtrlCb(e->code == LV_EVENT_SHORT_CLICKED ? MUSIC_CONTROL_FORWARD : MUSIC_CONTROL_NEXT); + } + else if(action == MUSIC_CONTROL_PREVIOUS) + { + musicPlayerScreen->musicPlaybackCtrlCb(e->code == LV_EVENT_SHORT_CLICKED ? MUSIC_CONTROL_REWIND : MUSIC_CONTROL_PREVIOUS); + } + else + { + musicPlayerScreen->musicPlaybackCtrlCb(action); + } + } +} + +void music_player_screen_init(MusicPlayerScreen_t * const musicPlayerScreen) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + memset(musicPlayerScreen, 0, sizeof(MusicPlayerScreen_t)); + musicPlayerScreen->currentPlayState = MUSIC_CONTROL_PAUSE; +} + +void music_player_screen_register_music_playback_control_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlCb_t musicPlaybackCtrlCb) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + musicPlayerScreen->musicPlaybackCtrlCb = musicPlaybackCtrlCb; +} + +void music_player_screen_notify_BLE_connection_state(MusicPlayerScreen_t * const musicPlayerScreen, bool connected) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + if(musicPlayerScreen->ble_connection_state != connected) + { + musicPlayerScreen->ble_connection_state = connected; + if(musicPlayerScreen->display != NULL) + _set_UI_no_ble_connection(musicPlayerScreen, musicPlayerScreen->ble_connection_state); + } +} + +void music_player_screen_set_playing_music_title_and_artist(MusicPlayerScreen_t * const musicPlayerScreen, const char *title, const char *artist) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + if(title) + { + strncpy(musicPlayerScreen->titleText, title, sizeof musicPlayerScreen->titleText); + musicPlayerScreen->titleText[sizeof(musicPlayerScreen->titleText) - 1] = '\0'; + + if(musicPlayerScreen->titleLabel) + { + lv_label_set_text_static(musicPlayerScreen->titleLabel, musicPlayerScreen->titleText); + } + } + + if(artist) + { + strncpy(musicPlayerScreen->artistText, artist, sizeof musicPlayerScreen->artistText); + musicPlayerScreen->artistText[sizeof(musicPlayerScreen->artistText) - 1] = '\0'; + + if(musicPlayerScreen->artistLabel) + { + lv_label_set_text_static(musicPlayerScreen->artistLabel, musicPlayerScreen->artistText); + } + } +} + +void music_player_screen_set_music_duration(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t durationInSeconds) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + musicPlayerScreen->currentMusicDuration = durationInSeconds; + //If the widget is currently displayed, we update it as well ! + if(!musicPlayerScreen->playbackArc) return; + + lv_arc_set_range(musicPlayerScreen->playbackArc, 0, musicPlayerScreen->currentMusicDuration); + + if(durationInSeconds < 3600)sprintf(musicPlayerScreen->durationTimeLabel.text, "%s%u:%s%u", durationInSeconds / 60 < 10 ? "0":"", durationInSeconds / 60, durationInSeconds % 60 < 10 ? "0":"", durationInSeconds % 60); + else sprintf(musicPlayerScreen->durationTimeLabel.text, "%s%u:%s%u:%s%u", durationInSeconds / 3600 < 10 ? "0":"", durationInSeconds / 3600, + (durationInSeconds % 3600) / 60 < 10 ? "0":"", (durationInSeconds % 3600) / 60, + (durationInSeconds % 3600) % 60 < 10 ? "0":"", (durationInSeconds % 3600) % 60); + lv_label_set_text_static(musicPlayerScreen->durationTimeLabel.label, musicPlayerScreen->durationTimeLabel.text); +} + +void music_player_screen_set_music_position(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t positionInSeconds) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + if(positionInSeconds > musicPlayerScreen->currentMusicDuration) positionInSeconds = musicPlayerScreen->currentMusicDuration; + + musicPlayerScreen->currentMusicPosition = positionInSeconds; + //If the widget is currently displayed, we update it as well ! + if(!musicPlayerScreen->playbackArc) return; + + lv_arc_set_value(musicPlayerScreen->playbackArc, musicPlayerScreen->currentMusicPosition); + + if(positionInSeconds < 3600)sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u", positionInSeconds / 60 < 10 ? "0":"", positionInSeconds / 60, positionInSeconds % 60 < 10 ? "0":"", positionInSeconds % 60); + else sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u:%s%u", positionInSeconds / 3600 < 10 ? "0":"", positionInSeconds / 3600, + (positionInSeconds % 3600) / 60 < 10 ? "0":"", (positionInSeconds % 3600) / 60, + (positionInSeconds % 3600) % 60 < 10 ? "0":"", (positionInSeconds % 3600) % 60); + lv_label_set_text_static(musicPlayerScreen->positionTimeLabel.label, musicPlayerScreen->positionTimeLabel.text); +} + +void music_player_screen_set_music_playing_state(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlAction_e playingState) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + if(musicPlayerScreen->currentPlayState == playingState) return; + if(playingState != MUSIC_CONTROL_PAUSE && playingState != MUSIC_CONTROL_PLAY) return; + + musicPlayerScreen->currentPlayState = playingState; + + if(!musicPlayerScreen->playPauseBtn.label) return; + + strcpy(musicPlayerScreen->playPauseBtn.icon, musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY ? LV_SYMBOL_PAUSE : LV_SYMBOL_PLAY); + lv_label_set_text_static(musicPlayerScreen->playPauseBtn.label, musicPlayerScreen->playPauseBtn.icon); +} + +bool music_player_screen_is_in_use(MusicPlayerScreen_t * const musicPlayerScreen) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return false; + } + + return musicPlayerScreen->display != NULL; +} + +void music_player_screen_create(MusicPlayerScreen_t * const musicPlayerScreen) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + if(musicPlayerScreen->display) + { + LV_LOG_ERROR("display should be NULL here !"); + lv_obj_del(musicPlayerScreen->display); + musicPlayerScreen->display = NULL; + } + musicPlayerScreen->display = lv_obj_create(NULL); + lv_obj_set_style_bg_color(musicPlayerScreen->display, lv_color_white(), LV_PART_MAIN); + lv_obj_clear_flag(musicPlayerScreen->display, LV_OBJ_FLAG_SCROLLABLE); + + //Black circled background + lv_obj_t *blackCircle = lv_obj_create(musicPlayerScreen->display); + lv_obj_set_style_bg_color(blackCircle, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(blackCircle, 0, LV_PART_MAIN); + lv_obj_set_style_pad_all(blackCircle, 0, LV_PART_MAIN); + lv_obj_set_style_radius(blackCircle, LV_RADIUS_CIRCLE, LV_PART_MAIN); + //The +1 to the hor and ver res is used to get rid of graphical issue... (1px white background bleeding on the black one) + lv_obj_set_size(blackCircle, lv_disp_get_ver_res(NULL)+1, lv_disp_get_hor_res(NULL)+1); + lv_obj_center(blackCircle); + + //Let's create the UI for this amazing music player ... + //Play/Pause button + if(musicPlayerScreen->playPauseBtn.button) + { + LV_LOG_ERROR("playPauseBtn should be NULL here !"); + lv_obj_del(musicPlayerScreen->playPauseBtn.button); + musicPlayerScreen->playPauseBtn.button = NULL; + } + musicPlayerScreen->playPauseBtn.button = lv_btn_create(musicPlayerScreen->display); + lv_obj_set_size(musicPlayerScreen->playPauseBtn.button, 60, 60); + lv_obj_set_style_radius(musicPlayerScreen->playPauseBtn.button, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_align(musicPlayerScreen->playPauseBtn.button, LV_ALIGN_BOTTOM_MID, 0, -80); + + musicPlayerScreen->playPauseBtn.label = lv_label_create(musicPlayerScreen->playPauseBtn.button); + strcpy(musicPlayerScreen->playPauseBtn.icon, musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY ? LV_SYMBOL_PAUSE : LV_SYMBOL_PLAY); + lv_label_set_text_static(musicPlayerScreen->playPauseBtn.label, musicPlayerScreen->playPauseBtn.icon); + lv_obj_set_style_text_font(musicPlayerScreen->playPauseBtn.label, &lv_font_montserrat_30, LV_PART_MAIN); + lv_obj_center(musicPlayerScreen->playPauseBtn.label); + + lv_obj_set_user_data(musicPlayerScreen->playPauseBtn.button, MUSIC_CONTROL_PLAY); + lv_obj_add_event_cb(musicPlayerScreen->playPauseBtn.button, &(music_player_button_click_event_cb), LV_EVENT_CLICKED, musicPlayerScreen); + + //Previous track button + musicPlayerScreen->previousBtn = lv_btn_create(musicPlayerScreen->display); + lv_obj_set_size(musicPlayerScreen->previousBtn, 47, 47); + lv_obj_set_style_radius(musicPlayerScreen->previousBtn, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_align_to(musicPlayerScreen->previousBtn, musicPlayerScreen->playPauseBtn.label, LV_ALIGN_OUT_LEFT_MID, -25, 0); + + lv_obj_t *previousBtnLabel = lv_label_create(musicPlayerScreen->previousBtn); + lv_label_set_text_static(previousBtnLabel, LV_SYMBOL_LEFT LV_SYMBOL_LEFT); + lv_obj_set_style_text_font(previousBtnLabel, &lv_font_montserrat_24, LV_PART_MAIN); + lv_obj_center(previousBtnLabel); + + lv_obj_set_user_data(musicPlayerScreen->previousBtn, (void *)MUSIC_CONTROL_PREVIOUS); + lv_obj_add_event_cb(musicPlayerScreen->previousBtn, &(music_player_button_click_event_cb), LV_EVENT_SHORT_CLICKED, musicPlayerScreen); + lv_obj_add_event_cb(musicPlayerScreen->previousBtn, &(music_player_button_click_event_cb), LV_EVENT_LONG_PRESSED, musicPlayerScreen); + + //Next track button + musicPlayerScreen->nextBtn = lv_btn_create(musicPlayerScreen->display); + lv_obj_set_size(musicPlayerScreen->nextBtn, 47, 47); + lv_obj_set_style_radius(musicPlayerScreen->nextBtn, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_align_to(musicPlayerScreen->nextBtn, musicPlayerScreen->playPauseBtn.label, LV_ALIGN_OUT_RIGHT_MID, 25, 0); + + lv_obj_t *nextBtnLabel = lv_label_create(musicPlayerScreen->nextBtn); + lv_label_set_text_static(nextBtnLabel, LV_SYMBOL_RIGHT LV_SYMBOL_RIGHT); + lv_obj_set_style_text_font(nextBtnLabel, &lv_font_montserrat_24, LV_PART_MAIN); + lv_obj_center(nextBtnLabel); + + lv_obj_set_user_data(musicPlayerScreen->nextBtn, (void *)MUSIC_CONTROL_NEXT); + lv_obj_add_event_cb(musicPlayerScreen->nextBtn, &(music_player_button_click_event_cb), LV_EVENT_SHORT_CLICKED, musicPlayerScreen); + lv_obj_add_event_cb(musicPlayerScreen->nextBtn, &(music_player_button_click_event_cb), LV_EVENT_LONG_PRESSED, musicPlayerScreen); + + //Volume down button + musicPlayerScreen->volumeDownBtn = lv_btn_create(musicPlayerScreen->display); + lv_obj_set_size(musicPlayerScreen->volumeDownBtn, 47, 47); + lv_obj_set_style_radius(musicPlayerScreen->volumeDownBtn, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_align_to(musicPlayerScreen->volumeDownBtn, musicPlayerScreen->previousBtn, LV_ALIGN_BOTTOM_MID, 25, 50); + + lv_obj_t *volumeDownBtnLabel = lv_label_create(musicPlayerScreen->volumeDownBtn); + lv_label_set_text_static(volumeDownBtnLabel, LV_SYMBOL_VOLUME_MID); + lv_obj_set_style_text_font(volumeDownBtnLabel, &lv_font_montserrat_24, LV_PART_MAIN); + lv_obj_center(volumeDownBtnLabel); + + lv_obj_set_user_data(musicPlayerScreen->volumeDownBtn, (void *)MUSIC_CONTROL_VOLUMEDOWN); + lv_obj_add_event_cb(musicPlayerScreen->volumeDownBtn, &(music_player_button_click_event_cb), LV_EVENT_CLICKED, musicPlayerScreen); + + //Volume up button + musicPlayerScreen->volumeUpBtn = lv_btn_create(musicPlayerScreen->display); + lv_obj_set_size(musicPlayerScreen->volumeUpBtn, 47, 47); + lv_obj_set_style_radius(musicPlayerScreen->volumeUpBtn, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_align_to(musicPlayerScreen->volumeUpBtn, musicPlayerScreen->nextBtn, LV_ALIGN_BOTTOM_MID, -25, 50); + + lv_obj_t *volumeUpBtnLabel = lv_label_create(musicPlayerScreen->volumeUpBtn); + lv_label_set_text_static(volumeUpBtnLabel, LV_SYMBOL_VOLUME_MAX); + lv_obj_set_style_text_font(volumeUpBtnLabel, &lv_font_montserrat_24, LV_PART_MAIN); + lv_obj_center(volumeUpBtnLabel); + + lv_obj_set_user_data(musicPlayerScreen->volumeUpBtn, (void *)MUSIC_CONTROL_VOLUMEUP); + lv_obj_add_event_cb(musicPlayerScreen->volumeUpBtn, &(music_player_button_click_event_cb), LV_EVENT_CLICKED, musicPlayerScreen); + + //Track title + if(musicPlayerScreen->titleLabel) + { + LV_LOG_ERROR("titleLabel should be NULL here !"); + lv_obj_del(musicPlayerScreen->titleLabel); + musicPlayerScreen->titleLabel = NULL; + } + musicPlayerScreen->titleLabel = lv_label_create(musicPlayerScreen->display); + lv_label_set_text_static(musicPlayerScreen->titleLabel, musicPlayerScreen->titleText); + lv_obj_set_style_text_color(musicPlayerScreen->titleLabel, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_font(musicPlayerScreen->titleLabel, &lv_font_montserrat_28, LV_PART_MAIN); + lv_obj_set_width(musicPlayerScreen->titleLabel, 200); + lv_obj_align(musicPlayerScreen->titleLabel, LV_ALIGN_TOP_MID, 0, 40); + lv_obj_set_style_text_align(musicPlayerScreen->titleLabel, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_label_set_long_mode(musicPlayerScreen->titleLabel, LV_LABEL_LONG_SCROLL_CIRCULAR); + + //Track artist + if(musicPlayerScreen->artistLabel) + { + LV_LOG_ERROR("artistLabel should be NULL here !"); + lv_obj_del(musicPlayerScreen->artistLabel); + musicPlayerScreen->artistLabel = NULL; + } + musicPlayerScreen->artistLabel = lv_label_create(musicPlayerScreen->display); + lv_label_set_text_static(musicPlayerScreen->artistLabel, musicPlayerScreen->artistText); + lv_obj_set_style_text_color(musicPlayerScreen->artistLabel, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_font(musicPlayerScreen->artistLabel, &lv_font_montserrat_16, LV_PART_MAIN); + lv_obj_set_size(musicPlayerScreen->artistLabel, 150, 20); + lv_obj_align_to(musicPlayerScreen->artistLabel, musicPlayerScreen->titleLabel, LV_ALIGN_BOTTOM_MID, 0, 25); + lv_obj_set_style_text_align(musicPlayerScreen->artistLabel, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_label_set_long_mode(musicPlayerScreen->artistLabel, LV_LABEL_LONG_SCROLL_CIRCULAR); + + //Track playback labels + if(musicPlayerScreen->durationTimeLabel.label) + { + LV_LOG_ERROR("durationTimeLabel should be NULL here !"); + lv_obj_del(musicPlayerScreen->durationTimeLabel.label); + musicPlayerScreen->durationTimeLabel.label = NULL; + } + musicPlayerScreen->durationTimeLabel.label = lv_label_create(musicPlayerScreen->display); + lv_obj_set_style_text_color(musicPlayerScreen->durationTimeLabel.label, lv_color_white(), LV_PART_MAIN); + lv_obj_align(musicPlayerScreen->durationTimeLabel.label, LV_ALIGN_BOTTOM_RIGHT, -60, -20); + + if(musicPlayerScreen->positionTimeLabel.label) + { + LV_LOG_ERROR("positionTimeLabel should be NULL here !"); + lv_obj_del(musicPlayerScreen->positionTimeLabel.label); + musicPlayerScreen->positionTimeLabel.label = NULL; + } + musicPlayerScreen->positionTimeLabel.label = lv_label_create(musicPlayerScreen->display); + lv_obj_set_style_text_color(musicPlayerScreen->positionTimeLabel.label, lv_color_white(), LV_PART_MAIN); + lv_obj_align(musicPlayerScreen->positionTimeLabel.label, LV_ALIGN_BOTTOM_LEFT, 60, -20); + + //Track playback cursor + if(musicPlayerScreen->playbackArc) + { + LV_LOG_ERROR("playbackArc should be NULL here !"); + lv_obj_del(musicPlayerScreen->playbackArc); + musicPlayerScreen->playbackArc = NULL; + } + musicPlayerScreen->playbackArc = lv_arc_create(musicPlayerScreen->display); + lv_obj_remove_style(musicPlayerScreen->playbackArc, NULL, LV_PART_KNOB); + lv_obj_clear_flag(musicPlayerScreen->playbackArc, LV_OBJ_FLAG_CLICKABLE); + lv_obj_align(musicPlayerScreen->playbackArc, LV_ALIGN_CENTER, 0,0); + lv_obj_set_size(musicPlayerScreen->playbackArc, 240, 240); + lv_obj_set_style_arc_color(musicPlayerScreen->playbackArc, lv_palette_main(LV_PALETTE_LIME), LV_PART_INDICATOR); + music_player_screen_set_music_duration(musicPlayerScreen, musicPlayerScreen->currentMusicDuration); + music_player_screen_set_music_position(musicPlayerScreen, musicPlayerScreen->currentMusicPosition); + + _set_UI_no_ble_connection(musicPlayerScreen, musicPlayerScreen->ble_connection_state); + + + //We register the event callback to handle gestures + lv_obj_add_event_cb(musicPlayerScreen->display, &(gesture_event_cb), LV_EVENT_GESTURE, musicPlayerScreen); + //We register the event callback to handle the cleanup + lv_obj_add_event_cb(musicPlayerScreen->display, &(cleanup_event_cb), LV_EVENT_DELETE, musicPlayerScreen); +} + +void music_player_screen_destroy(MusicPlayerScreen_t * const musicPlayerScreen) +{ + if(!musicPlayerScreen) + { + LV_LOG_ERROR("NULL pointer given !"); + return; + } + + memset(musicPlayerScreen, 0, offsetof(MusicPlayerScreen_t, musicPlaybackCtrlCb)); +} + +void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected) +{ + if(connected) + { + lv_obj_clear_state(musicPlayerScreen->playPauseBtn.button, LV_STATE_DISABLED); + lv_obj_clear_state(musicPlayerScreen->previousBtn, LV_STATE_DISABLED); + lv_obj_clear_state(musicPlayerScreen->nextBtn, LV_STATE_DISABLED); + lv_obj_clear_state(musicPlayerScreen->volumeDownBtn, LV_STATE_DISABLED); + lv_obj_clear_state(musicPlayerScreen->volumeUpBtn, LV_STATE_DISABLED); + lv_label_set_text_static(musicPlayerScreen->titleLabel, musicPlayerScreen->titleText); + lv_obj_clear_flag(musicPlayerScreen->artistLabel, LV_OBJ_FLAG_HIDDEN); + } + else + { + lv_obj_add_state(musicPlayerScreen->playPauseBtn.button, LV_STATE_DISABLED); + lv_obj_add_state(musicPlayerScreen->previousBtn, LV_STATE_DISABLED); + lv_obj_add_state(musicPlayerScreen->nextBtn, LV_STATE_DISABLED); + lv_obj_add_state(musicPlayerScreen->volumeDownBtn, LV_STATE_DISABLED); + lv_obj_add_state(musicPlayerScreen->volumeUpBtn, LV_STATE_DISABLED); + lv_label_set_text_static(musicPlayerScreen->titleLabel, translation_get_word(TRANSLATION_PHONE_NOT_CONNECTED_2)); + lv_obj_set_style_bg_color(musicPlayerScreen->titleLabel, lv_color_black(), LV_PART_MAIN); + lv_obj_add_flag(musicPlayerScreen->artistLabel, LV_OBJ_FLAG_HIDDEN); + } +} diff --git a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h new file mode 100644 index 0000000..60154f2 --- /dev/null +++ b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h @@ -0,0 +1,78 @@ +#ifndef MUSIC_PLAYER_SCREEN_H +#define MUSIC_PLAYER_SCREEN_H + +#include "lvgl.h" + +typedef enum MusicPlaybackCtrlAction +{ + MUSIC_CONTROL_PLAY = 0, + MUSIC_CONTROL_PAUSE, + MUSIC_CONTROL_PLAYPAUSE, + MUSIC_CONTROL_NEXT, + MUSIC_CONTROL_PREVIOUS, + MUSIC_CONTROL_VOLUMEUP, + MUSIC_CONTROL_VOLUMEDOWN, + MUSIC_CONTROL_FORWARD, + MUSIC_CONTROL_REWIND, +} MusicPlaybackCtrlAction_e; + +typedef void (*MusicPlaybackCtrlCb_t)(MusicPlaybackCtrlAction_e musicPlaybackCtrlAction); + +typedef struct PlayerButton +{ + lv_obj_t *button; + lv_obj_t *label; + char icon[4]; +} PlayerButton_t; + +typedef struct TimeLabel +{ + lv_obj_t *label; + char text[9]; +} TimeLabel_t; + +typedef struct MusicPlayerScreen +{ + //Can be erased attributes + lv_obj_t *display; + PlayerButton_t playPauseBtn; + lv_obj_t *previousBtn; + lv_obj_t *nextBtn; + lv_obj_t *volumeDownBtn; + lv_obj_t *volumeUpBtn; + + lv_obj_t *playbackArc; + lv_obj_t *titleLabel; + lv_obj_t *artistLabel; + TimeLabel_t positionTimeLabel, durationTimeLabel; + //Should not be erased attributes + MusicPlaybackCtrlCb_t musicPlaybackCtrlCb; + MusicPlaybackCtrlAction_e currentPlayState; + char titleText[60]; + char artistText[30]; + uint16_t currentMusicDuration; //The currently playing music's total duration in seconds. + uint16_t currentMusicPosition; //The currently playing music's cursor position in seconds. + bool ble_connection_state; +} MusicPlayerScreen_t; + +void music_player_screen_init(MusicPlayerScreen_t * const musicPlayerScreen); + +void music_player_screen_register_music_playback_control_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlCb_t musicPlaybackCtrlCb); + +void music_player_screen_notify_BLE_connection_state(MusicPlayerScreen_t * const musicPlayerScreen, bool connected); + +void music_player_screen_set_playing_music_title_and_artist(MusicPlayerScreen_t * const musicPlayerScreen, const char *title, const char *artist); + +void music_player_screen_set_music_duration(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t durationInSeconds); + +void music_player_screen_set_music_position(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t positionInSeconds); + +void music_player_screen_set_music_playing_state(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlAction_e playingState); + +bool music_player_screen_is_in_use(MusicPlayerScreen_t * const musicPlayerScreen); + +void music_player_screen_create(MusicPlayerScreen_t * const musicPlayerScreen); + +void music_player_screen_destroy(MusicPlayerScreen_t * const musicPlayerScreen); + +#endif // MUSIC_PLAYER_SCREEN_H