text/plain
•
5.79 KB
•
148 lines
#include "player_screen.h"
#include "../audio_player.h"
#include <stdlib.h>
#include <string.h>
static void cancel_event_cb(lv_event_t *e) {
(void)e;
audio_player_stop();
navigate_to(SCREEN_FILES);
}
static void play_btn_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
audio_state_t state = audio_player_get_state();
if (state == AUDIO_STATE_PLAYING) {
audio_player_pause();
} else if (state == AUDIO_STATE_PAUSED) {
audio_player_resume();
}
}
}
static void stop_btn_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
audio_player_stop();
navigate_to(SCREEN_FILES);
}
}
static void back_btn_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
audio_player_stop();
navigate_to(SCREEN_FILES);
}
}
ui_state_t setup_player_screen(void) {
player_screen_state_t *state = calloc(1, sizeof(player_screen_state_t));
// Main container
state->container = lv_obj_create(lv_screen_active());
lv_obj_set_size(state->container, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(state->container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(state->container, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(state->container, 8, 0);
lv_obj_set_style_pad_gap(state->container, 8, 0);
// Title - "Now Playing"
lv_obj_t *header = lv_label_create(state->container);
lv_label_set_text(header, "Now Playing");
lv_obj_set_style_text_color(header, lv_color_hex(0xE91E63), 0);
// Filename label
state->title_label = lv_label_create(state->container);
const char *filename = audio_player_get_filename();
lv_label_set_text(state->title_label, filename ? filename : "Unknown");
lv_label_set_long_mode(state->title_label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_width(state->title_label, LV_PCT(90));
// Status label
state->status_label = lv_label_create(state->container);
lv_label_set_text(state->status_label, LV_SYMBOL_PLAY " Playing");
lv_obj_set_style_text_color(state->status_label, lv_color_hex(0x4CAF50), 0);
// Button container
lv_obj_t *btn_cont = lv_obj_create(state->container);
lv_obj_set_size(btn_cont, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(btn_cont, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(btn_cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(btn_cont, 4, 0);
lv_obj_set_style_border_width(btn_cont, 0, 0);
lv_obj_set_style_bg_opa(btn_cont, LV_OPA_TRANSP, 0);
// Play/Pause button
state->play_btn = lv_button_create(btn_cont);
lv_obj_set_size(state->play_btn, 40, 40);
lv_obj_t *play_label = lv_label_create(state->play_btn);
lv_label_set_text(play_label, LV_SYMBOL_PAUSE);
lv_obj_center(play_label);
lv_obj_add_event_cb(state->play_btn, play_btn_cb, LV_EVENT_CLICKED, state);
lv_obj_add_event_cb(state->play_btn, cancel_event_cb, LV_EVENT_CANCEL, NULL);
lv_group_add_obj(lv_group_get_default(), state->play_btn);
// Stop button
state->stop_btn = lv_button_create(btn_cont);
lv_obj_set_size(state->stop_btn, 40, 40);
lv_obj_t *stop_label = lv_label_create(state->stop_btn);
lv_label_set_text(stop_label, LV_SYMBOL_STOP);
lv_obj_center(stop_label);
lv_obj_add_event_cb(state->stop_btn, stop_btn_cb, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(state->stop_btn, cancel_event_cb, LV_EVENT_CANCEL, NULL);
lv_group_add_obj(lv_group_get_default(), state->stop_btn);
// Back button
state->back_btn = lv_button_create(btn_cont);
lv_obj_set_size(state->back_btn, 40, 40);
lv_obj_t *back_label = lv_label_create(state->back_btn);
lv_label_set_text(back_label, LV_SYMBOL_LEFT);
lv_obj_center(back_label);
lv_obj_add_event_cb(state->back_btn, back_btn_cb, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(state->back_btn, cancel_event_cb, LV_EVENT_CANCEL, NULL);
lv_group_add_obj(lv_group_get_default(), state->back_btn);
// Focus play button by default
lv_group_focus_obj(state->play_btn);
return (ui_state_t){.type = SCREEN_PLAYER, .player = state};
}
void free_player_screen(player_screen_state_t *state) {
if (!state) return;
lv_group_remove_obj(state->play_btn);
lv_group_remove_obj(state->stop_btn);
lv_group_remove_obj(state->back_btn);
lv_obj_delete(state->container);
free(state);
}
void update_player_screen(player_screen_state_t *state) {
if (!state) return;
audio_state_t audio_state = audio_player_get_state();
// Update play/pause button icon
lv_obj_t *play_label = lv_obj_get_child(state->play_btn, 0);
if (audio_state == AUDIO_STATE_PLAYING) {
lv_label_set_text(play_label, LV_SYMBOL_PAUSE);
lv_label_set_text(state->status_label, LV_SYMBOL_PLAY " Playing");
lv_obj_set_style_text_color(state->status_label, lv_color_hex(0x4CAF50), 0);
} else if (audio_state == AUDIO_STATE_PAUSED) {
lv_label_set_text(play_label, LV_SYMBOL_PLAY);
lv_label_set_text(state->status_label, LV_SYMBOL_PAUSE " Paused");
lv_obj_set_style_text_color(state->status_label, lv_color_hex(0xFFA000), 0);
} else if (audio_state == AUDIO_STATE_ERROR) {
lv_label_set_text(play_label, LV_SYMBOL_PLAY);
lv_label_set_text(state->status_label, LV_SYMBOL_WARNING " Error: file too large");
lv_obj_set_style_text_color(state->status_label, lv_color_hex(0xF44336), 0);
} else {
lv_label_set_text(play_label, LV_SYMBOL_PLAY);
lv_label_set_text(state->status_label, LV_SYMBOL_STOP " Stopped");
lv_obj_set_style_text_color(state->status_label, lv_color_hex(0x757575), 0);
}
}