Improve mode-select focus UX and related touch hit feedback.

Redraw only changed mode buttons, restore focus-then-enter, and keep page transitions from false bottom-tab hits.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-08-31 21:59:12 +08:00
parent d48e3fa63a
commit 33f48d9171
4 changed files with 130 additions and 90 deletions

View File

@ -24,16 +24,9 @@ static uint8_t s_mode_select_focus = 0;
extern bool InModeFlag; extern bool InModeFlag;
static void UI_DrawModeSelectButton(uint16_t y, const uint8_t *row, uint8_t focused);
static void UI_ModeSelect_DrawButtons(void); static void UI_ModeSelect_DrawButtons(void);
static void UI_ModeSelect_SetFocus(uint8_t idx)
{
if (idx > 2 || idx == s_mode_select_focus)
return;
s_mode_select_focus = idx;
UI_ModeSelect_DrawButtons();
}
void UI_ReturnToModeSelect(void) void UI_ReturnToModeSelect(void)
{ {
StartFlag = 0; StartFlag = 0;
@ -67,17 +60,45 @@ static void UI_DrawModeSelectButton(uint16_t y, const uint8_t *row, uint8_t focu
LCD_WR_PIC_Trans(row_x, row_y, UI_MODE0831_ROW_W, UI_MODE0831_ROW_H, row, BLACK); LCD_WR_PIC_Trans(row_x, row_y, UI_MODE0831_ROW_W, UI_MODE0831_ROW_H, row, BLACK);
} }
static void UI_ModeSelect_DrawButtonAt(uint8_t idx)
{
switch (idx)
{
case 0:
UI_DrawModeSelectButton(40, gImage_Mode0831_Universal_Row_180_52,
s_mode_select_focus == 0);
break;
case 1:
UI_DrawModeSelectButton(132, gImage_Mode0831_Normal_Row_180_52,
s_mode_select_focus == 1);
break;
case 2:
UI_DrawModeSelectButton(224, gImage_Mode0831_Expert_Row_180_52,
s_mode_select_focus == 2);
break;
default:
break;
}
}
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_DrawModeSelectButton(40, UI_ModeSelect_DrawButtonAt(0);
gImage_Mode0831_Universal_Row_180_52, UI_ModeSelect_DrawButtonAt(1);
s_mode_select_focus == 0); UI_ModeSelect_DrawButtonAt(2);
UI_DrawModeSelectButton(132,
gImage_Mode0831_Normal_Row_180_52,
s_mode_select_focus == 1);
UI_DrawModeSelectButton(224,
gImage_Mode0831_Expert_Row_180_52,
s_mode_select_focus == 2);
} }
void UI_DrawModeSelectScreen(void) void UI_DrawModeSelectScreen(void)
@ -143,6 +164,8 @@ void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex)
/* 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;
/* 进入子页后抑制残留按下,否则易误触底栏 GUI_TAB_INDEX(id=5)→设置 */
app_touch_suppress(500);
switch (ID) switch (ID)
{ {
@ -212,7 +235,10 @@ void IdleProcess(DisplayTaskMessage_Type msg)
case MSG_ID_TOUCH: case MSG_ID_TOUCH:
{ {
static uint32_t s_last_enter_ms;
uint32_t now = rt_tick_get() * 1000U / RT_TICK_PER_SECOND;
uint8_t hit = 0U; uint8_t hit = 0U;
for(uint8_t k=0; k<TOUCH_AREA_MODE_SELECT_NUM; k++) for(uint8_t k=0; k<TOUCH_AREA_MODE_SELECT_NUM; k++)
{ {
if( msg.HiByte >= Touch_ModeSelect_Areas[k].x_min && msg.HiByte <= Touch_ModeSelect_Areas[k].x_max && if( msg.HiByte >= Touch_ModeSelect_Areas[k].x_min && msg.HiByte <= Touch_ModeSelect_Areas[k].x_max &&
@ -220,19 +246,28 @@ void IdleProcess(DisplayTaskMessage_Type msg)
{ {
hit = 1U; hit = 1U;
uint8_t row = (uint8_t)Touch_ModeSelect_Areas[k].Flag; 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)row, (unsigned)k, (unsigned)row, (unsigned)s_mode_select_focus,
(unsigned)msg.HiByte, (unsigned)msg.LoByte); (unsigned)msg.HiByte, (unsigned)msg.LoByte);
if (row == s_mode_select_focus) /* 调试十字:确认触点是否落在按钮上 */
Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag, Touch_ModeSelect_Areas[k].ID, k); TP_Drow_Touch_Point(msg.HiByte, msg.LoByte, RED);
else /* 已聚焦 → 进入;未聚焦 → 切蓝焦点,再点一次进入 */
if (row == s_mode_select_focus) {
if (now - s_last_enter_ms < 300U)
break;
s_last_enter_ms = now;
Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag,
Touch_ModeSelect_Areas[k].ID, k);
} else {
UI_ModeSelect_SetFocus(row); UI_ModeSelect_SetFocus(row);
}
break; break;
} }
} }
if (!hit) { if (!hit) {
LOG_I("UI", "mode_select miss x=%u y=%u", LOG_I("UI", "mode_select miss x=%u y=%u",
(unsigned)msg.HiByte, (unsigned)msg.LoByte); (unsigned)msg.HiByte, (unsigned)msg.LoByte);
TP_Drow_Touch_Point(msg.HiByte, msg.LoByte, YELLOW);
} }
} }
break; break;

View File

@ -385,8 +385,9 @@ void UI_SongMode_Process(DisplayTaskMessage_Type msg)
msg.LoByte >= pCurrentTouch_Area[k].y_min && msg.LoByte <= pCurrentTouch_Area[k].y_max ) msg.LoByte >= pCurrentTouch_Area[k].y_min && msg.LoByte <= pCurrentTouch_Area[k].y_max )
{ {
hit = 1U; hit = 1U;
LOG_I("UI", "song hit area=%u id=%u x=%u y=%u", LOG_I("UI", "song hit area=%u id=%u val=%u x=%u y=%u",
(unsigned)k, (unsigned)pCurrentTouch_Area[k].ID, (unsigned)k, (unsigned)pCurrentTouch_Area[k].ID,
(unsigned)pCurrentTouch_Area[k].Value,
(unsigned)msg.HiByte, (unsigned)msg.LoByte); (unsigned)msg.HiByte, (unsigned)msg.LoByte);
Touch_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value); Touch_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value);
ResetAutoPowerCount(); ResetAutoPowerCount();

View File

@ -34,62 +34,43 @@ void Touch_Seting_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8
switch(ID) switch(ID)
{ {
case 0: case 0:
MenuPage_Mixer_Proc(); if (CurrUIProcress != UI_Mixer_Process)
MenuPage_Mixer_Proc();
break; break;
// case 2: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><D4A4>
// MenuPage_FreeMode_Proc();
// break;
case 2: case 2:
MenuPage_Setting_Proc(); if (CurrUIProcress != UI_Setting_Process)
MenuPage_Setting_Proc();
break; break;
case 5: case 5:
last_value = mGuiData[GUI_TAB_INDEX].Current; last_value = mGuiData[GUI_TAB_INDEX].Current;
if (last_value == value)
break;
mGuiData[GUI_TAB_INDEX].Current = value; mGuiData[GUI_TAB_INDEX].Current = value;
if(last_value != value) switch(value)
{ {
switch(value) case 0:
{ if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current)
case 0: break;
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current) ADDRESS = 0x00000000;
break; break;
//AutoBandTop1_Stop(); // AutoBand 模块未加入工程
ADDRESS = 0x00000000;
//AutoBandTop1_LoadPresetItemFromFlash(0); // AutoBand 模块未加入工程
break;
case 1: case 1:
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current) if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current)
break; break;
//AutoBandTop1_Stop(); // AutoBand 模块未加入工程 ADDRESS = 0x0000EB41;
ADDRESS = 0x0000EB41; break;
//AutoBandTop1_LoadPresetItemFromFlash(0); // AutoBand 模块未加入工程
break;
case 2: case 2:
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current) if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[GUI_TAB_INDEX].Current)
break; break;
//AutoBandTop1_Stop(); ADDRESS = 0x000170EF;
ADDRESS = 0x000170EF; break;
break;
} default:
break;
} }
// switch(value) Refresh_TabSelect_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_TAB_INDEX]);
// {
// case 0:
//
// MenuPage_SongMode_Proc();
// break;
// case 1:
// MenuPage_ExpertMode_Proc();
// break;
// case 2:
// MenuPage_FreeMode_Proc();
// break;
// }
Refresh_TabSelect_ui(&UI_Label[ID], &mGuiData[ID]);
break; break;
} }
@ -241,28 +222,34 @@ void UI_DrawSysModeSelectScreen(void)
void UI_SystemSet_Init(void) void UI_SystemSet_Init(void)
{ {
UI_ClearFocus(); UI_ClearFocus();
// LCD_WR_REG(0x28); // Display OFF
pCurrentTouch_Area = Touch_SetingSelect_Areas; pCurrentTouch_Area = Touch_SetingSelect_Areas;
UI_DrawSysModeSelectScreen(); UI_DrawSysModeSelectScreen();
label_top();
label_Tab_Select_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_TAB_INDEX]); label_Tab_Select_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_TAB_INDEX]);
// LCD_WR_REG(0x29); // Display ON
} }
void UI_SystemSet_Process(DisplayTaskMessage_Type msg) void UI_SystemSet_Process(DisplayTaskMessage_Type msg)
{ {
static uint32_t s_last_touch_ms;
switch(msg.MessageType) switch(msg.MessageType)
{ {
case MSG_ID_TOUCH: case MSG_ID_TOUCH:
for(uint8_t k=0; k<TOUCH_AREA_SETING_SELECT_NUM; k++)
{ {
if( msg.HiByte >= pCurrentTouch_Area[k].x_min && uint32_t now = rt_tick_get() * 1000U / RT_TICK_PER_SECOND;
msg.HiByte <= pCurrentTouch_Area[k].x_max && if (now - s_last_touch_ms < 250U) {
msg.LoByte >= pCurrentTouch_Area[k].y_min && break;
msg.LoByte <= pCurrentTouch_Area[k].y_max ) }
s_last_touch_ms = now;
for(uint8_t k=0; k<TOUCH_AREA_SETING_SELECT_NUM; k++)
{ {
Touch_Seting_Select_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value); if( msg.HiByte >= pCurrentTouch_Area[k].x_min &&
break; msg.HiByte <= pCurrentTouch_Area[k].x_max &&
msg.LoByte >= pCurrentTouch_Area[k].y_min &&
msg.LoByte <= pCurrentTouch_Area[k].y_max )
{
Touch_Seting_Select_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value);
break;
}
} }
} }
break; break;

View File

@ -38,6 +38,7 @@ void CallUI_Idle(void) {
} }
void CallUI_SongMode(void) { void CallUI_SongMode(void) {
app_touch_suppress(500);
UI_SongMode_Init(); UI_SongMode_Init();
CurrUIProcress = UI_SongMode_Process; CurrUIProcress = UI_SongMode_Process;
app_log_set_ui_page("Song"); app_log_set_ui_page("Song");
@ -45,6 +46,7 @@ void CallUI_SongMode(void) {
} }
void CallUI_ExpertMode(void) { void CallUI_ExpertMode(void) {
app_touch_suppress(500);
UI_ExpertMode_Init(); UI_ExpertMode_Init();
// CurrUIProcress = UI_ExpertMode_Process; // CurrUIProcress = UI_ExpertMode_Process;
CurrUIProcress = UI_SongMode_Process; CurrUIProcress = UI_SongMode_Process;
@ -53,6 +55,7 @@ void CallUI_ExpertMode(void) {
} }
void CallUI_FreeMode(void) { void CallUI_FreeMode(void) {
app_touch_suppress(500);
UI_FreeMode_Init(); UI_FreeMode_Init();
// CurrUIProcress = UI_FreeMode_Process; // CurrUIProcress = UI_FreeMode_Process;
CurrUIProcress = UI_SongMode_Process; CurrUIProcress = UI_SongMode_Process;
@ -61,6 +64,7 @@ void CallUI_FreeMode(void) {
} }
void CallUI_Setting(void) { void CallUI_Setting(void) {
app_touch_suppress(500);
CurrUIProcress = UI_Setting_Process; CurrUIProcress = UI_Setting_Process;
UI_Setting_Init(); UI_Setting_Init();
app_log_set_ui_page("Setting"); app_log_set_ui_page("Setting");
@ -68,6 +72,7 @@ void CallUI_Setting(void) {
} }
void CallUI_Mixer(void) { void CallUI_Mixer(void) {
app_touch_suppress(500);
CurrUIProcress = UI_Mixer_Process; CurrUIProcress = UI_Mixer_Process;
UI_Mixer_Init(); UI_Mixer_Init();
app_log_set_ui_page("Mixer"); app_log_set_ui_page("Mixer");
@ -75,6 +80,7 @@ void CallUI_Mixer(void) {
} }
void CallUI_SystemSetting(void) { void CallUI_SystemSetting(void) {
app_touch_suppress(500);
CurrUIProcress = UI_SystemSet_Process; CurrUIProcress = UI_SystemSet_Process;
UI_SystemSet_Init(); UI_SystemSet_Init();
app_log_set_ui_page("SysSet"); app_log_set_ui_page("SysSet");
@ -184,23 +190,34 @@ void Refresh_SectionSelect(uint16_t last_value, const LEBEL_UI *UI, GUI_SWITCH *
Draw_Tab_Section_Menu(UI,(TAB_SECTION_INDEX)Group->Current); Draw_Tab_Section_Menu(UI,(TAB_SECTION_INDEX)Group->Current);
} }
/* TAB 选择刷新(占位) */ /* TAB 选择刷新tab 未变时不切页,避免误触/phantom touch 整页重绘闪烁 */
void Refresh_TabSelect_ui(const LEBEL_UI *UI, GUI_SWITCH *Group) void Refresh_TabSelect_ui(const LEBEL_UI *UI, GUI_SWITCH *Group)
{ {
switch(Group->Current) static uint8_t s_last_tab = 0xFFU;
{ uint8_t tab = (uint8_t)Group->Current;
(void)UI;
if (tab == s_last_tab) {
return;
}
s_last_tab = tab;
switch (tab)
{
case 0: case 0:
MenuPage_SongMode_Proc(); MenuPage_SongMode_Proc();
break; break;
case 1: case 1:
MenuPage_ExpertMode_Proc(); MenuPage_ExpertMode_Proc();
break; break;
case 2: case 2:
MenuPage_FreeMode_Proc(); MenuPage_FreeMode_Proc();
break; break;
case 3: case 3:
MenuPage_SystemSetting_Proc(); MenuPage_SystemSetting_Proc();
break; break;
default:
break;
} }
} }