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;
static void UI_DrawModeSelectButton(uint16_t y, const uint8_t *row, uint8_t focused);
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)
{
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);
}
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)
{
UI_DrawModeSelectButton(40,
gImage_Mode0831_Universal_Row_180_52,
s_mode_select_focus == 0);
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);
UI_ModeSelect_DrawButtonAt(0);
UI_ModeSelect_DrawButtonAt(1);
UI_ModeSelect_DrawButtonAt(2);
}
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) */
mGuiData[GUI_TAB_INDEX].Current = ID;
InModeFlag = true;
/* 进入子页后抑制残留按下,否则易误触底栏 GUI_TAB_INDEX(id=5)→设置 */
app_touch_suppress(500);
switch (ID)
{
@ -212,7 +235,10 @@ void IdleProcess(DisplayTaskMessage_Type msg)
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;
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 &&
@ -220,19 +246,28 @@ void IdleProcess(DisplayTaskMessage_Type msg)
{
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",
(unsigned)k, (unsigned)row,
LOG_I("UI", "mode_select hit area=%u row=%u focus=%u x=%u y=%u",
(unsigned)k, (unsigned)row, (unsigned)s_mode_select_focus,
(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);
else
/* 调试十字:确认触点是否落在按钮上 */
TP_Drow_Touch_Point(msg.HiByte, msg.LoByte, RED);
/* 已聚焦 → 进入;未聚焦 → 切蓝焦点,再点一次进入 */
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);
}
break;
}
}
if (!hit) {
LOG_I("UI", "mode_select miss x=%u y=%u",
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
TP_Drow_Touch_Point(msg.HiByte, msg.LoByte, YELLOW);
}
}
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 )
{
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)pCurrentTouch_Area[k].Value,
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
Touch_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value);
ResetAutoPowerCount();

View File

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

View File

@ -38,6 +38,7 @@ void CallUI_Idle(void) {
}
void CallUI_SongMode(void) {
app_touch_suppress(500);
UI_SongMode_Init();
CurrUIProcress = UI_SongMode_Process;
app_log_set_ui_page("Song");
@ -45,6 +46,7 @@ void CallUI_SongMode(void) {
}
void CallUI_ExpertMode(void) {
app_touch_suppress(500);
UI_ExpertMode_Init();
// CurrUIProcress = UI_ExpertMode_Process;
CurrUIProcress = UI_SongMode_Process;
@ -53,6 +55,7 @@ void CallUI_ExpertMode(void) {
}
void CallUI_FreeMode(void) {
app_touch_suppress(500);
UI_FreeMode_Init();
// CurrUIProcress = UI_FreeMode_Process;
CurrUIProcress = UI_SongMode_Process;
@ -61,6 +64,7 @@ void CallUI_FreeMode(void) {
}
void CallUI_Setting(void) {
app_touch_suppress(500);
CurrUIProcress = UI_Setting_Process;
UI_Setting_Init();
app_log_set_ui_page("Setting");
@ -68,6 +72,7 @@ void CallUI_Setting(void) {
}
void CallUI_Mixer(void) {
app_touch_suppress(500);
CurrUIProcress = UI_Mixer_Process;
UI_Mixer_Init();
app_log_set_ui_page("Mixer");
@ -75,6 +80,7 @@ void CallUI_Mixer(void) {
}
void CallUI_SystemSetting(void) {
app_touch_suppress(500);
CurrUIProcress = UI_SystemSet_Process;
UI_SystemSet_Init();
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);
}
/* TAB 选择刷新(占位) */
/* TAB 选择刷新tab 未变时不切页,避免误触/phantom touch 整页重绘闪烁 */
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:
MenuPage_SongMode_Proc();
break;
MenuPage_SongMode_Proc();
break;
case 1:
MenuPage_ExpertMode_Proc();
break;
MenuPage_ExpertMode_Proc();
break;
case 2:
MenuPage_FreeMode_Proc();
break;
MenuPage_FreeMode_Proc();
break;
case 3:
MenuPage_SystemSetting_Proc();
break;
MenuPage_SystemSetting_Proc();
break;
default:
break;
}
}