feat(sdk): M6.39批 — LazyGrid/LazyColumn/LazyRow MD3容器化 + SDK全局App内底部上滑回桌面(系统手势优先)
- meow_ui_widget.c: W_LIST/meow_list/LazyColumn/LazyRow默认container=1(MD3圆角卡surfaceContainer+tonal选中+卡内按压+去分隔线) + 新增meow_list_set_container; 平坦回退set_container(0) - meow_lazygrid.c: lg_draw_cell容器化(卡内缩8,surfaceContainer圆角+tonal选中+按压) - meow_ui_input.c: 新增meow_ui_input_is_home_swipe(镜像np_home_gesture:屏底28px热区+上移65px+竖向主导,与左缘返回/列表中滑互斥) + MEOW_EV_HOME分发→meow_ui_nav_request_exit(系统保留手势**优先于App on_swipe**,任意App内生效→MSG_NAV EXIT→批①保活回桌面; 不调request_exit避免进程退出断送保活) - 声明: meow_ui_input.h / meow_ui_widgets.h 各追加 - 宿主测试: test_meow_ui_home_gesture 19-0 / test_meow_ui_lazygrid 32-0, 0warning
This commit is contained in:
1 parent
d0a5901ffb
commit
501867b362
7 files changed
+350
-32
No files matched your search
@@ -407,6 +407,10 @@ meow_widget *meow_list_create(int x, int y, int w, int h, int count,
|
||||
t->owner = meow_ui_activity_active();
|
||||
t->state = MEOW_WS_ENABLED;
|
||||
t->count = count; t->src = src; t->ctx = ctx; t->sel = 0;
|
||||
/* M6.37 P1:SDK 默认列表(meow_list_create / meow_lazycolumn_create / meow_lazyrow_create,皆 W_LIST)
|
||||
* 走 MD3 容器模式——每项=surfaceContainer 圆角卡 + 项间空隙 + 去分隔线 + 卡内 tonal 选中/按压,
|
||||
* 与 meow_listview 容器同范式(全局统一)。需扁平的宿主可显式 meow_list_set_container(w,0) 回退。 */
|
||||
t->container = 1;
|
||||
meow_draw_widget_register(t);
|
||||
return t;
|
||||
}
|
||||
@@ -1014,6 +1018,17 @@ int meow_list_tap_at(meow_widget *w, int x, int y)
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* MD3 容器模式(W_LIST 共用,§5.5/§5.8.6):0=扁平满宽项+分隔线(回退);1=每项外套 surfaceContainer
|
||||
* 圆角卡+项间空隙(去分隔线),选中=primaryContainer/按压=primary α26(卡内 tonal)。
|
||||
* 覆盖 meow_list_create / meow_lazycolumn_create / meow_lazyrow_create。返回 0=成功;无效=负值。 */
|
||||
int meow_list_set_container(meow_widget *w, int on)
|
||||
{
|
||||
if (!w || w->type != W_LIST) return -1;
|
||||
w->container = on ? 1 : 0;
|
||||
meow_gfx_mark_dirty(w->x, w->y, w->w, w->h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
/* §5.5 结构化列表(W_LISTVIEW):行=图标+标题+副标题+右侧操作+选中
|
||||
* ------------------------------------------------------------
|
||||
@@ -1730,7 +1745,11 @@ void meow_widget_draw(meow_widget *w)
|
||||
}
|
||||
case W_LIST: {
|
||||
/* §5.8.6 列表容器(LazyColumn/LazyRow):只画可见项(虚拟化)+ 滚动偏移。
|
||||
* 纵向=行高 item_h(默认 44,兼容既有 meow_list_create);横向=LazyRow(列宽=item_h)。 */
|
||||
* 纵向=行高 item_h(默认 44,兼容既有 meow_list_create);横向=LazyRow(列宽=item_h)。
|
||||
* MD3 容器模式(w->container=1,默认):每项外套 surfaceContainer 圆角卡(12dp)+ 项间空隙
|
||||
* (去分隔线),选中=primaryContainer/按压=primary α26(卡内 tonal),与 meow_listview 容器同范式;
|
||||
* 卡在项内交叉轴内缩 MEOW_LISTV_CARD_MARGIN、滚动轴对称内缩 MEOW_LISTV_CARD_GAP(行中心=卡中心)。
|
||||
* 非容器(meow_list_set_container(0) 回退):满幅扁平行 + primary 选中 + onSurfaceVariant 分隔线。 */
|
||||
int pad = 16;
|
||||
int item = list_item(w);
|
||||
int vp = w->horizontal ? w->w : w->h;
|
||||
@@ -1747,36 +1766,70 @@ void meow_widget_draw(meow_widget *w)
|
||||
* 画到视口外 → 标脏并上屏 → 标题栏/底部残留脏区,P3)。 */
|
||||
int vx0 = w->x, vy0 = w->y, vx1 = w->x + w->w, vy1 = w->y + w->h;
|
||||
int thh = meow_ui_text_height(th->font_body);
|
||||
int cm = w->container ? MEOW_LISTV_CARD_MARGIN : 0; /* 卡交叉轴内缩(纵向=水平→横向=垂直) */
|
||||
int cgap = w->container ? MEOW_LISTV_CARD_GAP : 0; /* 卡滚动轴对称内缩(去分隔线、留空隙) */
|
||||
for (int i = first; i < last; i++) {
|
||||
char label[64] = "";
|
||||
if (!w->src || !w->src(i, label, (int)sizeof label, w->ctx)) continue;
|
||||
int pos = i * item - off; /* 相对容器起点的可视位置 */
|
||||
int sel = (i == w->sel);
|
||||
if (w->horizontal) {
|
||||
int rx = w->x + pos;
|
||||
if (rx >= vx1) break; /* 完全在右缘外 */
|
||||
if (rx + item <= vx0) continue; /* 完全在左缘外(滚出残余) */
|
||||
int cl = rx > vx0 ? rx : vx0; /* 可见左界 */
|
||||
int cr = (rx + item) < vx1 ? (rx + item) : vx1; /* 可见右界 */
|
||||
if (i == w->sel) meow_ui_fill_rect(cl, w->y, cr - cl, w->h, th->primary);
|
||||
uint32_t col = (i == w->sel) ? 0xFFFFFF : th->onSurface;
|
||||
int ctop = w->y + cm; /* 卡顶(交叉轴内缩) */
|
||||
int chh = w->h - 2 * cm; /* 卡高 */
|
||||
int clft = rx + cgap / 2; /* 卡左(滚动轴对称内缩) */
|
||||
int cwid = item - cgap; /* 卡宽 */
|
||||
int press = meow_input_touch_down() &&
|
||||
meow_input_touch_x() >= rx && meow_input_touch_x() < rx + item &&
|
||||
meow_input_touch_y() >= w->y && meow_input_touch_y() < w->y + w->h;
|
||||
if (w->container) {
|
||||
meow_gfx_fill_round(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->surfaceContainer);
|
||||
if (sel) meow_gfx_fill_round(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->primaryContainer);
|
||||
else if (press) meow_gfx_fill_round_alpha(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->primary, 26);
|
||||
} else {
|
||||
if (sel) meow_ui_fill_rect(cl, w->y, cr - cl, w->h, th->primary);
|
||||
}
|
||||
uint32_t col = sel ? (w->container ? th->onPrimaryContainer : 0xFFFFFF) : th->onSurface;
|
||||
int ty = w->y + (w->h - thh) / 2;
|
||||
if (rx >= vx0 && rx + item <= vx1) /* 仅整项可见才画文本(防泄漏) */
|
||||
meow_ui_text_center(rx + item / 2, ty, label, th->font_body, col);
|
||||
int sxp = rx + item - 1; /* 分隔线:仅当落在可见区 */
|
||||
if (sxp >= cl && sxp < cr) meow_ui_fill_rect(sxp, w->y, 1, w->h, th->onSurfaceVariant);
|
||||
if (!w->container) { /* 非容器才画分隔线(容器模式去冗余) */
|
||||
int sxp = rx + item - 1; /* 分隔线:仅当落在可见区 */
|
||||
if (sxp >= cl && sxp < cr) meow_ui_fill_rect(sxp, w->y, 1, w->h, th->onSurfaceVariant);
|
||||
}
|
||||
} else {
|
||||
int ry = w->y + pos;
|
||||
if (ry >= vy1) break; /* 完全在底缘外 */
|
||||
if (ry + item <= vy0) continue; /* 完全在顶缘外(滚出残余) */
|
||||
int cl = ry > vy0 ? ry : vy0; /* 可见顶界 */
|
||||
int cr = (ry + item) < vy1 ? (ry + item) : vy1; /* 可见底界 */
|
||||
if (i == w->sel) meow_ui_fill_rect(w->x, cl, w->w, cr - cl, th->primary);
|
||||
uint32_t col = (i == w->sel) ? 0xFFFFFF : th->onSurface;
|
||||
int clft = w->x + cm; /* 卡左(交叉轴内缩) */
|
||||
int cwid = w->w - 2 * cm; /* 卡宽 */
|
||||
int ctop = ry + cgap / 2; /* 卡顶(滚动轴对称内缩) */
|
||||
int chh = item - cgap; /* 卡高 */
|
||||
int press = meow_input_touch_down() &&
|
||||
meow_input_touch_x() >= w->x && meow_input_touch_x() < w->x + w->w &&
|
||||
meow_input_touch_y() >= ry && meow_input_touch_y() < ry + item;
|
||||
if (w->container) {
|
||||
meow_gfx_fill_round(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->surfaceContainer);
|
||||
if (sel) meow_gfx_fill_round(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->primaryContainer);
|
||||
else if (press) meow_gfx_fill_round_alpha(clft, ctop, cwid, chh, MEOW_LISTV_CARD_RADIUS, th->primary, 26);
|
||||
} else {
|
||||
if (sel) meow_ui_fill_rect(w->x, cl, w->w, cr - cl, th->primary);
|
||||
}
|
||||
uint32_t col = sel ? (w->container ? th->onPrimaryContainer : 0xFFFFFF) : th->onSurface;
|
||||
int txx = (w->container ? clft : w->x) + pad; /* 卡内文本左缘 */
|
||||
int ty = ry + (item - thh) / 2;
|
||||
if (ty >= vy0 && ty + thh <= vy1) /* 文本不越界才画(防标题/底部泄漏) */
|
||||
meow_ui_text(w->x + pad, ty, label, th->font_body, col);
|
||||
int sy = ry + item - 1; /* 分隔线:仅当落在可见区 */
|
||||
if (sy >= cl && sy < cr) meow_ui_fill_rect(w->x, sy, w->w, 1, th->onSurfaceVariant);
|
||||
meow_ui_text(txx, ty, label, th->font_body, col);
|
||||
if (!w->container) { /* 非容器才画分隔线(容器模式去冗余) */
|
||||
int sy = ry + item - 1; /* 分隔线:仅当落在可见区 */
|
||||
if (sy >= cl && sy < cr) meow_ui_fill_rect(w->x, sy, w->w, 1, th->onSurfaceVariant);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disabled) meow_ui_fill_rect_alpha(w->x, w->y, w->w, w->h, th->onSurface, 90);
|
||||
|
||||
Reference in new issue
Block a user