fix(lyric): 全局播放页进度条/按钮带局部重绘回退默认色修复 — 取色主题抽共用(np_grad_row/np_page_bg_row/np_theme_widgets),1s局部重绘也接取色(带底色渐变/进度条fill=accent/track=fg_dim/四钮accent);SDK W_PROGRESS改读opts.bg/fg向后兼容;宿主R1-R3 PASS,0warning;需重编meow_ui.a+四App重链
This commit is contained in:
1 parent
8971f6067b
commit
a82f3f9dfa
5 files changed
+180
-30
No files matched your search
@@ -96,7 +96,7 @@ static void ncp_media_btns_create(void)
|
||||
}
|
||||
|
||||
/* 绘制三控制按钮(prev/next 固定;play/pause 按会话状态只画其一——两钮同位,改画时新圆底盖掉旧)。
|
||||
* 每次刷新播放钮底色/图标(同 now_playing np_refresh_theme:跨主题切换跟手)。 */
|
||||
* 每次刷新播放钮底色/图标(同 now_playing np_theme_widgets:跨主题切换跟手)。 */
|
||||
static void ncp_draw_media_btns(const meow_media_session_t *s)
|
||||
{
|
||||
if (!g_ncp_media_btn_init) ncp_media_btns_create();
|
||||
|
||||
@@ -101,20 +101,34 @@ static void np_apply_lyric_colors(void)
|
||||
meow_lyric_view_set_colors(g_np_lyric, g_np_cc_valid ? &g_np_cc.lyr : NULL);
|
||||
}
|
||||
|
||||
/* 竖向双色渐变填充(无 GPU,逐行整数插值;封面主题背景用)。 */
|
||||
/* 渐变插值(无 GPU,逐行整数;封面主题背景用)。返回 [y0, y0+h) 带内屏幕行 y 的颜色。 */
|
||||
static uint32_t np_grad_row(uint32_t top, uint32_t bottom, int y0, int h, int y)
|
||||
{
|
||||
int t = (h <= 1) ? 0 : (y - y0) * 255 / (h - 1);
|
||||
if (t < 0) t = 0; else if (t > 255) t = 255;
|
||||
int tr = (top >> 16) & 255, tg = (top >> 8) & 255, tb = top & 255;
|
||||
int br = (bottom >> 16) & 255, bg = (bottom >> 8) & 255, bb = bottom & 255;
|
||||
int r = tr + ((br - tr) * t + 128) / 255;
|
||||
int g = tg + ((bg - tg) * t + 128) / 255;
|
||||
int b = tb + ((bb - tb) * t + 128) / 255;
|
||||
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b;
|
||||
}
|
||||
|
||||
/* 竖向双色渐变填充(封面主题背景用;整页/局部共用 np_grad_row,保证局部重绘与整页渐变无缝)。 */
|
||||
static void np_fill_gradient(int x, int y, int w, int h, uint32_t top, uint32_t bottom)
|
||||
{
|
||||
if (w <= 0 || h <= 0) return;
|
||||
int tr = (top >> 16) & 255, tg = (top >> 8) & 255, tb = top & 255;
|
||||
int br = (bottom >> 16) & 255, bg = (bottom >> 8) & 255, bb = bottom & 255;
|
||||
int span = h - 1;
|
||||
for (int yy = 0; yy < h; yy++) {
|
||||
int t = span > 0 ? yy * 255 / span : 0;
|
||||
int r = tr + ((br - tr) * t + 128) / 255;
|
||||
int g = tg + ((bg - tg) * t + 128) / 255;
|
||||
int b = tb + ((bb - tb) * t + 128) / 255;
|
||||
fill_rect(x, y + yy, w, 1, ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b);
|
||||
}
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
fill_rect(x, y + yy, w, 1, np_grad_row(top, bottom, y, h, y + yy));
|
||||
}
|
||||
|
||||
/* 播放页当前主题 · 页背景行色:内容区(状态栏下)屏幕行 y 的背景色。
|
||||
* 取色有效 → 取色渐变(按整页 span 插值:局部重绘进度带逐行取色与整页渐变无缝衔接);
|
||||
* 取色无效 → 返回 0(调用方回退 meow_theme 面)。 */
|
||||
static uint32_t np_page_bg_row(int y)
|
||||
{
|
||||
if (!g_np_cc_valid) return 0;
|
||||
return np_grad_row(g_np_cc.bg_top, g_np_cc.bg_bottom, SB_BAR_H, fb_yres - SB_BAR_H, y);
|
||||
}
|
||||
|
||||
#if 0 /* ================================================================
|
||||
@@ -217,23 +231,43 @@ static void np_widgets_create(void)
|
||||
g_np_init = 1;
|
||||
}
|
||||
|
||||
/* 主题刷新:播放钮底色/图标随当前主题(明暗/风格切换后跟手);批5 封面取色时随 accent。 */
|
||||
static void np_refresh_theme(void)
|
||||
/* 播放页当前主题 → 控件修饰(整页与局部重绘共用同一次派生,避免两处取色逻辑漂移)。
|
||||
* 进度条 meow_progress:opts.bg=轨道、opts.fg=填充(批5b W_PROGRESS 新增支持);
|
||||
* 控制钮 meow_iconbtn:opts.bg=圆底、opts.fg=图标墨色。
|
||||
* 取色有效(g_np_cc_valid):进度条轨道=fg_dim/填充=accent,三钮圆底=accent、图标=accent_fg;
|
||||
* 取色无效:全部清 opts 回主题默认(进度条=surfaceVariant/primary、play/pause=primary/onPrimary、
|
||||
* prev/next=surfaceContainerLow/onSurface——与创建时一致,不回归)。
|
||||
* 每次绘制前调用(np_draw_page 播放分支 / np_repaint_progress),保证主题跟手。 */
|
||||
static void np_theme_widgets(void)
|
||||
{
|
||||
if (!g_np_init) return;
|
||||
const meow_theme *th = meow_theme_get();
|
||||
meow_widget_opts op; memset(&op, 0, sizeof op);
|
||||
op.bg = g_np_cc_valid ? g_np_cc.accent : th->primary;
|
||||
op.fg = g_np_cc_valid ? g_np_cc.accent_fg : th->onPrimary;
|
||||
if (g_np_play) meow_widget_set_opts(g_np_play, &op);
|
||||
if (g_np_pause) meow_widget_set_opts(g_np_pause, &op);
|
||||
if (g_np_cc_valid) {
|
||||
op.bg = g_np_cc.fg_dim; op.fg = g_np_cc.accent; /* 进度条:track=fg_dim / fill=accent */
|
||||
if (g_np_prog) meow_widget_set_opts(g_np_prog, &op);
|
||||
op.bg = g_np_cc.accent; op.fg = g_np_cc.accent_fg; /* 三钮:圆底=accent / 图标=accent_fg */
|
||||
if (g_np_prev) meow_widget_set_opts(g_np_prev, &op);
|
||||
if (g_np_play) meow_widget_set_opts(g_np_play, &op);
|
||||
if (g_np_pause) meow_widget_set_opts(g_np_pause, &op);
|
||||
if (g_np_next) meow_widget_set_opts(g_np_next, &op);
|
||||
return;
|
||||
}
|
||||
/* 取色无效 → 默认主题(回退):清 prog/prev/next 的 opts,play/pause 回主题 primary。 */
|
||||
memset(&op, 0, sizeof op);
|
||||
if (g_np_prog) meow_widget_set_opts(g_np_prog, &op);
|
||||
if (g_np_prev) meow_widget_set_opts(g_np_prev, &op);
|
||||
if (g_np_next) meow_widget_set_opts(g_np_next, &op);
|
||||
if (g_np_play || g_np_pause) {
|
||||
op.bg = th->primary; op.fg = th->onPrimary; /* 主播放钮:强调动作 */
|
||||
if (g_np_play) meow_widget_set_opts(g_np_play, &op);
|
||||
if (g_np_pause) meow_widget_set_opts(g_np_pause, &op);
|
||||
}
|
||||
}
|
||||
|
||||
/* 绘制播放控制三钮(prev/next 固定;play/pause 按会话状态只画其一——两钮同位,改画时
|
||||
* 上一帧残留被新画圆底盖掉)。 */
|
||||
* 上一帧残留被新画圆底盖掉)。控件配色在调用前由 np_theme_widgets 统一挂载取色主题。 */
|
||||
static void np_draw_ctl(const meow_media_session_t *s)
|
||||
{
|
||||
np_refresh_theme();
|
||||
if (g_np_prev) { meow_widget_set_selected(g_np_prev, 0); meow_widget_draw(g_np_prev); }
|
||||
if (g_np_next) { meow_widget_set_selected(g_np_next, 0); meow_widget_draw(g_np_next); }
|
||||
int playing = (s && s->state == MEOW_MEDIA_PLAYING);
|
||||
@@ -379,6 +413,8 @@ static void np_draw_page(int redraw_sb)
|
||||
np_center_text(NP_ARTIST_Y, s->artist, 18, g_np_cc_valid ? g_np_cc.fg_dim : th->on_surface_variant, W - 60);
|
||||
if (s->album[0])
|
||||
np_center_text(NP_ALBUM_Y, s->album, 16, g_np_cc_valid ? g_np_cc.fg_dim : th->on_surface_variant, W - 80);
|
||||
/* 批5b:控件随播放页当前主题(进度条轨道/填充 + 三钮)——整页与局部重绘共用同一次派生。 */
|
||||
np_theme_widgets();
|
||||
/* 进度(SDK meow_progress) */
|
||||
uint32_t pos = meow_media_display_pos(s);
|
||||
np_draw_progress(s, pos, th);
|
||||
@@ -390,15 +426,24 @@ static void np_draw_page(int redraw_sb)
|
||||
if (redraw_sb) draw_statusbar();
|
||||
}
|
||||
|
||||
/* 仅重绘进度带 + 按钮(元数据/源变化时整页;纯进度变化时局部)。 */
|
||||
/* 仅重绘进度带 + 按钮(元数据/源变化时整页;纯进度变化时局部)。
|
||||
* 批5b:局部重绘也走播放页当前主题——进度带/按钮带底色用取色渐变(np_page_bg_row 与整页同 span
|
||||
* 无缝衔接),进度条/三钮经 np_theme_widgets 挂取色色;无取色回退 meow_theme 面/默认控件色。 */
|
||||
static void np_repaint_progress(void)
|
||||
{
|
||||
const meow_ui_theme_t *th = s_ui_theme();
|
||||
const meow_media_session_t *s = meow_media_current();
|
||||
if (!s || s->state == MEOW_MEDIA_STOPPED) return;
|
||||
np_cover_theme_update(); /* 取色当前主题(幂等,封面路径未变不重取) */
|
||||
uint32_t pos = meow_media_display_pos(s);
|
||||
/* 清进度带 + 控制带,再重绘(只脏这两带,不整屏)。 */
|
||||
fill_rect(0, NP_TIME_Y, fb_xres, NP_BTN_Y + NP_PLAY_R - NP_TIME_Y, th->surface);
|
||||
/* 清进度带 + 控制带,再重绘(只脏这两带,不整屏);底色随取色渐变或主题面。 */
|
||||
if (g_np_cc_valid) {
|
||||
for (int yy = NP_TIME_Y; yy < NP_BTN_Y + NP_PLAY_R; yy++)
|
||||
fill_rect(0, yy, fb_xres, 1, np_page_bg_row(yy));
|
||||
} else {
|
||||
fill_rect(0, NP_TIME_Y, fb_xres, NP_BTN_Y + NP_PLAY_R - NP_TIME_Y, th->surface);
|
||||
}
|
||||
np_theme_widgets(); /* 进度条/按钮随取色主题(或回退默认) */
|
||||
np_draw_progress(s, pos, th);
|
||||
np_draw_ctl(s);
|
||||
meow_dirty_add(0, NP_TIME_Y, fb_xres, NP_BTN_Y + NP_PLAY_R - NP_TIME_Y);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "meow_ui_internal.h" /* meow_ui_back_buf/pitch/bpp */
|
||||
#include "np_gesture.h" /* 批4:双页方向感知手势决策(纯逻辑,宿主可单测) */
|
||||
#include "meow_lyric_view.h" /* 批2:歌词页控件(批4接入,数据批3 meow_media_lyric_*) */
|
||||
#include "meow_img_color.h" /* 批5b:封面取色主题派生(局部重绘进度条/按钮带取色用例) */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -59,6 +60,8 @@ static void rd_px(int x, int y, unsigned short *p)
|
||||
else *p = (unsigned short)(*(unsigned int *)(bb + (size_t)y * line + (size_t)x * 4) >> 16);
|
||||
}
|
||||
static unsigned short px565(int x, int y) { unsigned short p; rd_px(x, y, &p); return p; }
|
||||
static unsigned short rgb565(uint32_t c)
|
||||
{ return (unsigned short)(((c >> 8) & 0xF800) | ((c >> 5) & 0x07E0) | ((c >> 3) & 0x001F)); }
|
||||
static int region_nonbg(int x, int y, int w, int h, uint32_t bg)
|
||||
{
|
||||
unsigned short bg565 = ((bg >> 8) & 0xF800) | ((bg >> 5) & 0x07E0) | ((bg >> 3) & 0x001F);
|
||||
@@ -179,6 +182,103 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ============ R1 批5b:局部重绘取色——进度条 fill=accent/track=fg_dim + 默认回退 ============
|
||||
* 镜像 np_theme_widgets(取色有效→进度条 opts.bg=fg_dim/opts.fg=accent)+ np_draw_progress。
|
||||
* 用「直接 fill_rect 参考像素」对比,绕开 565 精度差异(同一渲染器同色 → 同 565)。 */
|
||||
printf("R1 progress cover-theme fill/track + default fallback\n");
|
||||
meow_ui_set_style(MEOW_STYLE_MD3);
|
||||
meow_theme_set_mode(MEOW_THEME_DARK);
|
||||
th = meow_theme_get();
|
||||
meow_img_color_theme cc; memset(&cc, 0, sizeof cc);
|
||||
meow_img_color_derive(0xE53935u, 0x1E88E5u, th, &cc); /* 红/蓝两色 → 派生取色主题 */
|
||||
|
||||
/* 覆盖取色:进度条 fill=accent / track=fg_dim */
|
||||
{
|
||||
meow_widget_opts op; memset(&op, 0, sizeof op);
|
||||
op.bg = cc.fg_dim; op.fg = cc.accent;
|
||||
meow_widget_set_opts(prog, &op);
|
||||
meow_ui_clear(0);
|
||||
meow_ui_fill_rect(NP_PROG_X, NP_PROG_Y, 5, 6, cc.accent); /* fill 参考 */
|
||||
unsigned short ref_fill = px565(NP_PROG_X + 2, NP_PROG_Y + 3);
|
||||
meow_ui_clear(0);
|
||||
meow_ui_fill_rect(NP_PROG_X + NP_PROG_W - 4, NP_PROG_Y, 3, 6, cc.fg_dim); /* track 参考 */
|
||||
unsigned short ref_track = px565(NP_PROG_X + NP_PROG_W - 3, NP_PROG_Y + 3);
|
||||
meow_ui_clear(0);
|
||||
meow_progress_set(prog, 50);
|
||||
meow_widget_draw(prog);
|
||||
int fill_x = NP_PROG_X + NP_PROG_W / 4; /* 50% 填充区内 */
|
||||
int track_x = NP_PROG_X + NP_PROG_W - 4; /* 尾部轨道区 */
|
||||
CHECK(px565(fill_x, NP_PROG_Y + 3) == ref_fill, "cover: progress fill == accent");
|
||||
CHECK(px565(track_x, NP_PROG_Y + 3) == ref_track, "cover: progress track == fg_dim");
|
||||
|
||||
/* 默认回退:清 opts → 回到主题 primary/surfaceVariant(无取色回退默认) */
|
||||
memset(&op, 0, sizeof op);
|
||||
meow_widget_set_opts(prog, &op);
|
||||
meow_ui_clear(0);
|
||||
meow_ui_fill_rect(NP_PROG_X, NP_PROG_Y, 5, 6, th->primary);
|
||||
unsigned short ref_pri = px565(NP_PROG_X + 2, NP_PROG_Y + 3);
|
||||
meow_ui_clear(0);
|
||||
meow_progress_set(prog, 50);
|
||||
meow_widget_draw(prog);
|
||||
CHECK(px565(fill_x, NP_PROG_Y + 3) == ref_pri, "default: progress fill == theme primary");
|
||||
CHECK(px565(fill_x, NP_PROG_Y + 3) != ref_fill, "default vs cover fill differ");
|
||||
}
|
||||
|
||||
/* ============ R2 批5b:进度/按钮带底色随取色渐变(非默认 surface) ============
|
||||
* 镜像 np_repaint_progress 的带底色分支(np_page_bg_row 按整页 span 插值)。
|
||||
* 旧 bug:本地重绘用 th->surface 清带 → 带内被刷成默认色;现应取色渐变且 != surface。 */
|
||||
printf("R2 band background uses cover gradient (not default surface)\n");
|
||||
{
|
||||
#define NP_SB_H 28
|
||||
int H = 720;
|
||||
meow_ui_clear(0);
|
||||
for (int yy = NP_TIME_Y; yy < NP_BTN_Y + NP_PLAY_R; yy++) {
|
||||
int t = (H - NP_SB_H <= 1) ? 0 : (yy - NP_SB_H) * 255 / (H - NP_SB_H - 1);
|
||||
if (t < 0) t = 0; else if (t > 255) t = 255;
|
||||
int tr = (cc.bg_top >> 16) & 255, tg = (cc.bg_top >> 8) & 255, tb = cc.bg_top & 255;
|
||||
int br = (cc.bg_bottom >> 16) & 255, bg = (cc.bg_bottom >> 8) & 255, bb = cc.bg_bottom & 255;
|
||||
int r = tr + ((br - tr) * t + 128) / 255;
|
||||
int g = tg + ((bg - tg) * t + 128) / 255;
|
||||
int b = tb + ((bb - tb) * t + 128) / 255;
|
||||
meow_ui_fill_rect(0, yy, 480, 1, ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b);
|
||||
}
|
||||
unsigned short bandpx = px565(10, NP_TIME_Y + 55);
|
||||
CHECK(bandpx != rgb565(th->surface), "cover: band bg != default surface");
|
||||
CHECK(bandpx != 0, "cover: band bg rendered");
|
||||
}
|
||||
|
||||
/* ============ R3 批5b:控制三钮(含 prev/next)随取色 accent + 默认回退 ============
|
||||
* 镜像 np_theme_widgets:取色有效→四钮 opts.bg=accent/opts.fg=accent_fg(prev/next 不再默认底色)。 */
|
||||
printf("R3 control buttons follow cover accent\n");
|
||||
{
|
||||
meow_widget_opts op; memset(&op, 0, sizeof op);
|
||||
op.bg = cc.accent; op.fg = cc.accent_fg;
|
||||
meow_widget_set_opts(prev, &op);
|
||||
meow_widget_set_opts(next, &op);
|
||||
meow_widget_set_opts(play, &op);
|
||||
meow_widget_set_opts(pause, &op);
|
||||
meow_ui_clear(0);
|
||||
meow_ui_fill_rect(NP_PREV_CX - 2, NP_BTN_Y - 18, 4, 2, cc.accent); /* accent 参考(圆底上方、图标外) */
|
||||
unsigned short ref_acct = px565(NP_PREV_CX, NP_BTN_Y - 17);
|
||||
meow_ui_clear(0);
|
||||
meow_widget_draw(prev); /* r=22,cy-17 在圆内且高于图标(cy-13) */
|
||||
CHECK(px565(NP_PREV_CX, NP_BTN_Y - 17) == ref_acct, "cover: prev bg == accent");
|
||||
meow_ui_clear(0);
|
||||
meow_widget_draw(play); /* r=30,cy-26 在圆内且高于图标(cy-18) */
|
||||
CHECK(px565(NP_PLAY_CX, NP_BTN_Y - 26) == ref_acct, "cover: play bg == accent");
|
||||
|
||||
/* 默认回退:清 prev/next opts → 回 surfaceContainerLow(无取色不回归旧形态) */
|
||||
memset(&op, 0, sizeof op);
|
||||
meow_widget_set_opts(prev, &op);
|
||||
meow_widget_set_opts(next, &op);
|
||||
meow_ui_clear(0);
|
||||
meow_ui_fill_rect(NP_PREV_CX - 2, NP_BTN_Y - 18, 4, 2, th->surfaceContainerLow);
|
||||
unsigned short ref_def = px565(NP_PREV_CX, NP_BTN_Y - 17);
|
||||
meow_ui_clear(0);
|
||||
meow_widget_draw(prev);
|
||||
CHECK(px565(NP_PREV_CX, NP_BTN_Y - 17) == ref_def, "default: prev bg == surfaceContainerLow");
|
||||
}
|
||||
|
||||
/* ============ G5 双页手势方向感知(np_gesture.h,纯逻辑) ============ */
|
||||
printf("G5 dual-page direction-aware gestures\n");
|
||||
/* 播放页:右→左滑 → 进歌词页 */
|
||||
|
||||
Reference in new issue
Block a user