feat(ui): tap status-bar Bluetooth icon to toggle power

Hit area on mode/home/settings hub; off state uses gray icon + slash until a disabled asset is ready. Syncs system setting and NVM.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-22 17:42:04 +08:00
parent d00f570e2f
commit 04abc2e1be
5 changed files with 80 additions and 4 deletions

View File

@ -68,6 +68,9 @@ void UI_DrawModeSelectScreen(void)
}
const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = {
/* 状态栏蓝牙:点击开关(须在模式行之前,避免被误判) */
{ UI0902_BT_HIT_X0, UI0902_BT_HIT_X1, UI0902_BT_HIT_Y0, UI0902_BT_HIT_Y1,
0, 0, GUI_BL_SW, NULL },
/* Flag=按钮序号(0万能/1普通/2专业);ID=进入 TAB。全宽便于命中;Y 与 MODE_ROW_* 一致 */
{ 0, 239, 48, 135, 0, 0, 0, NULL },
{ 0, 239, 140, 227, 1, 0, 2, NULL },
@ -123,6 +126,11 @@ void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex)
{
(void)areaIndex;
(void)FLAG;
if (ID == GUI_BL_SW)
{
UI_StatusBar_ToggleBluetooth();
return;
}
StartTask();
/* ID 为 TAB 索引:0=万能(Song) 1=专业(Expert) 2=普通(Free) */
mGuiData[GUI_TAB_INDEX].Current = ID;
@ -215,6 +223,13 @@ void IdleProcess(DisplayTaskMessage_Type msg)
(unsigned)k,
(unsigned)Touch_ModeSelect_Areas[k].Flag,
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
/* 蓝牙开关不受进模式防抖限制 */
if (Touch_ModeSelect_Areas[k].ID == GUI_BL_SW)
{
Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag,
Touch_ModeSelect_Areas[k].ID, k);
break;
}
/* 单击直接进入对应模式主页 */
if (now - s_last_enter_ms < 300U)
break;

View File

@ -339,9 +339,8 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
return;
}
else if(ID==GUI_BL_SW)
{
mGuiData[ID].Current = !mGuiData[ID].Current;
Show_BL_Icon(mGuiData[GUI_BL_SW].Current);
{
UI_StatusBar_ToggleBluetooth();
return;
}
}

View File

@ -3,6 +3,9 @@
/* 0902-11 设置入口:调音台 / 系统设置 两大入口 + 底栏设置高亮 */
const Touch_AreaTypeDef Touch_SetingSelect_Areas[] = {
/* 状态栏蓝牙:点击开关 */
{ UI0902_BT_HIT_X0, UI0902_BT_HIT_X1, UI0902_BT_HIT_Y0, UI0902_BT_HIT_Y1,
0, 0, GUI_BL_SW, NULL },
/* 调音台卡片 */
{ UI0902_HUB_CARD_X, (uint16_t)(UI0902_HUB_CARD_X + UI0902_HUB_CARD_W - 1),
UI0902_HUB_CARD_Y0, (uint16_t)(UI0902_HUB_CARD_Y0 + UI0902_HUB_CARD_H - 1),
@ -45,6 +48,12 @@ void Touch_Seting_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex, uint
(void)FLAG;
(void)areaIndex;
if (ID == GUI_BL_SW)
{
UI_StatusBar_ToggleBluetooth();
return;
}
if (ID == GUI_NAV_BAR)
{
if (value == UI0902_NAV_SETTING)

View File

@ -375,7 +375,35 @@ void UI_GotoCurrentModePage(void)
}
}
/* 蓝牙图标:按系统开关显示;关则清空区域不画图标 */
/* 暂无禁用蓝牙素材:开态图改灰 + 斜杠;后续替换 gImage 禁用图标即可 */
static void Show_BL_Icon_DrawDisabled(void)
{
const unsigned char *data = gImage_UI0902_Bluetooth_11x17;
uint16_t x = UI0902_BT_X;
uint16_t y = UI0902_BT_Y;
uint16_t w = UI0902_BT_W;
uint16_t h = UI0902_BT_H;
uint32_t total = (uint32_t)w * (uint32_t)h;
uint32_t i;
for (i = 0; i < total; i++)
{
uint16_t c = (uint16_t)(((uint16_t)data[i * 2] << 8) | data[i * 2 + 1]);
uint8_t r = (uint8_t)((c >> 11) & 0x1F);
uint8_t g = (uint8_t)((c >> 5) & 0x3F);
uint8_t b = (uint8_t)(c & 0x1F);
/* 近黑视为透明(与 LCD_WR_PIC_Trans 一致) */
if (r <= 1 && g <= 2 && b <= 1)
continue;
LCD_DrawPoint((uint16_t)(x + (i % w)), (uint16_t)(y + (i / w)), GRAY);
}
/* 禁用斜杠(左下→右上,略加粗) */
LCD_DrawLine(x, (uint16_t)(y + h - 1), (uint16_t)(x + w - 1), y, WHITE);
LCD_DrawLine(x, (uint16_t)(y + h - 2), (uint16_t)(x + w - 2), y, WHITE);
LCD_DrawLine((uint16_t)(x + 1), (uint16_t)(y + h - 1), (uint16_t)(x + w - 1), (uint16_t)(y + 1), WHITE);
}
/* 蓝牙图标:开=素材;关=自绘灰图标+斜杠(待换禁用素材) */
void Show_BL_Icon(uint8_t value)
{
static int8_t s_bt_pwr = -1;
@ -390,6 +418,10 @@ void Show_BL_Icon(uint8_t value)
LCD_WR_PIC_Trans(UI0902_BT_X, UI0902_BT_Y, UI0902_BT_W, UI0902_BT_H,
gImage_UI0902_Bluetooth_11x17, BLACK);
}
else
{
Show_BL_Icon_DrawDisabled();
}
if (s_bt_pwr != (int8_t)on)
{
s_bt_pwr = (int8_t)on;
@ -398,6 +430,18 @@ void Show_BL_Icon(uint8_t value)
UI_DrawStatusSepLine();
}
void UI_StatusBar_ToggleBluetooth(void)
{
NvmParam_Type *nvm = drv_nvm_param_ptr();
uint8_t on = mGuiData[GUI_BL_SW].Current ? 0u : 1u;
mGuiData[GUI_BL_SW].Current = on;
mGuiData_SystemSETTING[GUI_BLUETOOTH_SW].Current = on;
nvm->param.BluetoothSW = on;
drv_nvm_save_to_flash();
Show_BL_Icon(on);
}
void Draw_Status_Battery_Icon(uint8_t battery_percent)
{
uint8_t Info[8];

View File

@ -128,6 +128,13 @@ void CallUI_RestoreSelect(void);
#define UI0902_BT_H 17
#define UI0902_BT_X ((240 - UI0902_BT_W) / 2) /* 居中 */
#define UI0902_BT_Y 5
/* 状态栏蓝牙点击热区:略大于图标,便于点按 */
#define UI0902_BT_HIT_PAD_X 14
#define UI0902_BT_HIT_X0 ((UI0902_BT_X > UI0902_BT_HIT_PAD_X) \
? (uint16_t)(UI0902_BT_X - UI0902_BT_HIT_PAD_X) : 0)
#define UI0902_BT_HIT_X1 (uint16_t)(UI0902_BT_X + UI0902_BT_W + UI0902_BT_HIT_PAD_X - 1)
#define UI0902_BT_HIT_Y0 0
#define UI0902_BT_HIT_Y1 (uint16_t)(UI_STATUS_BAR_H + 2)
#define UI0902_BATTERY_W 29
#define UI0902_BATTERY_H 12
/* 0918 充电态:闪电电池图(替换外壳+填充),28x13,与外壳同中心 */
@ -212,6 +219,8 @@ void Show_Battery_Icon(uint8_t flag);
void UI_DrawStatusSepLine(void);
void Show_BL_Icon(uint8_t value);
/* 状态栏蓝牙图标点击:开关电源、同步设置项与 NVM、刷新图标 */
void UI_StatusBar_ToggleBluetooth(void);
void Draw_Tab_Section_Menu(const LEBEL_UI *UI, TAB_SECTION_INDEX select_tab);
void UI_NavBar_Action(uint8_t value);
void Draw_Bottom_Bar(uint8_t sel, uint8_t first_back);