Files
MeowOS-SDK/sdk/test_meow_ui_iconbtn.c
T
AskaEth 27a3750e36 SDK: 同步主仓 M15/M16/bug3/MD3 修复 — 时钟 ABI 补全/IME 冷却窗/列表行高派生/形状 token/翻页键
公开 SDK 落后主仓的一批 bugfix(主仓是固件构建源,这些修复已在设备上跑过)。
本次只做「主仓 → 公开仓」单向同步,图像栈方向由主仓侧另一单处理。

时钟 ABI(M16 第二弹,原文件自认「残余未修」):
- meow_ui_time.c 147→345 行:futex 相对超时接管(__timedwait/_cp)、
  timerfd_create/settime/gettime 的 itimerspec 64↔32 双向转换、
  __clock_settime64 越界返 ENOTSUP,另有 4 个纯换算函数
- meow_ui_internal.h:struct meow_time32 / meow_itimerspec32 契约移入内部头
- CLOCK_ABI.md:补接管机制、验证配方与 objdump 证据
- 新增 test_meow_time64.c

IME bug3(成对才有意义):
- meow_ui_ime.c:IME_TAP_COOLDOWN_MS 200 冷却窗 + 打开时二次 drain
- meow_ui_input.c:meow_input_touch_reset() 并在 drain 内调用(复位触摸状态机)
- test_ime_fix.c:新增用例④ stray-tap

列表行高(M15,修用户可见 bug):
- meow_ui_widget.c:listv_item_h() 由主题字体行高派生,不再写死 56
  (两行列表 62 > 56 会让首行标题被裁剪守卫整条跳过)
- include/meow_ui_widgets.h:新增 meow_listview_item_h()
- 新增 test_meow_ui_listview_rowh.c

其余:meow_select.c / meow_ui_dialog.c 统一 MD3 形状 token;
include/meow_ipc.h 补 MSG_KEY_PAGEUP/PAGEDOWN 枚举;
meow_ui_sys.c / meow_cachegov.c 取时统一走 meow_ui_time_ms()。

测试辅助函数标定:tuku/test/test_settings_lock_host.c 的注入前等待 150ms→350ms。
该等待按修复前 IME 标定,新冷却窗下首键 dt_open≈114ms 会被当迟到抬起吞掉,
只录到 "68" 两位。仅改等待时长,断言原样保留。

验证:tuku 四套脚本全绿(run_tests 644 PASS / zip 106 / cbz 296 / webtoon PASS);
12 个源文件与主仓逐字节一致;sdk/build_sdk.sh 34 成员;
tuku/build_tuku.sh 产出静态 MIPS32r2 ELF。
2026-11-06 21:31:54 +08:00

122 lines
5.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_meow_ui_iconbtn.c — M7.0a 缺口#2 宿主验证:IconButton 圆形命中 + 按压态 + 位图图标。
*
* 覆盖:
* I1 圆形命中:中心/边界命中,角部/外缘不命中(区别于矩形按钮);
* I2 owner==active + enabled 双闸门:非 active 或禁用不命中;
* I3 按压态视觉:设 MEOW_WS_PRESSED 后重绘,圆心像素向 onSurface 变亮(与未按不同);
* 禁用时圆心向灰变暗;
* I4 实时按压(meow_input_touch 注入):按下命中圆心 → 圆心变亮;释放恢复。
*
* 编译(宿主 gcc,链真实 gfx/sys/theme/vol/log/widget/input/activity/dialog/ime + 打桩 font/global):
* gcc -Wall -Wextra -o test_meow_ui_iconbtn test_meow_ui_iconbtn.c test_host_stub.c \
* meow_ui_gfx.c meow_ui_time.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \
* meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c meow_ui_str.c \
* meow_pinyin.c meow_ui_draw.c meow_ui_view.c meow_ui_box.c meow_ui_anim.c meow_ui_scroll.c \
* meow_ui_img.c meow_ui_media.c meow_notify_ipc.c stb_image.c meow_ui_nav.c \
* -I. -Iinclude -DMEOW_UI_HOST_TEST -pthread -lm
* 运行:./test_meow_ui_iconbtn
*/
#include "meow_ui.h"
#include "meow_ui_internal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static int g_fail = 0;
#define CHECK(cond, name) do { \
if (cond) printf(" PASS %s\n", name); \
else { printf(" FAIL %s\n", name); g_fail++; } } while (0)
/* ---- back_buf 像素读取(断言真实渲染,不依赖目检) ---- */
static void rd_px(int x, int y, unsigned short *p)
{
unsigned char *bb = meow_ui_back_buf();
int line = meow_ui_back_buf_pitch(), bpp = meow_ui_back_buf_bpp();
if (!bb || x < 0 || y < 0) { *p = 0; return; }
if (bpp == 16) *p = *(unsigned short *)(bb + (size_t)y * line + (size_t)x * 2);
else *p = (unsigned short)(*(unsigned int *)(bb + (size_t)y * line + (size_t)x * 4) >> 16);
}
static unsigned short px565_at(int x, int y)
{
unsigned short p; rd_px(x, y, &p); return p;
}
int main(void)
{
setenv("MEOW_UI_DUMP", "/tmp/iconbtn.ppm", 1);
meow_ui_opts o = { 480, 720 };
assert(meow_ui_init(&o) == 0);
meow_ui_activity_push(7); /* owner 对齐:IconButton 绑定 active=7 */
meow_theme_set_mode(MEOW_THEME_DARK);
/* size=64 → 外接框 (100,100,64,64) → 圆心 (132,132) r=32 */
meow_widget *ic = meow_iconbtn_create(100, 100, 64, MEOW_ICON_PLAY_ARROW);
assert(ic != NULL);
/* ============ I1 圆形命中 ============ */
printf("I1 circular hit\n");
CHECK(meow_widget_hit(ic, 132, 132), "center hits");
CHECK(meow_widget_hit(ic, 100, 132), "left edge (boundary) hits");
CHECK(meow_widget_hit(ic, 132, 100), "top edge (boundary) hits");
CHECK(!meow_widget_hit(ic, 100, 100), "corner (dist>r) MISSES (rect would hit)");
CHECK(!meow_widget_hit(ic, 132, 165), "below center (dist 33>32) MISSES");
/* ============ I2 owner 闸门:切 active 后不命中 ============ */
printf("I2 owner gate\n");
meow_ui_activity_push(8); /* 换 active:original owner=7 ≠ active=8 */
CHECK(!meow_widget_hit(ic, 132, 132), "non-active owner -> MISS (gate)");
meow_ui_activity_pop(); /* 回 active=7 */
CHECK(meow_widget_hit(ic, 132, 132), "back to active -> hits");
/* enabled 闸门 */
meow_widget_set_enabled(ic, 0);
CHECK(!meow_widget_hit(ic, 132, 132), "disabled -> MISS");
meow_widget_set_enabled(ic, 1);
CHECK(meow_widget_hit(ic, 132, 132), "enabled -> hits");
/* ============ I3 按压态视觉(状态机位 + 禁用变暗) ============
* 采样点选 (162,132):圆内 (r=30<32) 但超出图标 ink 右缘(约 x≤148)——取的是圆形底色,
* 而非图标墨色(圆心为图标覆盖,不适合测底色 tint)。 */
printf("I3 pressed visual (state machine / disabled)\n");
const meow_theme *th = meow_theme_get();
meow_ui_clear(th->bg);
unsigned short p_bg = px565_at(100, 100); /* 空屏角部 = 页面底色 */
meow_widget_set_state(ic, MEOW_WS_PRESSED, 0); /* 未按 */
meow_widget_draw(ic);
unsigned short p_idle = px565_at(162, 132);
meow_widget_set_state(ic, MEOW_WS_PRESSED, 1); /* 按下 */
meow_widget_draw(ic);
unsigned short p_press = px565_at(162, 132);
CHECK(p_press != p_idle, "pressed circle-bg pixel differs from idle (tint layer)");
/* 禁用:向灰变暗,圆 bg 应更接近 onSurface 混合(与 idle 不同且更亮/更灰) */
meow_widget_set_state(ic, MEOW_WS_PRESSED, 0);
meow_widget_set_enabled(ic, 0);
meow_widget_draw(ic);
unsigned short p_dis = px565_at(162, 132);
CHECK(p_dis != p_idle, "disabled circle-bg pixel differs from idle (dim)");
meow_widget_set_enabled(ic, 1);
/* 角部(圆外)不应出现圆形底色:等于页面底色(圆形命中/填充不外溢) */
meow_widget_draw(ic);
CHECK(px565_at(100, 100) == p_bg, "corner (outside circle) = page bg (no stray fill)");
/* ============ I4 实时按压(meow_input_touch 注入) ============ */
printf("I4 live press via input touch\n");
meow_widget_set_state(ic, MEOW_WS_PRESSED, 0);
meow_ui_clear(th->bg);
meow_widget_draw(ic);
unsigned short q_idle = px565_at(162, 132);
meow_input_touch_set(1, 132, 132, 0); /* 按在圆心 */
meow_widget_draw(ic);
unsigned short q_live = px565_at(162, 132);
CHECK(q_live != q_idle, "live touch press -> circle bg brightens");
meow_input_touch_set(0, 0, 0, 0); /* 释放 */
meow_widget_draw(ic);
CHECK(px565_at(162, 132) == q_idle, "release -> circle bg restores");
meow_widget_free(ic);
meow_ui_activity_pop();
meow_ui_shutdown();
printf(g_fail ? "\nRESULT: %d FAIL(S)\n" : "\nRESULT: ALL PASS\n", g_fail);
return g_fail;
}