Fix mode-select UX and status-bar battery alignment.

Single-tap mode entry, hide top separator and row artifact line, center battery with vol/BT, and make % match digit height.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-06 18:19:47 +08:00
parent 49af730f91
commit 5daf5e794b
4 changed files with 58 additions and 67 deletions

View File

@ -19,9 +19,6 @@ void RGB_Y_TO_G()
#define UI_MODE_SCREEN_WIDTH 240 #define UI_MODE_SCREEN_WIDTH 240
#define UI_MODE_SCREEN_HEIGHT 320 #define UI_MODE_SCREEN_HEIGHT 320
/* 模式选择页焦点0=万能 1=普通 2=专业,默认选中万能(与规范一致) */
static uint8_t s_mode_select_focus = 0;
extern bool InModeFlag; extern bool InModeFlag;
/* 0902/0819三行模式撑满状态栏下方至底边无底栏222x88 @ y=43/135/225 */ /* 0902/0819三行模式撑满状态栏下方至底边无底栏222x88 @ y=43/135/225 */
@ -31,44 +28,28 @@ extern bool InModeFlag;
#define UI0902_MODE_ROW_Y0 43 #define UI0902_MODE_ROW_Y0 43
#define UI0902_MODE_ROW_DY 92 #define UI0902_MODE_ROW_DY 92
static const uint32_t s_mode_row_addr[3][2] = { /* 模式页不显示焦点:三行均用未选中资源;单击直接进入 */
{ UI0902_ROW_UNIVERSAL_NOT_ADDR, UI0902_ROW_UNIVERSAL_SEL_ADDR }, /* 0 万能 */ static const uint32_t s_mode_row_addr[3] = {
{ UI0902_ROW_NORMAL_NOT_ADDR, UI0902_ROW_NORMAL_SEL_ADDR }, /* 1 普通 */ UI0902_ROW_UNIVERSAL_NOT_ADDR, /* 0 万能 */
{ UI0902_ROW_EXPERT_NOT_ADDR, UI0902_ROW_EXPERT_SEL_ADDR }, /* 2 专业 */ UI0902_ROW_NORMAL_NOT_ADDR, /* 1 普通 */
UI0902_ROW_EXPERT_NOT_ADDR, /* 2 专业 */
}; };
static void UI_DrawModeSelectButton(uint16_t y, uint8_t idx, uint8_t focused)
{
LCD_WR_PIC_FROM_FLASH(UI0902_MODE_ROW_X, y, UI0902_MODE_ROW_W, UI0902_MODE_ROW_H,
s_mode_row_addr[idx][focused ? 1 : 0]);
}
static void UI_ModeSelect_DrawButtonAt(uint8_t idx)
{
if (idx > 2)
return;
UI_DrawModeSelectButton((uint16_t)(UI0902_MODE_ROW_Y0 + idx * UI0902_MODE_ROW_DY),
idx, s_mode_select_focus == idx);
}
static void UI_ModeSelect_SetFocus(uint8_t idx)
{
uint8_t prev;
if (idx > 2 || idx == s_mode_select_focus)
return;
prev = s_mode_select_focus;
s_mode_select_focus = idx;
/* 只重绘新旧两个按钮,避免整页三键闪烁 */
UI_ModeSelect_DrawButtonAt(prev);
UI_ModeSelect_DrawButtonAt(idx);
}
static void UI_ModeSelect_DrawButtons(void) static void UI_ModeSelect_DrawButtons(void)
{ {
UI_ModeSelect_DrawButtonAt(0); uint8_t i;
UI_ModeSelect_DrawButtonAt(1); for (i = 0; i < 3; i++) {
UI_ModeSelect_DrawButtonAt(2); uint16_t y = (uint16_t)(UI0902_MODE_ROW_Y0 + i * UI0902_MODE_ROW_DY);
LCD_WR_PIC_FROM_FLASH(UI0902_MODE_ROW_X, y,
UI0902_MODE_ROW_W, UI0902_MODE_ROW_H,
s_mode_row_addr[i]);
/* 万能模式素材顶部有残留近白横线(相对行内 y=7/8盖成行底色 */
if (i == 0) {
LCD_FillByColor(UI0902_MODE_ROW_X, (uint16_t)(y + 7),
(uint16_t)(UI0902_MODE_ROW_X + UI0902_MODE_ROW_W),
(uint16_t)(y + 9), UI0902_ROW_BG);
}
}
} }
void UI_ReturnToModeSelect(void) void UI_ReturnToModeSelect(void)
@ -76,7 +57,6 @@ void UI_ReturnToModeSelect(void)
StartFlag = 0; StartFlag = 0;
InModeFlag = false; InModeFlag = false;
AutoBandTop1_Stop(); AutoBandTop1_Stop();
s_mode_select_focus = 0;
CallUI_Idle(); CallUI_Idle();
UI_DrawModeSelectScreen(); UI_DrawModeSelectScreen();
} }
@ -93,10 +73,10 @@ void UI_DrawModeSelectScreen(void)
} }
const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = { const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = {
/* Flag=按钮序号(0万能/1普通/2专业)ID=进入 TAB。三行撑满,无底栏 */ /* Flag=按钮序号(0万能/1普通/2专业)ID=进入 TAB。全宽便于命中 */
{ 9, 231, 43, 130, 0, 0, 0, NULL }, { 0, 239, 43, 130, 0, 0, 0, NULL },
{ 9, 231, 135, 222, 1, 0, 2, NULL }, { 0, 239, 135, 222, 1, 0, 2, NULL },
{ 9, 231, 225, 312, 2, 0, 1, NULL }, { 0, 239, 225, 312, 2, 0, 1, NULL },
}; };
#define TOUCH_AREA_MODE_SELECT_NUM (sizeof(Touch_ModeSelect_Areas)/sizeof(Touch_AreaTypeDef)) #define TOUCH_AREA_MODE_SELECT_NUM (sizeof(Touch_ModeSelect_Areas)/sizeof(Touch_AreaTypeDef))
@ -140,8 +120,8 @@ void LoadConfig(void)
void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex) void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex)
{ {
(void)areaIndex; (void)areaIndex;
(void)FLAG;
StartTask(); StartTask();
s_mode_select_focus = (uint8_t)FLAG;
/* ID 为 TAB 索引0=万能(Song) 1=专业(Expert) 2=普通(Free) */ /* ID 为 TAB 索引0=万能(Song) 1=专业(Expert) 2=普通(Free) */
mGuiData[GUI_TAB_INDEX].Current = ID; mGuiData[GUI_TAB_INDEX].Current = ID;
InModeFlag = true; InModeFlag = true;
@ -184,7 +164,6 @@ void IdleProcess(DisplayTaskMessage_Type msg)
app_adc_sync_volume(vol); app_adc_sync_volume(vol);
Send_volume(vol); Send_volume(vol);
s_mode_select_focus = 0;
UI_DrawModeSelectScreen(); UI_DrawModeSelectScreen();
TM1629D_AllLedOn(LED_COLOR_G); TM1629D_AllLedOn(LED_COLOR_G);
TM1629D_UpdateDisplay(0); TM1629D_UpdateDisplay(0);
@ -221,20 +200,16 @@ void IdleProcess(DisplayTaskMessage_Type msg)
msg.LoByte >= Touch_ModeSelect_Areas[k].y_min && msg.LoByte <= Touch_ModeSelect_Areas[k].y_max ) msg.LoByte >= Touch_ModeSelect_Areas[k].y_min && msg.LoByte <= Touch_ModeSelect_Areas[k].y_max )
{ {
hit = 1U; hit = 1U;
uint8_t row = (uint8_t)Touch_ModeSelect_Areas[k].Flag; LOG_I("UI", "mode_select hit area=%u row=%u x=%u y=%u",
LOG_I("UI", "mode_select hit area=%u row=%u focus=%u x=%u y=%u", (unsigned)k,
(unsigned)k, (unsigned)row, (unsigned)s_mode_select_focus, (unsigned)Touch_ModeSelect_Areas[k].Flag,
(unsigned)msg.HiByte, (unsigned)msg.LoByte); (unsigned)msg.HiByte, (unsigned)msg.LoByte);
/* 已聚焦 → 进入;未聚焦 → 切蓝焦点,再点一次进入 */ /* 单击直接进入对应模式主页 */
if (row == s_mode_select_focus) {
if (now - s_last_enter_ms < 300U) if (now - s_last_enter_ms < 300U)
break; break;
s_last_enter_ms = now; s_last_enter_ms = now;
Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag, Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag,
Touch_ModeSelect_Areas[k].ID, k); Touch_ModeSelect_Areas[k].ID, k);
} else {
UI_ModeSelect_SetFocus(row);
}
break; break;
} }
} }

View File

@ -226,13 +226,17 @@ uint8_t UI_SetFocus(uint8_t widget_id)
return 1; return 1;
} }
void UI_DrawStatusSepLine(void)
{
/* 模式选择等页不需要顶栏底部分割线,保留空实现以免局部刷新再画出 */
(void)0;
}
void label_top() void label_top()
{ {
const uint16_t btn_color = /*DARKLGRAY*/0x2988;
LCD_FillByColor(0, 0, 240, UI_STATUS_BAR_H, UI0902_BG_COLOR); LCD_FillByColor(0, 0, 240, UI_STATUS_BAR_H, UI0902_BG_COLOR);
/* 音量条:渐变 + 圆角(见 Draw_Volume_Bar */ /* 音量条:渐变 + 圆角(见 Draw_Volume_Bar */
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY); Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY);
LCD_DrawLine(0, 26, 240, 26, btn_color);
Show_BL_Icon(mGuiData[GUI_BL_SW].Current); Show_BL_Icon(mGuiData[GUI_BL_SW].Current);
Show_Battery_Icon(usb_charging_state); Show_Battery_Icon(usb_charging_state);
} }
@ -297,15 +301,22 @@ void UI_GotoCurrentModePage(void)
/* 蓝牙图标:设计稿居中 */ /* 蓝牙图标:设计稿居中 */
void Show_BL_Icon(uint8_t value) void Show_BL_Icon(uint8_t value)
{ {
static int8_t s_bt_pwr = -1;
/* Fill 终点为开区间,传 W/H 本身;高度须停在分割线之上 */
LCD_FillByColor(UI0902_BT_X, UI0902_BT_Y, LCD_FillByColor(UI0902_BT_X, UI0902_BT_Y,
UI0902_BT_X + UI0902_BT_W - 1, UI0902_BT_X + UI0902_BT_W,
UI0902_BT_Y + UI0902_BT_H - 1, UI0902_BG_COLOR); UI0902_BT_Y + UI0902_BT_H, UI0902_BG_COLOR);
if (value) if (value)
{ {
LCD_WR_PIC_Trans(UI0902_BT_X, UI0902_BT_Y, UI0902_BT_W, UI0902_BT_H, LCD_WR_PIC_Trans(UI0902_BT_X, UI0902_BT_Y, UI0902_BT_W, UI0902_BT_H,
gImage_UI0902_Bluetooth_11x17, BLACK); gImage_UI0902_Bluetooth_11x17, BLACK);
} }
if (s_bt_pwr != (int8_t)value)
{
s_bt_pwr = (int8_t)value;
BSP_BlueToothPowerEnable(value); BSP_BlueToothPowerEnable(value);
}
} }
void Draw_Status_Battery_Icon(uint8_t battery_percent) void Draw_Status_Battery_Icon(uint8_t battery_percent)
@ -337,7 +348,8 @@ void Draw_Status_Battery_Icon(uint8_t battery_percent)
if ((int16_t)text_y < 0) if ((int16_t)text_y < 0)
text_y = 0; text_y = 0;
LCD_FillByColor(bat_x > 2 ? (uint16_t)(bat_x - 2) : 0, 0, 240, UI_STATUS_BAR_H, /* 只清分割线上方 */
LCD_FillByColor(bat_x > 2 ? (uint16_t)(bat_x - 2) : 0, 0, 240, UI0902_STATUS_SEP_Y,
UI0902_BG_COLOR); UI0902_BG_COLOR);
/* 实心电量条:内腔约 x+3..x+23宽21勿盖住右侧壳壁 */ /* 实心电量条:内腔约 x+3..x+23宽21勿盖住右侧壳壁 */
@ -345,8 +357,8 @@ void Draw_Status_Battery_Icon(uint8_t battery_percent)
if (fill_w > 0) { if (fill_w > 0) {
fill_x1 = (uint16_t)(bat_x + 3); fill_x1 = (uint16_t)(bat_x + 3);
fill_y1 = (uint16_t)(UI0902_BATTERY_Y + 2); fill_y1 = (uint16_t)(UI0902_BATTERY_Y + 2);
fill_x2 = (uint16_t)(fill_x1 + fill_w - 1); fill_x2 = (uint16_t)(fill_x1 + fill_w);
fill_y2 = (uint16_t)(fill_y1 + 7); fill_y2 = (uint16_t)(fill_y1 + 8);
LCD_FillByColor(fill_x1, fill_y1, fill_x2, fill_y2, WHITE); LCD_FillByColor(fill_x1, fill_y1, fill_x2, fill_y2, WHITE);
} }
LCD_WR_PIC_Trans(bat_x, UI0902_BATTERY_Y, UI0902_BATTERY_W, UI0902_BATTERY_H, LCD_WR_PIC_Trans(bat_x, UI0902_BATTERY_Y, UI0902_BATTERY_W, UI0902_BATTERY_H,

View File

@ -28,6 +28,8 @@ void CallUI_RestoreSelect(void);
#define UI_STATUS_BAR_H 26 #define UI_STATUS_BAR_H 26
#define UI0902_STATUS_SEP_Y 26
#define UI0902_STATUS_SEP_COLOR 0x52AA /* 比旧 0x2988 更清晰,避免在蓝牙下看成断开 */
/* 0902 设计稿配色与底栏导航 */ /* 0902 设计稿配色与底栏导航 */
#define UI0902_BG_COLOR 0x0042 /* #000813 页面背景 */ #define UI0902_BG_COLOR 0x0042 /* #000813 页面背景 */
#define UI0902_ROW_BG 0x2147 /* #242B3A 列表行背景 */ #define UI0902_ROW_BG 0x2147 /* #242B3A 列表行背景 */
@ -122,7 +124,8 @@ void CallUI_RestoreSelect(void);
#define UI0902_BT_Y 5 #define UI0902_BT_Y 5
#define UI0902_BATTERY_W 29 #define UI0902_BATTERY_W 29
#define UI0902_BATTERY_H 12 #define UI0902_BATTERY_H 12
#define UI0902_BATTERY_Y 13 /* 顶≈y13底 y24与分隔线 y26 留空,避免底边被切 */ /* 与音量(y3..20)/蓝牙(y5..21)视觉中心对齐12px 高 → 顶 y7 */
#define UI0902_BATTERY_Y 7
#define UI0902_BATTERY_RIGHT_MARGIN 6 #define UI0902_BATTERY_RIGHT_MARGIN 6
#define UI0902_BATTERY_TEXT_GAP 4 #define UI0902_BATTERY_TEXT_GAP 4
#define UI0902_BATTERY_TEXT_SIZE 9 /* mode.png 百分比字号 ≈9完整显示 % */ #define UI0902_BATTERY_TEXT_SIZE 9 /* mode.png 百分比字号 ≈9完整显示 % */
@ -191,6 +194,7 @@ void UI_GetFocusGrad(uint8_t widget_id, uint16_t *c_top, uint16_t *c_bot);
void Draw_Status_Battery_Icon(uint8_t battery_percent); void Draw_Status_Battery_Icon(uint8_t battery_percent);
void Show_Battery_Icon(uint8_t flag); void Show_Battery_Icon(uint8_t flag);
void UI_DrawStatusSepLine(void);
void Show_BL_Icon(uint8_t value); void Show_BL_Icon(uint8_t value);
void Draw_Tab_Section_Menu(const LEBEL_UI *UI, TAB_SECTION_INDEX select_tab); void Draw_Tab_Section_Menu(const LEBEL_UI *UI, TAB_SECTION_INDEX select_tab);

View File

@ -997,7 +997,7 @@ const unsigned char ascii_94[][9]={
{0x00,0x00,0x00,0x14,0x14,0x14,0x00,0x00,0x00},/*""",2*/ {0x00,0x00,0x00,0x14,0x14,0x14,0x00,0x00,0x00},/*""",2*/
{0x24,0x24,0x7E,0x24,0x24,0x12,0x7F,0x12,0x12},/*"#",3*/ {0x24,0x24,0x7E,0x24,0x24,0x12,0x7F,0x12,0x12},/*"#",3*/
{0x0C,0x0C,0x02,0x02,0x0C,0x10,0x10,0x0C,0x0C},/*"$",4*/ {0x0C,0x0C,0x02,0x02,0x0C,0x10,0x10,0x0C,0x0C},/*"$",4*/
{0x02,0x25,0x12,0x08,0x24,0x52,0x20,0x00,0x00},/*"%",5*/ {0x26,0x29,0x29,0x16,0x08,0x34,0x4A,0x4A,0x34},/*"%",5*/ /* 9px 满高,与数字同高 */
{0x0C,0x12,0x12,0x0A,0x26,0x25,0x19,0x09,0x36},/*"&",6*/ {0x0C,0x12,0x12,0x0A,0x26,0x25,0x19,0x09,0x36},/*"&",6*/
{0x00,0x00,0x00,0x08,0x08,0x08,0x00,0x00,0x00},/*"'",7*/ {0x00,0x00,0x00,0x08,0x08,0x08,0x00,0x00,0x00},/*"'",7*/
{0x08,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x08},/*"(",8*/ {0x08,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x08},/*"(",8*/