diff --git a/Apps/ReynaBot/main/Source/main.c b/Apps/ReynaBot/main/Source/main.c index c1882b6..717a3f3 100644 --- a/Apps/ReynaBot/main/Source/main.c +++ b/Apps/ReynaBot/main/Source/main.c @@ -47,6 +47,8 @@ typedef struct { lv_obj_t* lbl_response; lv_obj_t* btn_ptt; lv_obj_t* btn_ptt_label; + lv_obj_t* btn_grace; + lv_obj_t* btn_elias; // PTT control bool is_pressed; @@ -273,6 +275,39 @@ static void reynabot_rx_task(void* arg) { vTaskDelete(NULL); } +/* ─── UI Speaker Selection Event Callback ─── */ +static void speaker_event_cb(lv_event_t* e) { + ReynaBotCtx* ctx = (ReynaBotCtx*)lv_event_get_user_data(e); + lv_obj_t* target = lv_event_get_target(e); + lv_event_code_t code = lv_event_get_code(e); + + if (code == LV_EVENT_CLICKED) { + if (target == ctx->btn_grace) { + strcpy(ctx->device_id, "grace-esp32"); + // Grace active styling + lv_obj_set_style_bg_color(ctx->btn_grace, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_grace, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_grace, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + // Elias inactive styling + lv_obj_set_style_bg_color(ctx->btn_elias, lv_color_hex(0x1C1B22), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_elias, lv_color_hex(0x2D2B36), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_elias, lv_color_hex(0x9E9E9E), LV_PART_MAIN); + } else if (target == ctx->btn_elias) { + strcpy(ctx->device_id, "elias-esp32"); + // Elias active styling + lv_obj_set_style_bg_color(ctx->btn_elias, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_elias, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_elias, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + // Grace inactive styling + lv_obj_set_style_bg_color(ctx->btn_grace, lv_color_hex(0x1C1B22), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_grace, lv_color_hex(0x2D2B36), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_grace, lv_color_hex(0x9E9E9E), LV_PART_MAIN); + } + } +} + /* ─── UI Press-to-Talk Event Callback ─── */ static void ptt_event_cb(lv_event_t* e) { ReynaBotCtx* ctx = (ReynaBotCtx*)lv_event_get_user_data(e); @@ -597,6 +632,57 @@ static void on_show(AppHandle app, void* data, lv_obj_t* parent) { lv_obj_add_flag(ctx->lbl_status, LV_OBJ_FLAG_FLOATING); lv_obj_align(ctx->lbl_status, LV_ALIGN_RIGHT_MID, -10, 0); lv_obj_set_style_text_color(ctx->lbl_status, lv_color_hex(0x9E9E9E), LV_PART_MAIN); + + // Default to Grace if device_id is not already configured to elias-esp32 + if (strcmp(ctx->device_id, "elias-esp32") != 0) { + strcpy(ctx->device_id, "grace-esp32"); + } + + // Speaker Selection Container (Grace / Elias) + lv_obj_t* speaker_row = lv_obj_create(parent); + lv_obj_set_size(speaker_row, lv_pct(95), 45); + lv_obj_set_flex_flow(speaker_row, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(speaker_row, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(speaker_row, 0, LV_PART_MAIN); + lv_obj_set_style_bg_opa(speaker_row, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(speaker_row, 0, LV_PART_MAIN); + + ctx->btn_grace = lv_btn_create(speaker_row); + lv_obj_set_size(ctx->btn_grace, lv_pct(47), 35); + lv_obj_set_style_radius(ctx->btn_grace, 8, LV_PART_MAIN); + lv_obj_set_style_border_width(ctx->btn_grace, 1, LV_PART_MAIN); + lv_obj_t* lbl_grace = lv_label_create(ctx->btn_grace); + lv_label_set_text(lbl_grace, "Grace"); + lv_obj_center(lbl_grace); + lv_obj_add_event_cb(ctx->btn_grace, speaker_event_cb, LV_EVENT_CLICKED, ctx); + + ctx->btn_elias = lv_btn_create(speaker_row); + lv_obj_set_size(ctx->btn_elias, lv_pct(47), 35); + lv_obj_set_style_radius(ctx->btn_elias, 8, LV_PART_MAIN); + lv_obj_set_style_border_width(ctx->btn_elias, 1, LV_PART_MAIN); + lv_obj_t* lbl_elias = lv_label_create(ctx->btn_elias); + lv_label_set_text(lbl_elias, "Elias"); + lv_obj_center(lbl_elias); + lv_obj_add_event_cb(ctx->btn_elias, speaker_event_cb, LV_EVENT_CLICKED, ctx); + + // Set initial highlights and text colors + if (strcmp(ctx->device_id, "elias-esp32") == 0) { + lv_obj_set_style_bg_color(ctx->btn_elias, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_elias, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_elias, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_set_style_bg_color(ctx->btn_grace, lv_color_hex(0x1C1B22), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_grace, lv_color_hex(0x2D2B36), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_grace, lv_color_hex(0x9E9E9E), LV_PART_MAIN); + } else { + lv_obj_set_style_bg_color(ctx->btn_grace, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_grace, lv_color_hex(0x6200EE), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_grace, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_set_style_bg_color(ctx->btn_elias, lv_color_hex(0x1C1B22), LV_PART_MAIN); + lv_obj_set_style_border_color(ctx->btn_elias, lv_color_hex(0x2D2B36), LV_PART_MAIN); + lv_obj_set_style_text_color(ctx->btn_elias, lv_color_hex(0x9E9E9E), LV_PART_MAIN); + } // Conversation bubble container lv_obj_t* conv_card = lv_obj_create(parent);