Files
MeowOS-For-R3P2/patch_v2/sdk/test_meow_ui_widgets.c
T

189 lines
8.5 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_widgets.c — 宿主验证 §5.8.6 Material 子集纯逻辑(create/hit/state/滚动/选中)+
* 各组件绘制(5x7 字库兜底)dump PPM 目检。不依赖 /dev/fb0/字库(meow_font 打桩)。
*
* 编译(宿主 gcc,链真实 gfx/sys/theme/vol/log/widget/input/activity/dialog/ime + 打桩 font/global):
* gcc -o test_meow_ui_widgets test_meow_ui_widgets.c test_host_stub.c \
* meow_ui_gfx.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_draw.c meow_ui_view.c \
* -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread
* 运行:MEOW_UI_DUMP=/tmp/b2.ppm ./test_meow_ui_widgets (可选,dump 屏幕)
*/
#include "meow_ui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* 测试数据源(列表容器) */
static int list_src(int idx, char *label, int len, void *ctx)
{
(void)ctx;
if (idx < 0 || idx >= 100) return 0;
snprintf(label, (size_t)len, "item %d", idx);
return 1;
}
static meow_widget *g_w[64];
static int g_wn = 0;
static meow_widget *W(meow_widget *w) { g_w[g_wn++] = w; return w; }
static void free_all(void)
{
for (int i = 0; i < g_wn; i++) meow_widget_free(g_w[i]);
g_wn = 0;
}
int main(void)
{
setenv("MEOW_UI_DUMP", "/tmp/b2.ppm", 1);
meow_ui_opts o = { 480, 720 };
assert(meow_ui_init(&o) == 0);
int xres = meow_ui_width(), yres = meow_ui_height();
assert(xres == 480 && yres == 720);
/* ---------- Button 五型:create_variant/set_variant + 命中 ---------- */
meow_widget *bf = W(meow_btn_create_variant(10, 10, 200, 56, "FILLED", MEOW_BTN_FILLED));
meow_widget *bt = W(meow_btn_create_variant(10, 80, 200, 56, "TONAL", MEOW_BTN_TONAL));
meow_widget *bo = W(meow_btn_create_variant(10, 150, 200, 56, "OUTLINED", MEOW_BTN_OUTLINED));
meow_widget *bx = W(meow_btn_create_variant(10, 220, 200, 56, "TEXT", MEOW_BTN_TEXT));
meow_widget *be = W(meow_btn_create_variant(10, 290, 200, 56, "ELEV", MEOW_BTN_ELEVATED));
assert(meow_btn_set_variant(bt, MEOW_BTN_TONAL) == 0); /* 同值 */
assert(meow_btn_set_variant(bo, MEOW_BTN_OUTLINED) == 0);
assert(meow_widget_hit(bf, 100, 30) == 1);
assert(meow_widget_hit(bf, 5, 5) == 0); /* 越界 */
meow_widget_set_enabled(bf, 0);
assert(meow_widget_hit(bf, 100, 30) == 0); /* 禁用不命中 */
meow_widget_set_enabled(bf, 1);
meow_widget_set_selected(be, 1);
assert(meow_widget_selected(be) == 1);
printf("PASS button-variant: create/set/hit/disabled/selected\n");
/* ---------- TextField ---------- */
char tfbuf[32] = "";
meow_widget *tf = W(meow_textfield_create(10, 360, 300, 44, "Type here...", tfbuf, 32, MEOW_IME_ASCII));
strcpy(tfbuf, "abc");
assert(strcmp(meow_textfield_text(tf), "abc") == 0);
assert(meow_widget_hit(tf, 20, 380) == 1);
meow_textfield_set_placeholder(tf, "placeholder");
printf("PASS textfield: create/text/placeholder/hit\n");
/* ---------- Card + content ---------- */
meow_widget *card = W(meow_card_create(240, 10, 220, 180));
meow_widget *inner = W(meow_btn_create_variant(260, 40, 180, 44, "IN CARD", MEOW_BTN_FILLED));
meow_card_set_content(card, inner);
assert(meow_widget_hit(card, 250, 20) == 1);
printf("PASS card: create/content/hit\n");
/* ---------- Divider / Badge ---------- */
meow_widget *dv = W(meow_divider_create(10, 470, 200, 0));
meow_widget *dv2 = W(meow_divider_create(230, 470, 8, 1));
meow_widget *bd = W(meow_badge_create(400, 100));
meow_badge_set(bd, 3);
meow_badge_set(bd, 0);
printf("PASS divider/badge: create/set\n");
/* ---------- Checkbox / Radio ---------- */
meow_widget *ck = W(meow_checkbox_create(300, 200));
meow_widget *rd = W(meow_radio_create(300, 250));
meow_widget_set_selected(ck, 1);
meow_widget_set_selected(rd, 1);
assert(meow_widget_selected(ck) == 1);
assert(meow_widget_hit(rd, 315, 265) == 1);
printf("PASS checkbox/radio: create/select/hit\n");
/* ---------- ProgressBar ---------- */
meow_widget *pg = W(meow_progress_create(10, 520, 300, 6, 40));
meow_progress_set(pg, 200); /* clamp 100(无 getter,仅不崩) */
meow_widget *pgc = W(meow_progress_circular_create(420, 520, 20, 66));
meow_progress_set(pgc, -1); /* 不定 */
printf("PASS progress: create/set linear+circular\n");
/* ---------- FAB ---------- */
meow_widget *fab = W(meow_fab_create(410, 620, 56, "+"));
assert(meow_widget_hit(fab, 430, 640) == 1);
printf("PASS fab: create/hit\n");
/* ---------- TopAppBar ---------- */
meow_widget *tab_ = W(meow_topappbar_create(0, 0, 480, 56, "Title"));
meow_topappbar_set_back(tab_, 1);
int a0 = meow_topappbar_add_action(tab_, "Save");
int a1 = meow_topappbar_add_action(tab_, "Edit");
assert(a0 == 0 && a1 == 1);
assert(meow_topappbar_hit(tab_, 10, 28) == MEOW_TOPBAR_BACK); /* 返回区 */
assert(meow_topappbar_hit(tab_, 440, 28) == 1); /* 右缘动作 "Edit"(最右) */
printf("PASS topappbar: create/back/action/hit\n");
/* ---------- NavigationBar ---------- */
meow_widget *nav = W(meow_navigationbar_create(0, 680, 480, 40));
int n0 = meow_navigationbar_add_item(nav, "Home");
int n1 = meow_navigationbar_add_item(nav, "Library");
int n2 = meow_navigationbar_add_item(nav, "Settings");
assert(n0 == 0 && n1 == 1 && n2 == 2);
meow_navigationbar_set_selected(nav, 2);
assert(meow_navigationbar_selected(nav) == 2);
assert(meow_navigationbar_hit(nav, 420, 700) == 2); /* 第 3 项 */
assert(meow_navigationbar_hit(nav, 10, 700) == 0);
printf("PASS navigationbar: add/select/hit\n");
/* ---------- TabBar ---------- */
meow_widget *tbb = W(meow_tabbar_create(0, 660, 480, 36));
meow_tabbar_add_tab(tbb, "Playlist");
meow_tabbar_add_tab(tbb, "Queue");
meow_tabbar_set_selected(tbb, 1);
assert(meow_tabbar_hit(tbb, 300, 678) == 1);
printf("PASS tabbar: add/select/hit\n");
/* ---------- 列表容器(LazyColumn 虚拟化 + 滚动) ---------- */
meow_widget *lc = W(meow_lazycolumn_create(20, 460, 260, 180, 40, 100, list_src, NULL));
assert(meow_list_scroll(lc) == 0);
assert(meow_list_max_scroll(lc) == 100 * 40 - 180); /* 4000-180=3820 */
meow_list_set_scroll(lc, 5000);
assert(meow_list_scroll(lc) == 3820); /* clamp 到 max */
meow_list_scroll_by(lc, -320);
assert(meow_list_scroll(lc) == 3500);
assert(meow_list_hit_index(lc, 30, 480) == ((480 - 460 + 3500) / 40)); /* 可见项换算 */
meow_list_set_item_h(lc, 50);
assert(meow_widget_hit(lc, 30, 470) == 1);
/* M2.71-bug8:行选中 + 命中点击回调 */
meow_list_set_selected(lc, 5);
assert(meow_list_selected(lc) == 5);
/* 验证 tap_at 返回命中下标并置选中 */
int hidx = meow_list_tap_at(lc, 30, 480);
assert(hidx == ((480 - 460 + meow_list_scroll(lc)) / 50));
assert(meow_list_selected(lc) == hidx);
/* LazyRow 横向 */
meow_widget *lr = W(meow_lazyrow_create(20, 640, 380, 40, 60, 100, list_src, NULL));
meow_list_scroll_by(lr, 200);
assert(meow_list_hit_index(lr, 40, 660) == ((40 - 20 + 200) / 60));
printf("PASS lazy list: scroll clamp/virtualize/hit_index/tap_at/select (col+row)\n");
/* ---------- Dialog / BottomSheet 纯逻辑(create/set/add;show 阻塞故不调) ---------- */
meow_dialog *dlg = meow_dialog_create(MEOW_DLG_SELECT, "Pick one");
const char *items[] = { "Alpha", "Beta", "Gamma" };
meow_dialog_set_items(dlg, items, 3, 1);
assert(meow_dialog_result(dlg) == 0); /* 未 show 默认 */
meow_dialog_free(dlg);
meow_dialog *dc = meow_dialog_create(MEOW_DLG_CONFIRM, "Sure?");
assert(meow_dialog_result(dc) == 0);
meow_dialog_free(dc);
meow_sheet *sh = meow_sheet_create("Options", 0);
int s0 = meow_sheet_add_item(sh, "Copy");
int s1 = meow_sheet_add_item(sh, "Delete");
assert(s0 == 0 && s1 == 1);
meow_sheet_free(sh);
printf("PASS dialog/sheet: create/set_items/add_item (blocking show skipped)\n");
/* ---------- 绘制所有控件到 back_buf(5x7 兜底),flush 出屏幕 ---------- */
const meow_theme *th = meow_theme_get();
meow_ui_clear(th->bg);
for (int i = 0; i < g_wn; i++) meow_widget_draw(g_w[i]);
meow_ui_flush();
printf("PASS draw: all %d widgets rendered, screen dumps to /tmp/b2.ppm\n", g_wn);
free_all();
meow_ui_shutdown();
printf("ALL PASS\n");
return 0;
}