style(bt): 后台管理页行改MD3圆角卡+8px外距(bgm_row_card_y/h,卡高48行距56上下对称,删除分隔线,按压限卡内,按钮相对卡定位恒等)+test_bg_row_card PASS,0warning
This commit is contained in:
1 parent
7a276f609e
commit
2db87b2c5c
2 files changed
+129
-9
No files matched your search
@@ -6,6 +6,8 @@
|
|||||||
* 列表(live=1 约 2s 重扫,实时增删):
|
* 列表(live=1 约 2s 重扫,实时增删):
|
||||||
* - 每后台 App 一行 SUB_ROW:label=名字,sub=「CPU x% · yMB · 状态」,**行最右一个「杀」按钮**
|
* - 每后台 App 一行 SUB_ROW:label=名字,sub=「CPU x% · yMB · 状态」,**行最右一个「杀」按钮**
|
||||||
* (sub_page_t.row_draw 行自绘 + row_tap 自定义命中:命中按钮区=kill 该 App;行体不响应)。
|
* (sub_page_t.row_draw 行自绘 + row_tap 自定义命中:命中按钮区=kill 该 App;行体不响应)。
|
||||||
|
* - 行=MD3 圆角卡(meow_gfx_fill_round r=12 surfaceContainer;卡在行高内上下对称内缩
|
||||||
|
* BGM_CARD_GAP/2,行中心=卡中心,相邻卡 8px 外距——与主界面列表/ ncm 歌单同手法)。
|
||||||
* - 空态「无后台 App」。
|
* - 空态「无后台 App」。
|
||||||
* 数据源=amsd FG/BG 注册表(后台常驻集=launcher meow_bg 表,EV BG/FG 上报进 amsd)+ 每进程
|
* 数据源=amsd FG/BG 注册表(后台常驻集=launcher meow_bg 表,EV BG/FG 上报进 amsd)+ 每进程
|
||||||
* pcpu/rss(meow_svc_perf 同源 /proc 聚合,本页在 launcher 内同口径取)。
|
* pcpu/rss(meow_svc_perf 同源 /proc 聚合,本页在 launcher 内同口径取)。
|
||||||
@@ -24,6 +26,13 @@
|
|||||||
#define BGM_BTN_W 46
|
#define BGM_BTN_W 46
|
||||||
#define BGM_BTN_H 34
|
#define BGM_BTN_H 34
|
||||||
|
|
||||||
|
/* 圆角卡列表项外边距(item margin/gap):相邻卡片间可见空隙 px。SDK listview 行距(=SUB_ITEM_H)
|
||||||
|
* 不变——卡片在其行高内上下对称内缩 BGM_CARD_GAP/2,故行内内容(按行高垂直居中)仍落卡中心;
|
||||||
|
* 相邻卡顶间距恒=SUB_ITEM_H=卡高+BGM_CARD_GAP。要求偶数,保证上下对称。 */
|
||||||
|
#define BGM_CARD_GAP 8
|
||||||
|
static inline int bgm_row_card_y(int row_top) { return row_top + BGM_CARD_GAP / 2; }
|
||||||
|
static inline int bgm_row_card_h(int h) { return h - BGM_CARD_GAP; }
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct app *apps;
|
struct app *apps;
|
||||||
int napps;
|
int napps;
|
||||||
@@ -177,13 +186,15 @@ static int bgm_rows(void *ctx, sub_row_t *rbuf, int max)
|
|||||||
/* kill 通道(bgmgr_kill_all 的函数指针签名:void(*)(const char*)) */
|
/* kill 通道(bgmgr_kill_all 的函数指针签名:void(*)(const char*)) */
|
||||||
static void bgm_kill_fn(const char *app_id) { meow_bg_terminate(app_id); }
|
static void bgm_kill_fn(const char *app_id) { meow_bg_terminate(app_id); }
|
||||||
|
|
||||||
/* ---- 行内杀按钮矩形(绘制与命中共用;行视口矩形 rx,ry,rw,rh → 右侧 46×34 圆角钮)---- */
|
/* ---- 行内杀按钮矩形(绘制与命中共用;行视口矩形 rx,ry,rw,rh → 右侧 46×34 圆角钮)----
|
||||||
|
* 卡在行高内上下对称内缩 BGM_CARD_GAP/2(行中心=卡中心);按钮垂直居中于卡内,故其中心
|
||||||
|
* =卡中心=行中心。命中矩形仍为整行距(row_tap 传整行视口),按钮几何不变 → 卡内缩后命中不破。 */
|
||||||
static void bgm_btn_rect(int rx, int ry, int rw, int rh, int *bx, int *by, int *bw, int *bh)
|
static void bgm_btn_rect(int rx, int ry, int rw, int rh, int *bx, int *by, int *bw, int *bh)
|
||||||
{
|
{
|
||||||
*bw = BGM_BTN_W;
|
*bw = BGM_BTN_W;
|
||||||
*bh = BGM_BTN_H;
|
*bh = BGM_BTN_H;
|
||||||
*bx = rx + rw - 12 - BGM_BTN_W;
|
*bx = rx + rw - 12 - BGM_BTN_W;
|
||||||
*by = ry + (rh - BGM_BTN_H) / 2;
|
*by = bgm_row_card_y(ry) + (bgm_row_card_h(rh) - BGM_BTN_H) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 行完全自绘(sub_page_t.row_draw;覆盖默认 renderer)----
|
/* ---- 行完全自绘(sub_page_t.row_draw;覆盖默认 renderer)----
|
||||||
@@ -195,18 +206,24 @@ static void bgm_row_draw(void *ctx, int idx, sub_row_t *r,
|
|||||||
bgm_ctx_t *b = ctx;
|
bgm_ctx_t *b = ctx;
|
||||||
const meow_theme *mt = meow_theme_get();
|
const meow_theme *mt = meow_theme_get();
|
||||||
int i = r->act;
|
int i = r->act;
|
||||||
|
|
||||||
|
/* MD3 圆角卡:行高内上下对称内缩 BGM_CARD_GAP/2(行中心=卡中心),替代扁平行+底部分隔线。 */
|
||||||
|
int cy = bgm_row_card_y(y);
|
||||||
|
int ch = bgm_row_card_h(h);
|
||||||
|
meow_gfx_fill_round(x, cy, w, ch, 12, mt->surfaceContainer);
|
||||||
|
if (state & MEOW_LISTVIEW_ST_PRESSED)
|
||||||
|
meow_gfx_fill_round_alpha(x, cy, w, ch, 12, mt->primary, 26); /* 按压态(实时,限卡内) */
|
||||||
|
|
||||||
if (i < 0 || i >= b->n) { /* 空态行 */
|
if (i < 0 || i >= b->n) { /* 空态行 */
|
||||||
int th = meow_ui_text_height(18);
|
int th = meow_ui_text_height(18);
|
||||||
meow_ui_text_center(x + w / 2, y + (h - th) / 2,
|
meow_ui_text_center(x + w / 2, cy + (ch - th) / 2,
|
||||||
r->label ? r->label : meow_str_zh("bgmgr.empty", "无后台 App"),
|
r->label ? r->label : meow_str_zh("bgmgr.empty", "无后台 App"),
|
||||||
18, mt->onSurfaceVariant);
|
18, mt->onSurfaceVariant);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state & MEOW_LISTVIEW_ST_PRESSED)
|
|
||||||
meow_ui_fill_rect_alpha(x, y, w, h, mt->primary, 26); /* 按压态(实时) */
|
|
||||||
int th = meow_ui_text_height(20), tsub = meow_ui_text_height(16);
|
int th = meow_ui_text_height(20), tsub = meow_ui_text_height(16);
|
||||||
int rx = x + 16; /* 左内边距 */
|
int rx = x + 16; /* 左内边距 */
|
||||||
int ry = y + (h - (th + tsub + 4)) / 2;
|
int ry = cy + (ch - (th + tsub + 4)) / 2; /* 内容在卡内垂直居中(行中心=卡中心) */
|
||||||
if (r->label) meow_ui_text(rx, ry, r->label, 20, mt->onSurface);
|
if (r->label) meow_ui_text(rx, ry, r->label, 20, mt->onSurface);
|
||||||
if (r->sub) meow_ui_text(rx, ry + th + 4, r->sub, 16, mt->onSurfaceVariant);
|
if (r->sub) meow_ui_text(rx, ry + th + 4, r->sub, 16, mt->onSurfaceVariant);
|
||||||
/* 行内杀按钮(圆角框 + 「杀」;error=红=杀) */
|
/* 行内杀按钮(圆角框 + 「杀」;error=红=杀) */
|
||||||
@@ -215,9 +232,6 @@ static void bgm_row_draw(void *ctx, int idx, sub_row_t *r,
|
|||||||
int bth = meow_ui_text_height(16);
|
int bth = meow_ui_text_height(16);
|
||||||
if (bth > bh) bth = bh;
|
if (bth > bh) bth = bh;
|
||||||
meow_ui_text_center(bx + bw / 2, by + (bh - bth) / 2, "杀", 16, mt->error);
|
meow_ui_text_center(bx + bw / 2, by + (bh - bth) / 2, "杀", 16, mt->error);
|
||||||
/* 底部分隔线 */
|
|
||||||
if (y + h - 1 <= fb_yres)
|
|
||||||
meow_ui_fill_rect(x, y + h - 1, w, 1, mt->outlineVariant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 行内自定义命中(sub_page_t.row_tap;仅按钮区 kill,行体不响应/不误杀)---- */
|
/* ---- 行内自定义命中(sub_page_t.row_tap;仅按钮区 kill,行体不响应/不误杀)---- */
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/* meow_launcherd/test_bg_row_card.c — 宿主验证:后台管理页(bg_page)MD3 圆角卡行 + 行内杀按钮
|
||||||
|
* 的几何与命中(纯整数运算,不链 SDK / 不开设备):
|
||||||
|
* gcc -Wall -Wextra test_bg_row_card.c -o test_bg_row_card && ./test_bg_row_card
|
||||||
|
*
|
||||||
|
* 断言集(对应「相邻 item 顶之间 = item 高 + gap」的可见形式):
|
||||||
|
* ① 卡高 = 行高 - BGM_CARD_GAP;卡在其行高内上下对称内缩 gap/2(行中心=卡中心);
|
||||||
|
* ② 相邻卡顶间距 = SUB_ITEM_H(= 卡高 + gap;SDK 行距不变),卡片间可见外距 = gap;
|
||||||
|
* ③ 杀按钮垂直居中于卡(中心=卡中心=行中心),完整落卡内,右缘距行右 12px;
|
||||||
|
* ④ 命中不破:卡内缩后按钮几何不变(相对整行视口)——按钮区内点按命中(1),
|
||||||
|
* 行体/卡内空白点按不命中(0);命中矩形仍为整行距;
|
||||||
|
* ⑤ 滚动偏移只整体平移,不改变上述间距/对称/命中。
|
||||||
|
*
|
||||||
|
* 几何公式与 patch_v2/meow_launcherd/bg_page.c 的 bgm_row_card_y/bgm_row_card_h/bgm_btn_rect 同源。
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define SUB_ITEM_H 56 /* 行距(SDK listview item_h,subpage.c,不变) */
|
||||||
|
#define BGM_CARD_GAP 8
|
||||||
|
#define BGM_BTN_W 46
|
||||||
|
#define BGM_BTN_H 34
|
||||||
|
|
||||||
|
/* 与 bg_page.c bgm_row_card_y / bgm_row_card_h 同源(上下对称内缩)。 */
|
||||||
|
static int bgm_row_card_y(int row_top) { return row_top + BGM_CARD_GAP / 2; }
|
||||||
|
static int bgm_row_card_h(int h) { return h - BGM_CARD_GAP; }
|
||||||
|
|
||||||
|
/* 与 bg_page.c bgm_btn_rect 同源(按钮垂直居中于卡;卡中心=行中心 → 命中不破)。 */
|
||||||
|
static void bgm_btn_rect(int rx, int ry, int rw, int rh, int *bx, int *by, int *bw, int *bh)
|
||||||
|
{
|
||||||
|
*bw = BGM_BTN_W;
|
||||||
|
*bh = BGM_BTN_H;
|
||||||
|
*bx = rx + rw - 12 - BGM_BTN_W;
|
||||||
|
*by = bgm_row_card_y(ry) + (bgm_row_card_h(rh) - BGM_BTN_H) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 行顶 = list_y + idx*item - off(SDK listview 布局:行距=item)。 */
|
||||||
|
static int row_top(int idx, int item, int list_y, int off) { return list_y + idx * item - off; }
|
||||||
|
|
||||||
|
/* 复刻 bgm_row_tap 的按钮命中判定(仅几何):命中按钮区=1,行体/卡内空白=0。 */
|
||||||
|
static int btn_hit(int tx, int ty, int rx, int ry, int rw, int rh)
|
||||||
|
{
|
||||||
|
int bx, by, bw, bh; bgm_btn_rect(rx, ry, rw, rh, &bx, &by, &bw, &bh);
|
||||||
|
if (tx < bx || tx >= bx + bw || ty < by || ty >= by + bh) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
const int item = SUB_ITEM_H;
|
||||||
|
const int gap = BGM_CARD_GAP;
|
||||||
|
const int list_y = 100; /* 内容区顶缘(SUB_CONT_TOP 等值,任意值皆可) */
|
||||||
|
const int rw = 480; /* 行视口宽(fb_xres,480×720) */
|
||||||
|
const int rx = 0; /* 行视口左缘 */
|
||||||
|
|
||||||
|
int y0 = bgm_row_card_y(row_top(0, item, list_y, 0));
|
||||||
|
int y1 = bgm_row_card_y(row_top(1, item, list_y, 0));
|
||||||
|
int h = bgm_row_card_h(item);
|
||||||
|
|
||||||
|
/* ① 卡相对行顶对称内缩 gap/2;卡高=item-gap;卡高+gap=item */
|
||||||
|
assert(y0 == list_y + gap / 2);
|
||||||
|
assert(h == item - gap);
|
||||||
|
assert(h + gap == item);
|
||||||
|
|
||||||
|
/* ① 相邻卡顶间距 = item(顶到顶 = 卡高 + gap) */
|
||||||
|
assert(y1 - y0 == item);
|
||||||
|
|
||||||
|
/* ② 卡片间可见外距 = gap(卡 0 底 到 卡 1 顶) */
|
||||||
|
assert(y1 - (y0 + h) == gap);
|
||||||
|
|
||||||
|
/* ③ 卡中心 == 行中心(内容按行高居中 → 落卡中心) */
|
||||||
|
assert(y0 - gap / 2 + item / 2 == y0 + h / 2);
|
||||||
|
/* 下行底到卡底 = gap/2(下对称) */
|
||||||
|
assert((list_y + item) - (y0 + h) == gap / 2);
|
||||||
|
|
||||||
|
/* ③④ 杀按钮:相对整行视口定位,垂直居中于卡(中心=卡中心=行中心),完整落卡内,
|
||||||
|
* 右缘距行右 12px;滚动偏移只平移,不改变以上(③④⑤合并循环)。 */
|
||||||
|
for (int off = 0; off <= item; off += item / 2) {
|
||||||
|
int r0 = row_top(0, item, list_y, off);
|
||||||
|
int bx, by, bw, bh; bgm_btn_rect(rx, r0, rw, item, &bx, &by, &bw, &bh);
|
||||||
|
int card_top = bgm_row_card_y(r0);
|
||||||
|
int card_bot = card_top + bgm_row_card_h(item);
|
||||||
|
int row_cy = r0 + item / 2;
|
||||||
|
int card_cy = card_top + bgm_row_card_h(item) / 2;
|
||||||
|
|
||||||
|
/* 按钮完整落卡内(含圆角内边距;上下由卡限,左右由行限) */
|
||||||
|
assert(bx >= rx && bx + bw <= rx + rw);
|
||||||
|
assert(by >= card_top && by + bh <= card_bot);
|
||||||
|
/* 按钮中心 = 卡中心 = 行中心(垂直) */
|
||||||
|
assert(by + bh / 2 == card_cy);
|
||||||
|
assert(by + bh / 2 == row_cy);
|
||||||
|
/* 按钮右缘距行右 12px(与绘制一致) */
|
||||||
|
assert(rx + rw - (bx + bw) == 12);
|
||||||
|
|
||||||
|
/* ④ 命中:按钮中心 → 命中(1);卡内空白(左上圆角内) / 行体左缘 → 不命中(0) */
|
||||||
|
assert(btn_hit(bx + bw / 2, by + bh / 2, rx, r0, rw, item) == 1);
|
||||||
|
assert(btn_hit(card_top + 2, card_top + 2, rx, r0, rw, item) == 0);
|
||||||
|
assert(btn_hit(rx + 16, row_cy, rx, r0, rw, item) == 0);
|
||||||
|
/* 卡上/下外侧(gap 带内)点按 → 不命中(命中仍按整行距,含 gap 带) */
|
||||||
|
assert(btn_hit(rx + rw / 2, r0 + gap / 2 - 1, rx, r0, rw, item) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("PASS bg_row_card_gap=%d card_h=%d top2top=%d visible_gap=%d "
|
||||||
|
"btn_in_card=1 btn_center==row_center=1 hit_unbroken=1\n",
|
||||||
|
gap, h, item, gap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user