Align status bar volume icon with UI spec.

Replace the old volume bars with 5 rounded-top bars using a left-to-right brightness gradient, synced from the ADC volume pot.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-08-28 10:07:48 +08:00
parent f754676aa1
commit 37242f108a
4 changed files with 142 additions and 70 deletions

View File

@ -277,14 +277,14 @@ static void app_adc_volume_process(void)
if(abs((int16_t)vol_last - (int16_t)val) > 2) if(abs((int16_t)vol_last - (int16_t)val) > 2)
{ {
vol_last = val; vol_last = val;
/* <EFBFBD><EFBFBD> 6 <20><> */ /* 5 格状态栏音量条0=静音5=最大 */
if (val <= 5) level = 0; if (val <= 5) level = 0;
else if (val <= 35) level = 1; else if (val <= 35) level = 1;
else if (val <= 65) level = 2; else if (val <= 65) level = 2;
else if (val <= 95) level = 3; else if (val <= 95) level = 3;
else if (val <= 115) level = 4; else if (val <= 115) level = 4;
else level = 5; else level = 5;
MainTask_Sendmsg(MSG_ID_EC_VOL, val, level, 0); MainTask_Sendmsg(MSG_ID_EC_VOL, val, level, 0);
} }
} }

View File

@ -270,7 +270,6 @@ void IdleProcess(DisplayTaskMessage_Type msg)
{ {
//LCD_ShowString(200, 0, Num_To_String(msg.DataU16[1],buff,3), RED, WHITE, 16, 0); //LCD_ShowString(200, 0, Num_To_String(msg.DataU16[1],buff,3), RED, WHITE, 16, 0);
uint8_t vol = msg.ID; uint8_t vol = msg.ID;
// uint8_t level;
if (vol <= 5) level = 0; if (vol <= 5) level = 0;
else if (vol <= 35) level = 1; else if (vol <= 35) level = 1;
else if (vol <= 65) level = 2; else if (vol <= 65) level = 2;

View File

@ -1,6 +1,6 @@
#include "includes.h" #include "includes.h"
extern uint8_t level;
// ============================================== // ==============================================
// <20><><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EBB6A8> // <20><><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EBB6A8>
@ -78,7 +78,7 @@ void label_top()
const uint16_t btn_color = /*DARKLGRAY*/0x2988; // 深灰<E6B7B1>????? const uint16_t btn_color = /*DARKLGRAY*/0x2988; // 深灰<E6B7B1>?????
//LCD_FillByColor(0,0,240,25,BLACK); //LCD_FillByColor(0,0,240,25,BLACK);
//LCD_WR_PIC(5,0,12,20,gImage_bar); //LCD_WR_PIC(5,0,12,20,gImage_bar);
Draw_Volume_Bar(5, 5, 3,1, WHITE,GRAY); Draw_Volume_Bar(5, 5, level, 1, WHITE, GRAY);
LCD_DrawLine(0, 26, 240, 26, btn_color); 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);

View File

@ -1706,36 +1706,116 @@ void LCD_DrawMinus_RoundBox(uint16_t x, uint16_t y, uint8_t size, uint8_t radius
/** /**
* @brief 5 * @brief
* @param x: X坐标 */
* @param y: Y坐标 static void LCD_FillRoundTopRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t r, uint16_t color)
* @param volume_level: (0-50=5=) {
* @param color_on: RGB值WHITE/0xFFFF if(w == 0 || h == 0)
* @param color_off: RGB值BLACK/0x0000 {
return;
}
if(r > (w / 2))
{
r = w / 2;
}
if(r > h)
{
r = h;
}
if(r == 0)
{
LCD_FillByColor(x, y, x + w, y + h, color);
return;
}
LCD_FillRoundRect(x, y, w, h, r, color);
if(h > r)
{
LCD_FillByColor(x, y + h - r, x + w, y + h, color);
}
}
/**
* @brief RGB565
*/
static uint16_t LCD_BlendColor565(uint16_t c0, uint16_t c1, uint8_t num, uint8_t den)
{
uint16_t r0 = (c0 >> 11) & 0x1F;
uint16_t g0 = (c0 >> 5) & 0x3F;
uint16_t b0 = c0 & 0x1F;
uint16_t r1 = (c1 >> 11) & 0x1F;
uint16_t g1 = (c1 >> 5) & 0x3F;
uint16_t b1 = c1 & 0x1F;
uint16_t r;
uint16_t g;
uint16_t b;
if(den == 0)
{
return c1;
}
r = r0 + (uint16_t)(r1 - r0) * num / den;
g = g0 + (uint16_t)(g1 - g0) * num / den;
b = b0 + (uint16_t)(b1 - b0) * num / den;
return (r << 11) | (g << 5) | b;
}
/**
* @brief 5
* @param volume_level: (0-50=5=)
* @note N N ()
*/ */
void Draw_Volume_Bar(uint16_t x, uint16_t y, uint8_t volume_level,uint8_t scale,uint16_t color_on, uint16_t color_off) void Draw_Volume_Bar(uint16_t x, uint16_t y, uint8_t volume_level,uint8_t scale,uint16_t color_on, uint16_t color_off)
{ {
uint8_t i; uint8_t i;
//const uint8_t bar_count = 5; // 音量条总数量5挡 uint8_t bar_count = 5;
uint8_t w = 5 * scale; // 单条宽度(支持缩放) uint8_t w = 3 * scale;
uint8_t gap = 2 * scale; // 条间距(支持缩放) uint8_t gap = 2 * scale;
// 每条约的Y偏移和高度按原始比例缩放 uint8_t radius = 1 * scale;
uint8_t y_offset[5] = {8,6,4,2,0}; uint8_t height[5] = {6, 9, 12, 15, 18};
uint8_t height[5] = {12,14,16,18,20}; uint8_t max_h = height[4];
uint16_t clear_w;
uint16_t dim_color = color_off;
// 限制音量等级范围,避免越界 (void)color_on;
volume_level = (volume_level > 5) ? 5 : volume_level;
// 循环绘制5个音量条按档位控制颜色 if(volume_level > 5)
for(i = 0; i < 5; i++)
{ {
uint16_t curr_x = x + (w + gap) * i; // 当前条的X坐标 volume_level = 5;
uint8_t curr_y = y + y_offset[i] * scale; // 当前条的Y坐标缩放后 }
uint8_t curr_h = height[i] * scale; // 当前条的高度(缩放后)
uint16_t curr_color = (i < volume_level) ? color_on : color_off; // 按档位选颜色
// 绘制圆角矩形音量条 clear_w = (uint16_t)(w + gap) * bar_count - gap;
LCD_FillRoundRect(curr_x, curr_y, w, curr_h, 2 * scale, curr_color); LCD_FillByColor(x, y, x + clear_w, y + max_h * scale, BLACK);
if(volume_level == 0)
{
return;
}
for(i = 0; i < bar_count; i++)
{
uint16_t curr_x = x + (w + gap) * i;
uint8_t curr_h = height[i] * scale;
uint8_t curr_y = y + (max_h * scale - curr_h);
uint16_t bar_color;
if(i >= volume_level)
{
continue;
}
if(volume_level == 1)
{
bar_color = WHITE;
}
else
{
/* 左暗右亮第1格最暗当前档位的最右格为全白 */
bar_color = LCD_BlendColor565(dim_color, WHITE, i, volume_level - 1);
}
LCD_FillRoundTopRect(curr_x, curr_y, w, curr_h, radius, bar_color);
} }
} }
@ -1755,64 +1835,57 @@ void Draw_Volume_Bar(uint16_t x, uint16_t y, uint8_t volume_level,uint8_t scale,
/** /**
* @brief * @brief 线 + +
* @param x: X坐标 * @param x/y:
* @param y: Y坐标 * @param battery_percent: 0-100
* @param battery_percent: 0-100 * @param scale:
* @param scale: 1=2=2 * @param border_color / bg_color / fill_color:
* @param border_color: RGB值WHITE/0xFFFF
* @param bg_color: BLACK/0x0000
* @param fill_color: WHITE/0xFFFF
*/ */
void Draw_Battery_Icon(uint16_t x, uint16_t y, uint8_t battery_percent,uint8_t scale, uint16_t border_color, uint16_t bg_color, uint16_t fill_color) void Draw_Battery_Icon(uint16_t x, uint16_t y, uint8_t battery_percent,uint8_t scale, uint16_t border_color, uint16_t bg_color, uint16_t fill_color)
{ {
// 1. 基础参数原始尺寸按scale缩放 uint16_t bat_w = 22 * scale; /* 主体宽度 */
uint16_t bat_w = 25 * scale; // 电池主体宽度 uint16_t bat_h = 12 * scale; /* 主体高度(更扁) */
uint16_t bat_h = 15 * scale; // 电池主体高度 uint16_t fill_gap = 2 * scale; /* 填充与边框间距 */
uint8_t round_r = 2 * scale; // 电池圆角半径
uint16_t inner_gap = 1 * scale; // 内部边框间隙
uint16_t fill_gap = 2 * scale; // 电量填充区间隙
uint8_t Info[40]; uint8_t Info[40];
uint16_t pole_w = 2 * scale;
uint16_t pole_h = 6 * scale;
uint16_t pole_x = x + bat_w;
uint16_t pole_y = y + (bat_h - pole_h) / 2;
uint16_t fill_w;
uint16_t fill_h;
uint16_t text_x;
LCD_FillByColor(x,y,240,y+bat_h,BLACK); /* 清到右缘,避免百分比位数变化残留 */
LCD_FillByColor(x, y, 240, y + ((bat_h > 16) ? bat_h : 16), BLACK);
// 2. 限制电量范围避免负数或超过100%
if(battery_percent > 100) battery_percent = 100; if(battery_percent > 100) battery_percent = 100;
if(battery_percent == 0) battery_percent = 0;
// 3. 计算电量填充宽度(按百分比) fill_w = (bat_w - 2 * fill_gap) * battery_percent / 100;
uint16_t fill_w = (bat_w - 2 * fill_gap) * battery_percent / 100; fill_h = bat_h - 2 * fill_gap;
// 电量填充高度留1像素间隙和内部区域匹配
uint16_t fill_h = bat_h - 2 * fill_gap;
// 4. 绘制电池外框(带圆角) /* 1px 线框外轮廓 */
LCD_FillRoundRect(x, y, bat_w, bat_h, round_r, border_color); LCD_DrawRectangle(x, y, x + bat_w - 1, y + bat_h - 1, border_color);
// 5. 绘制电池内部背景(黑色底) /* 内部背景 */
LCD_FillRoundRect(x + inner_gap, y + inner_gap, if(bat_w > 2 && bat_h > 2)
bat_w - 2 * inner_gap, bat_h - 2 * inner_gap,
0, bg_color);
// 6. 绘制电量填充(按百分比动态显示)
if(battery_percent > 0) // 电量>0才绘制填充
{ {
LCD_FillRoundRect(x + fill_gap, y + fill_gap, LCD_FillByColor(x + 1, y + 1, x + bat_w - 1, y + bat_h - 1, bg_color);
fill_w, fill_h,
0, fill_color);
} }
// 7. 绘制电池正极(右上角小矩形,增强视觉效果) /* 电量填充(与百分比成比例) */
uint16_t pole_w = 3 * scale; // 正极宽度 if(battery_percent > 0 && fill_w > 0)
uint16_t pole_h = 7 * scale; // 正极高度 {
uint16_t pole_x = x + bat_w; // 正极X坐标电池右侧 LCD_FillByColor(x + fill_gap, y + fill_gap,
uint16_t pole_y = y + (bat_h - pole_h) / 2; // 正极垂直居中 x + fill_gap + fill_w, y + fill_gap + fill_h,
LCD_FillRoundRect(pole_x, pole_y, pole_w, pole_h, 1 * scale, border_color); fill_color);
}
sprintf ((char*)Info, "%d%%", battery_percent);
LCD_ShowString(x+bat_w+pole_w, y, Info, WHITE, BLACK, 16, 0);
/* 右侧正极小凸起 */
LCD_FillByColor(pole_x, pole_y, pole_x + pole_w, pole_y + pole_h, border_color);
sprintf((char*)Info, "%d%%", battery_percent);
text_x = pole_x + pole_w + 2 * scale;
LCD_ShowString(text_x, y, Info, WHITE, BLACK, 16, 0);
} }
/****************************************************************************** /******************************************************************************