refactor(hello): 视图框架批次② — hello.c 拆分为 app.c+ui/{home,full,demo}.c+ui/common/chrome.c+logic/{notify,state}.c(定案B: demo视图态留ui/;定案b: page导航包装activity栈);test_p1p2p3_repro 改多文件链接形态 (agent-177)
hello f45ba051→c06b3b4f; mipsel -Wall -Wextra 0 warning; 宿主 P1c/P2/P3+widgets 全 PASS 出入(诚实): view on_draw/on_event 路径暂未启用(注册表直绘已覆盖, on_draw 双画风险), 留批③实测; home/full 仍手绘未迁注册表
This commit is contained in:
1 parent
896f391fee
commit
1d2496b38c
12 files changed
+668
-364
No files matched your search
@@ -0,0 +1,36 @@
|
||||
/* ui/common/chrome.c — demo 页共享 chrome(TopAppBar / NavigationBar / FAB)。
|
||||
*
|
||||
* 与 demo 内容分离:chrome 固定不随内容重建滚动;显式 set_z(999) 置顶(§6.2),
|
||||
* 区域/整帧重画都最后画 chrome。FAB 可被 demo 交互重建换计数 label(见 demo_on_tap)。
|
||||
* chrome 控件 owner=ACT_DEMO(由调用方 demo_init 先 push ACT_DEMO 再建),命中/绘制只在 demo 态生效。
|
||||
*/
|
||||
#include "hello_internal.h"
|
||||
|
||||
meow_widget *g_tb = NULL; /* TopAppBar(chrome 固定) */
|
||||
meow_widget *g_nav = NULL; /* NavigationBar(chrome 固定) */
|
||||
meow_widget *g_fab = NULL; /* FAB(chrome 固定,可重建换计数 label) */
|
||||
rect_t r_tb, r_nav, r_fab;
|
||||
|
||||
void chrome_create(void)
|
||||
{
|
||||
int sb = meow_ui_statusbar_height();
|
||||
r_tb = RX(0, sb, 480, 56); g_tb = meow_topappbar_create(0, sb, 480, 56, "Widgets Demo");
|
||||
meow_topappbar_set_back(g_tb, 1);
|
||||
r_nav = RX(0, 680, 480, 40); g_nav = meow_navigationbar_create(0, 680, 480, 40);
|
||||
meow_navigationbar_add_item(g_nav, "Buttons");
|
||||
meow_navigationbar_add_item(g_nav, "List");
|
||||
meow_navigationbar_add_item(g_nav, "More");
|
||||
meow_navigationbar_set_selected(g_nav, 0);
|
||||
r_fab = RX(406, 616, 56, 56); g_fab = meow_fab_create(406, 616, 56, "+");
|
||||
/* chrome 显式置顶(§6.2):> 一切自动 z(127),区域重画/整帧都最后画 chrome。 */
|
||||
meow_widget_set_z(g_tb, 999);
|
||||
meow_widget_set_z(g_nav, 999);
|
||||
meow_widget_set_z(g_fab, 999);
|
||||
}
|
||||
|
||||
void chrome_free(void)
|
||||
{
|
||||
if (g_tb) { meow_widget_free(g_tb); g_tb = NULL; }
|
||||
if (g_nav) { meow_widget_free(g_nav); g_nav = NULL; }
|
||||
if (g_fab) { meow_widget_free(g_fab); g_fab = NULL; }
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
/* ui/demo.c — 控件库 Demo 演示页(ACT_DEMO)view + 控制器。
|
||||
*
|
||||
* 内容控件以绝对坐标创建,页滚动 = 按「base_y - scroll」重建内容(owner=ACT_DEMO 不变);
|
||||
* 各控件跨重建状态存 g_ds(App 持有),重建后恢复。绘制走 batch① 郑序注册表:demo_paint 调
|
||||
* meow_ui_set_page_bg + meow_ui_paint_full(整帧按 z 重画:内容→标题/slider值→chrome 置顶),
|
||||
* 局部刷新统一 meow_ui_invalidate(清底+按 z 重画相交绘制物)。旧 d_paint_region/d_redraw/
|
||||
* d_rect_overlap(App 层郑栈重画)已删、下沉 SDK。
|
||||
*
|
||||
* 设计定案 B(SDK_VIEW_FRAMEWORK_DESIGN §B.3/F):demo 的 g_ds/g_drag_* /g_demo_scroll 等视图态
|
||||
* 留本文件(不迁 logic);UI→业务只经 logic_* / notify_*。页面进入/离开经 meow_view_page_push/pop
|
||||
* 驱动 on_enter/on_leave(demo_page_enter/leave)。
|
||||
*/
|
||||
#include "hello_internal.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* 供 demo_content_tap / touch 回调用的前向声明 */
|
||||
static void demo_slider_drag(int x);
|
||||
|
||||
static demo_ctrl g_demo_ctrl;
|
||||
|
||||
/* ---- demo 演示页状态 ---- */
|
||||
int g_demo = 0; /* 1=处于 demo 演示页 */
|
||||
int g_demo_scroll = 0; /* 内容区滚动偏移(base 空间 px) */
|
||||
int g_demo_focus = 0; /* 1=LazyColumn 聚焦(swipe 滚列表而非页面) */
|
||||
static int g_demo_fab = 0; /* FAB 点击计数反馈 */
|
||||
static int g_demo_prog = 0; /* ProgressBar 动画当前值 0..100 */
|
||||
static uint64_t g_demo_prog_last = 0;
|
||||
static int g_demo_ct = 0; /* 内容视口顶(屏y = statusbar+56+8) */
|
||||
static int g_demo_cb = 0; /* 内容视口底(屏y =608,NavBar 上方留白) */
|
||||
static int g_demo_content_h = 0;/* 内容总高(base 空间;决定 max_scroll) */
|
||||
|
||||
/* M2.71-bug2/6:拖动过程(跟手)状态。on_touch_down 锁一种拖拽,on_touch_move 实时更新。 */
|
||||
static int g_drag_slider = 0; /* 手指按在 slider */
|
||||
int g_drag_list = 0; /* 手指按在 LazyColumn:拖拽滚列表 */
|
||||
int g_drag_page = 0; /* 手指按在页内容(非 slider/list):拖拽滚页面 */
|
||||
static int g_drag_list_last_y = 0; /* 列表拖拽上一帧 y */
|
||||
static int g_drag_page_last_y = 0; /* 页面拖拽上一帧 y */
|
||||
static int g_drag_page_delta = 0; /* 页面拖拽累计位移(节流重建,≥8px 才重建一次) */
|
||||
|
||||
/* SDK 控件不透明:App 自记几何,用于局部 flush / 命中 / scroll 重建。 */
|
||||
|
||||
/* demo 各控件跨重建保留的状态(app 持有;重建后按此恢复) */
|
||||
static struct {
|
||||
int sw_on; int slider; char tf[32];
|
||||
int ck; int r1, r2; int btn[5]; int card; int tab; int list; int list_sel; int prog;
|
||||
} g_ds = { .sw_on = 1, .slider = 40, .r1 = 1, .tab = 1, .list = 0, .list_sel = 0, .prog = 0 };
|
||||
|
||||
/* demo 内容布局常量(base 空间) */
|
||||
#define DCL_X 16
|
||||
#define DCR_X 252
|
||||
#define DCW 212
|
||||
#define DFW 448
|
||||
#define DBH 44
|
||||
#define DCH 52 /* 一行两列按钮步进 */
|
||||
|
||||
/* demo 内容槽:控件 + 其当前屏幕几何(rebuild 时重算) */
|
||||
#define D_SLOT_MAX 64
|
||||
static struct { meow_widget *w; rect_t r; } g_dslot[D_SLOT_MAX];
|
||||
static int g_dslot_n = 0;
|
||||
|
||||
/* demo 分区小标题(纯文本,非控件;屏幕坐标在 rebuild 时算好) */
|
||||
#define D_TITLE_MAX 16
|
||||
static struct { int x, y; const char *s; } g_dtitle[D_TITLE_MAX];
|
||||
static int g_dtitle_n = 0;
|
||||
|
||||
/* demo 交互组件引用(rebuild 时 g_* 与 r_* 同步重指/recompute;chrome 在 ui/common/chrome.c) */
|
||||
static meow_widget *g_dbtn_b[5]; static rect_t r_btn[5]; /* Button 五型 */
|
||||
static meow_widget *g_dbtn_d; /* DISABLED 按钮(禁用不命中,无需 rect) */
|
||||
static meow_widget *g_dsw; static rect_t r_dsw; /* Switch */
|
||||
static meow_widget *g_dslider; static rect_t r_slider, r_slider_txt; /* Slider + 值文本 */
|
||||
static meow_widget *g_dtf; static rect_t r_dtf; /* TextField */
|
||||
static meow_widget *g_dcb; static rect_t r_dcb; /* Checkbox */
|
||||
static meow_widget *g_dr1, *g_dr2; rect_t r_dr1, r_dr2; /* Radio 单选组 */
|
||||
static meow_widget *g_dprl; static rect_t r_prl; /* ProgressBar 线性 */
|
||||
meow_widget *g_dprc; rect_t r_prc; /* ProgressBar 圆形 */
|
||||
static meow_widget *g_dcard; static rect_t r_card; /* Card */
|
||||
static meow_widget *g_dcard_btn; static rect_t r_cardbtn; /* Card 内容子按钮 */
|
||||
static meow_widget *g_dbadge; /* Badge */
|
||||
static meow_widget *g_dtab; static rect_t r_tab; /* TabBar */
|
||||
static meow_widget *g_dbtn_dlg; static rect_t r_dlg; /* 打开 Dialog 的按钮 */
|
||||
static meow_widget *g_dbtn_sheet; static rect_t r_sheet;/* 打开 BottomSheet 的按钮 */
|
||||
meow_widget *g_dlc; rect_t r_list; /* LazyColumn */
|
||||
|
||||
/* ---- demo 分区标题/slider 值文本:注册为 CUSTOM 绘制物(§6.2 区域重画会重画它们)----
|
||||
* 显式 z=D_TITLE_Z:> 一切自动 z(=127)、< chrome 置顶(999)。非控件直绘必须注册,否则
|
||||
* meow_ui_invalidate 清底后会漏画。 */
|
||||
#define D_TITLE_Z 128
|
||||
static int g_dtitle_cid[D_TITLE_MAX]; /* 分区标题绘制物 id(rebuild 时注销/重注册) */
|
||||
static int g_slider_cid = 0; /* slider 值文本绘制物 id */
|
||||
|
||||
/* CUSTOM 绘制回调:分区标题(ctx=title 下标,指向 g_dtitle[i]) */
|
||||
static void demo_draw_title(void *ctx)
|
||||
{
|
||||
int i = (int)(intptr_t)ctx;
|
||||
if (i < 0 || i >= g_dtitle_n) return;
|
||||
const meow_theme *th = meow_theme_get();
|
||||
meow_ui_text(g_dtitle[i].x, g_dtitle[i].y, g_dtitle[i].s, 20, th->primary);
|
||||
}
|
||||
/* CUSTOM 绘制回调:slider 当前值文本(bbox=r_slider_txt) */
|
||||
static void demo_draw_slider_val(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
if (!g_dslider) return;
|
||||
const meow_theme *th = meow_theme_get();
|
||||
char buf[28]; snprintf(buf, sizeof buf, "slider = %d", meow_slider_get(g_dslider));
|
||||
meow_ui_text(r_slider_txt.x, r_slider_txt.y, buf, 20, th->dim);
|
||||
}
|
||||
|
||||
/* ---- demo 构建/布局 ---- */
|
||||
|
||||
static void d_slot(meow_widget *w, rect_t r)
|
||||
{
|
||||
if (g_dslot_n < D_SLOT_MAX) { g_dslot[g_dslot_n].w = w; g_dslot[g_dslot_n].r = r; g_dslot_n++; }
|
||||
}
|
||||
static void d_title(int x, int y, const char *s)
|
||||
{
|
||||
if (g_dtitle_n < D_TITLE_MAX) {
|
||||
int i = g_dtitle_n;
|
||||
g_dtitle[i].x = x; g_dtitle[i].y = y; g_dtitle[i].s = s;
|
||||
g_dtitle_n++;
|
||||
int tw = meow_ui_text_width(s, 20);
|
||||
int th = meow_ui_text_height(20);
|
||||
g_dtitle_cid[i] = meow_draw_custom_register(D_TITLE_Z, x, y, tw, th,
|
||||
demo_draw_title, (void *)(intptr_t)i);
|
||||
}
|
||||
}
|
||||
|
||||
/* LazyColumn 数据源(100 项虚拟化) */
|
||||
static int demo_list_src(int idx, char *label, int len, void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
if (idx < 0 || idx >= 100) return 0;
|
||||
snprintf(label, (size_t)len, "list item %d", idx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 释放当前全部内容控件(含 Card 的独立子按钮)与 CUSTOM 绘制物;chrome 不在其列。 */
|
||||
static void demo_free_content(void)
|
||||
{
|
||||
for (int i = 0; i < g_dslot_n; i++) meow_widget_free(g_dslot[i].w);
|
||||
g_dslot_n = 0;
|
||||
if (g_dcard_btn) { meow_widget_free(g_dcard_btn); g_dcard_btn = NULL; }
|
||||
for (int i = 0; i < g_dtitle_n; i++)
|
||||
if (g_dtitle_cid[i] > 0) { meow_draw_unregister(g_dtitle_cid[i]); g_dtitle_cid[i] = 0; }
|
||||
if (g_slider_cid > 0) { meow_draw_unregister(g_slider_cid); g_slider_cid = 0; }
|
||||
g_dtitle_n = 0;
|
||||
}
|
||||
|
||||
/* 按 scroll 重建全部内容控件(owner=ACT_DEMO:调用方须已 push ACT_DEMO)。
|
||||
* 控件以绝对坐标创建于 (x, base_y - scroll),几何同步写入 r_* / 槽;状态从 g_ds 恢复。 */
|
||||
static void demo_build_at(int scroll)
|
||||
{
|
||||
int ct = meow_ui_statusbar_height() + 56 + 8;
|
||||
g_demo_ct = ct; g_demo_cb = 608;
|
||||
g_dslot_n = 0; g_dtitle_n = 0;
|
||||
int yb = 0;
|
||||
#define SY(base) (ct + (base) - scroll) /* base 空间 → 屏幕 y */
|
||||
#define SLOT(w,x,y,ww,hh) do { rect_t _r=RX(x,y,ww,hh); d_slot((w),_r); } while(0)
|
||||
|
||||
/* ---- Buttons(五型 + 禁用) ---- */
|
||||
d_title(DCL_X, SY(yb), "BUTTONS 5-variants"); yb += 26;
|
||||
r_btn[0] = RX(DCL_X, SY(yb), DCW, DBH); g_dbtn_b[0] = meow_btn_create_variant(r_btn[0].x, r_btn[0].y, DCW, DBH, "FILLED", MEOW_BTN_FILLED); SLOT(g_dbtn_b[0], r_btn[0].x, r_btn[0].y, r_btn[0].w, r_btn[0].h);
|
||||
r_btn[1] = RX(DCR_X, SY(yb), DCW, DBH); g_dbtn_b[1] = meow_btn_create_variant(r_btn[1].x, r_btn[1].y, DCW, DBH, "TONAL", MEOW_BTN_TONAL); SLOT(g_dbtn_b[1], r_btn[1].x, r_btn[1].y, r_btn[1].w, r_btn[1].h);
|
||||
yb += DCH;
|
||||
r_btn[2] = RX(DCL_X, SY(yb), DCW, DBH); g_dbtn_b[2] = meow_btn_create_variant(r_btn[2].x, r_btn[2].y, DCW, DBH, "OUTLINED", MEOW_BTN_OUTLINED); SLOT(g_dbtn_b[2], r_btn[2].x, r_btn[2].y, r_btn[2].w, r_btn[2].h);
|
||||
r_btn[3] = RX(DCR_X, SY(yb), DCW, DBH); g_dbtn_b[3] = meow_btn_create_variant(r_btn[3].x, r_btn[3].y, DCW, DBH, "TEXT", MEOW_BTN_TEXT); SLOT(g_dbtn_b[3], r_btn[3].x, r_btn[3].y, r_btn[3].w, r_btn[3].h);
|
||||
yb += DCH;
|
||||
r_btn[4] = RX(DCL_X, SY(yb), DCW, DBH); g_dbtn_b[4] = meow_btn_create_variant(r_btn[4].x, r_btn[4].y, DCW, DBH, "ELEVATED", MEOW_BTN_ELEVATED); SLOT(g_dbtn_b[4], r_btn[4].x, r_btn[4].y, r_btn[4].w, r_btn[4].h);
|
||||
g_dbtn_d = meow_btn_create_variant(DCR_X, SY(yb), DCW, DBH, "DISABLED", MEOW_BTN_FILLED);
|
||||
SLOT(g_dbtn_d, DCR_X, SY(yb), DCW, DBH);
|
||||
meow_widget_set_enabled(g_dbtn_d, 0); /* 禁用态:不命中 + 变暗 */
|
||||
yb += DCH;
|
||||
for (int i = 0; i < 5; i++) meow_widget_set_selected(g_dbtn_b[i], g_ds.btn[i]);
|
||||
|
||||
SLOT(meow_divider_create(DCL_X, SY(yb), DFW, 0), DCL_X, SY(yb), DFW, 1); yb += 16;
|
||||
|
||||
/* ---- Input / State(Switch / Slider / TextField / Checkbox / Radio) ---- */
|
||||
d_title(DCL_X, SY(yb), "INPUT & STATE"); yb += 26;
|
||||
r_dsw = RX(DCL_X, SY(yb), 56, 32); g_dsw = meow_switch_create(r_dsw.x, r_dsw.y, g_ds.sw_on); SLOT(g_dsw, r_dsw.x, r_dsw.y, r_dsw.w, r_dsw.h); yb += 44;
|
||||
|
||||
r_slider_txt = RX(DCL_X, SY(yb), 160, 24); yb += 24; /* 加宽到覆盖值文本全宽(防局部刷漏尾) */
|
||||
r_slider = RX(DCL_X, SY(yb), DFW, 40); g_dslider = meow_slider_create(r_slider.x, r_slider.y, r_slider.w, 0, 100, g_ds.slider); SLOT(g_dslider, r_slider.x, r_slider.y, r_slider.w, r_slider.h); yb += 48;
|
||||
g_slider_cid = meow_draw_custom_register(D_TITLE_Z, r_slider_txt.x, r_slider_txt.y,
|
||||
r_slider_txt.w, r_slider_txt.h,
|
||||
demo_draw_slider_val, NULL);
|
||||
|
||||
r_dtf = RX(DCL_X, SY(yb), DFW, 44); g_dtf = meow_textfield_create(r_dtf.x, r_dtf.y, r_dtf.w, r_dtf.h, "Type here...", g_ds.tf, 32, MEOW_IME_ASCII); SLOT(g_dtf, r_dtf.x, r_dtf.y, r_dtf.w, r_dtf.h); yb += 54;
|
||||
|
||||
r_dcb = RX(DCL_X, SY(yb), 34, 34); g_dcb = meow_checkbox_create(r_dcb.x, r_dcb.y); SLOT(g_dcb, r_dcb.x, r_dcb.y, r_dcb.w, r_dcb.h);
|
||||
r_dr1 = RX(DCR_X, SY(yb), 34, 34); g_dr1 = meow_radio_create(r_dr1.x, r_dr1.y); SLOT(g_dr1, r_dr1.x, r_dr1.y, r_dr1.w, r_dr1.h);
|
||||
yb += 40;
|
||||
r_dr2 = RX(DCR_X, SY(yb), 34, 34); g_dr2 = meow_radio_create(r_dr2.x, r_dr2.y); SLOT(g_dr2, r_dr2.x, r_dr2.y, r_dr2.w, r_dr2.h);
|
||||
yb += 40;
|
||||
meow_widget_set_selected(g_dcb, g_ds.ck);
|
||||
meow_widget_set_selected(g_dr1, g_ds.r1);
|
||||
meow_widget_set_selected(g_dr2, g_ds.r2);
|
||||
|
||||
/* ---- ProgressBar(线性 + 圆形,on_tick 动画) ---- */
|
||||
d_title(DCL_X, SY(yb), "PROGRESS (animated)"); yb += 26;
|
||||
r_prl = RX(DCL_X, SY(yb), DFW, 8); g_dprl = meow_progress_create(r_prl.x, r_prl.y, r_prl.w, r_prl.h, g_ds.prog); SLOT(g_dprl, r_prl.x, r_prl.y, r_prl.w, r_prl.h); yb += 16;
|
||||
r_prc = RX(DCL_X + 400 + 17 - 20, SY(yb) + 17 - 20, 40, 40);
|
||||
g_dprc = meow_progress_circular_create(r_prc.x + 20, r_prc.y + 20, 17, g_ds.prog);
|
||||
SLOT(g_dprc, r_prc.x, r_prc.y, r_prc.w, r_prc.h); yb += 48;
|
||||
|
||||
/* ---- Container(Card / Badge / TabBar) ---- */
|
||||
d_title(DCL_X, SY(yb), "CONTAINER"); yb += 26;
|
||||
r_card = RX(DCL_X, SY(yb), DFW, 88); g_dcard = meow_card_create(r_card.x, r_card.y, r_card.w, r_card.h); SLOT(g_dcard, r_card.x, r_card.y, r_card.w, r_card.h);
|
||||
r_cardbtn = RX(DCL_X + 16, SY(yb) + 20, DFW - 32, 40); g_dcard_btn = meow_btn_create_variant(r_cardbtn.x, r_cardbtn.y, r_cardbtn.w, r_cardbtn.h, "IN-CARD BUTTON", MEOW_BTN_TONAL);
|
||||
meow_widget_set_selected(g_dcard_btn, g_ds.card);
|
||||
meow_card_set_content(g_dcard, g_dcard_btn);
|
||||
yb += 96;
|
||||
g_dbadge = meow_badge_create(DCL_X + 60, SY(yb) + 10);
|
||||
SLOT(g_dbadge, DCL_X + 52, SY(yb) + 2, 18, 18);
|
||||
meow_badge_set(g_dbadge, 3);
|
||||
yb += 30;
|
||||
r_tab = RX(DCL_X, SY(yb), DFW, 36); g_dtab = meow_tabbar_create(r_tab.x, r_tab.y, r_tab.w, r_tab.h); SLOT(g_dtab, r_tab.x, r_tab.y, r_tab.w, r_tab.h);
|
||||
meow_tabbar_add_tab(g_dtab, "Playlist");
|
||||
meow_tabbar_add_tab(g_dtab, "Queue");
|
||||
meow_tabbar_add_tab(g_dtab, "Now");
|
||||
meow_tabbar_set_selected(g_dtab, g_ds.tab);
|
||||
yb += 44;
|
||||
|
||||
/* ---- Modals(Dialog + BottomSheet) ---- */
|
||||
d_title(DCL_X, SY(yb), "MODALS (blocking)"); yb += 26;
|
||||
r_dlg = RX(DCL_X, SY(yb), DCW, DBH); g_dbtn_dlg = meow_btn_create_variant(r_dlg.x, r_dlg.y, r_dlg.w, r_dlg.h, "DIALOG", MEOW_BTN_OUTLINED); SLOT(g_dbtn_dlg, r_dlg.x, r_dlg.y, r_dlg.w, r_dlg.h);
|
||||
r_sheet = RX(DCR_X, SY(yb), DCW, DBH); g_dbtn_sheet = meow_btn_create_variant(r_sheet.x, r_sheet.y, r_sheet.w, r_sheet.h, "SHEET", MEOW_BTN_OUTLINED); SLOT(g_dbtn_sheet, r_sheet.x, r_sheet.y, r_sheet.w, r_sheet.h);
|
||||
yb += DCH;
|
||||
|
||||
/* ---- LazyColumn(100 项列表滚动) ---- */
|
||||
d_title(DCL_X, SY(yb), "LIST (LazyColumn, tap+swipe)"); yb += 26;
|
||||
r_list = RX(DCL_X, SY(yb), DFW, 150); g_dlc = meow_lazycolumn_create(r_list.x, r_list.y, r_list.w, r_list.h, 40, 100, demo_list_src, NULL);
|
||||
SLOT(g_dlc, r_list.x, r_list.y, r_list.w, r_list.h);
|
||||
meow_list_set_scroll(g_dlc, g_ds.list);
|
||||
meow_list_set_selected(g_dlc, g_ds.list_sel); /* M2.71-bug8:跨重建保留选中行 */
|
||||
yb += 158;
|
||||
|
||||
g_demo_content_h = yb;
|
||||
#undef SY
|
||||
#undef SLOT
|
||||
}
|
||||
|
||||
/* demo 全页重绘:整帧按 z 序重画全部(set_page_bg 清底 + 注册表按 z 升序)。 */
|
||||
void demo_paint(void)
|
||||
{
|
||||
const meow_theme *th = meow_theme_get();
|
||||
meow_ui_set_page_bg(th->bg); /* 页面底 = 主题 bg(区域/整帧重画清底用) */
|
||||
meow_ui_paint_full(); /* 整帧按 z 序重画 */
|
||||
}
|
||||
|
||||
/* 重建内容到指定 scroll(clamp 到 [0, max_scroll]);进入/滚动共用 */
|
||||
void demo_rebuild_to(int scroll)
|
||||
{
|
||||
int vp_h = g_demo_cb - g_demo_ct;
|
||||
int maxs = g_demo_content_h - vp_h;
|
||||
if (maxs < 0) maxs = 0;
|
||||
if (scroll < 0) scroll = 0;
|
||||
if (scroll > maxs) scroll = maxs;
|
||||
demo_free_content();
|
||||
demo_build_at(scroll);
|
||||
g_demo_scroll = scroll;
|
||||
demo_paint();
|
||||
}
|
||||
|
||||
/* ---- demo 交互 ---- */
|
||||
|
||||
/* 局部刷新统一走 SDK meow_ui_invalidate(清底 + 按 z 重画相交绘制物 + 上屏)。 */
|
||||
static void d_toggle_sel(meow_widget *w, rect_t r)
|
||||
{
|
||||
if (!w) return;
|
||||
meow_widget_set_selected(w, !meow_widget_selected(w));
|
||||
meow_ui_invalidate(r.x, r.y, r.w, r.h);
|
||||
}
|
||||
|
||||
/* Tap:落点在内容控件上,返回 1=已消费 */
|
||||
static int demo_content_tap(int x, int y)
|
||||
{
|
||||
g_demo_focus = 0; /* 默认切回页滚动;仅命中列表时改置 1 */
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
if (meow_widget_hit(g_dbtn_b[i], x, y)) { d_toggle_sel(g_dbtn_b[i], r_btn[i]); g_ds.btn[i] = meow_widget_selected(g_dbtn_b[i]); return 1; }
|
||||
if (meow_widget_hit(g_dr1, x, y)) { meow_widget_set_selected(g_dr1, 1); meow_widget_set_selected(g_dr2, 0); g_ds.r1 = 1; g_ds.r2 = 0; meow_ui_invalidate(r_dr1.x, r_dr1.y, r_dr1.w, r_dr1.h); meow_ui_invalidate(r_dr2.x, r_dr2.y, r_dr2.w, r_dr2.h); return 1; }
|
||||
if (meow_widget_hit(g_dr2, x, y)) { meow_widget_set_selected(g_dr2, 1); meow_widget_set_selected(g_dr1, 0); g_ds.r2 = 1; g_ds.r1 = 0; meow_ui_invalidate(r_dr1.x, r_dr1.y, r_dr1.w, r_dr1.h); meow_ui_invalidate(r_dr2.x, r_dr2.y, r_dr2.w, r_dr2.h); return 1; }
|
||||
if (meow_widget_hit(g_dcb, x, y)) { d_toggle_sel(g_dcb, r_dcb); g_ds.ck = meow_widget_selected(g_dcb); return 1; }
|
||||
if (meow_widget_hit(g_dsw, x, y)) { g_ds.sw_on = !meow_switch_get(g_dsw); meow_switch_set(g_dsw, g_ds.sw_on); meow_ui_invalidate(r_dsw.x, r_dsw.y, r_dsw.w, r_dsw.h); return 1; }
|
||||
if (meow_widget_hit(g_dslider, x, y)) { demo_slider_drag(x); return 1; }
|
||||
if (meow_widget_hit(g_dtf, x, y)) {
|
||||
meow_textfield_activate(g_dtf); /* 阻塞 IME,返回后刷新 + 状态回写 */
|
||||
strncpy(g_ds.tf, meow_textfield_text(g_dtf), sizeof g_ds.tf - 1);
|
||||
g_ds.tf[sizeof g_ds.tf - 1] = 0;
|
||||
meow_ui_invalidate(r_dtf.x, r_dtf.y, r_dtf.w, r_dtf.h);
|
||||
return 1;
|
||||
}
|
||||
if (meow_widget_hit(g_dcard_btn, x, y)) { d_toggle_sel(g_dcard_btn, r_cardbtn); g_ds.card = meow_widget_selected(g_dcard_btn); return 1; }
|
||||
if (g_dtab) {
|
||||
int t = meow_tabbar_hit(g_dtab, x, y);
|
||||
if (t >= 0) { g_ds.tab = t; meow_tabbar_set_selected(g_dtab, t); meow_ui_invalidate(r_tab.x, r_tab.y, r_tab.w, r_tab.h); return 1; }
|
||||
}
|
||||
if (meow_widget_hit(g_dbtn_dlg, x, y)) { meow_dialog_show(g_dlg); meow_log(MEOW_LOG_INFO, "dialog result=%d", meow_dialog_result(g_dlg)); meow_ui_invalidate(r_dlg.x, r_dlg.y, r_dlg.w, r_dlg.h); return 1; }
|
||||
if (meow_widget_hit(g_dbtn_sheet, x, y)) { int r = meow_sheet_open(g_sheet); meow_log(MEOW_LOG_INFO, "sheet result=%d", r); meow_ui_invalidate(r_sheet.x, r_sheet.y, r_sheet.w, r_sheet.h); return 1; }
|
||||
if (meow_widget_hit(g_dlc, x, y)) {
|
||||
g_demo_focus = 1;
|
||||
int li = meow_list_tap_at(g_dlc, x, y); /* M2.71-bug8:命中行→置选中并高亮 */
|
||||
if (li >= 0) { g_ds.list_sel = li; meow_ui_invalidate(r_list.x, r_list.y, r_list.w, r_list.h); }
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* demo 页 on_tap 分发(chrome → 内容) */
|
||||
void demo_on_tap(int x, int y)
|
||||
{
|
||||
if (g_tb) {
|
||||
int ah = meow_topappbar_hit(g_tb, x, y);
|
||||
if (ah == MEOW_TOPBAR_BACK) { meow_view_page_pop(); return; }
|
||||
}
|
||||
if (g_fab && meow_widget_hit(g_fab, x, y)) {
|
||||
g_demo_fab++;
|
||||
char lb[16]; snprintf(lb, sizeof lb, "+%d", g_demo_fab);
|
||||
meow_widget_free(g_fab);
|
||||
g_fab = meow_fab_create(r_fab.x, r_fab.y, 56, lb);
|
||||
meow_widget_set_z(g_fab, 999); /* 重建后重挂顶:新 entry 自动 z 低,须显式置顶 */
|
||||
meow_ui_invalidate(r_fab.x, r_fab.y, r_fab.w, r_fab.h); /* 重画 FAB 及其下重叠 z 栈 */
|
||||
return;
|
||||
}
|
||||
if (g_nav) {
|
||||
int idx = meow_navigationbar_hit(g_nav, x, y);
|
||||
if (idx >= 0) { meow_navigationbar_set_selected(g_nav, idx); meow_ui_invalidate(r_nav.x, r_nav.y, r_nav.w, r_nav.h); return; }
|
||||
}
|
||||
demo_content_tap(x, y);
|
||||
}
|
||||
|
||||
/* demo 页 on_tick:ProgressBar 动画(局部刷,~120ms 步进) */
|
||||
void demo_tick(uint64_t now)
|
||||
{
|
||||
if (g_demo_prog_last == 0) g_demo_prog_last = now;
|
||||
if (now - g_demo_prog_last < 120) return;
|
||||
g_demo_prog_last = now;
|
||||
g_ds.prog = (g_ds.prog + 3) % 101;
|
||||
g_demo_prog = g_ds.prog;
|
||||
meow_progress_set(g_dprl, g_demo_prog); meow_ui_invalidate(r_prl.x, r_prl.y, r_prl.w, r_prl.h);
|
||||
meow_progress_set(g_dprc, g_demo_prog); meow_ui_invalidate(r_prc.x, r_prc.y, r_prc.w, r_prc.h);
|
||||
}
|
||||
|
||||
/* 按触碰 X 落 slider 值并局部刷(按下即定位 + 拖动实时,M2.71-bug2) */
|
||||
static void demo_slider_drag(int x)
|
||||
{
|
||||
int frac = x - r_slider.x; if (frac < 0) frac = 0; if (frac > r_slider.w) frac = r_slider.w;
|
||||
g_ds.slider = frac * 100 / r_slider.w;
|
||||
meow_slider_set(g_dslider, g_ds.slider);
|
||||
meow_ui_invalidate(r_slider.x, r_slider.y, r_slider.w, r_slider.h);
|
||||
meow_ui_invalidate(r_slider_txt.x, r_slider_txt.y, r_slider_txt.w, r_slider_txt.h); /* 重画值文本 */
|
||||
}
|
||||
|
||||
/* demo 页 on_touch_down:锁一种拖拽(slider > list > 页内容)。 */
|
||||
void demo_touch_down(int x, int y)
|
||||
{
|
||||
g_drag_slider = 0; g_drag_list = 0; g_drag_page = 0; g_drag_page_delta = 0;
|
||||
if (!g_demo) return;
|
||||
if (meow_widget_hit(g_dslider, x, y)) { g_drag_slider = 1; demo_slider_drag(x); return; }
|
||||
if (g_dlc && meow_widget_hit(g_dlc, x, y)) {
|
||||
g_demo_focus = 1; g_drag_list = 1; g_drag_list_last_y = y; return;
|
||||
}
|
||||
g_demo_focus = 0;
|
||||
if (y >= g_demo_ct && y < g_demo_cb && x >= 0 && x < meow_ui_width()) {
|
||||
g_drag_page = 1; g_drag_page_last_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
/* demo 页 on_touch_move:拖动过程实时更新(slider 值 / 列表滚动 / 页面滚动节流重建)。 */
|
||||
void demo_touch_move(int x, int y)
|
||||
{
|
||||
if (!g_demo) return;
|
||||
if (g_drag_slider) { demo_slider_drag(x); return; }
|
||||
if (g_drag_list) {
|
||||
int dy = y - g_drag_list_last_y; g_drag_list_last_y = y;
|
||||
if (dy) { meow_list_scroll_by(g_dlc, -dy); g_ds.list = meow_list_scroll(g_dlc); meow_ui_invalidate(r_list.x, r_list.y, r_list.w, r_list.h); }
|
||||
return;
|
||||
}
|
||||
if (g_drag_page) {
|
||||
int dy = y - g_drag_page_last_y; g_drag_page_last_y = y;
|
||||
g_drag_page_delta += -dy; /* 手指上移(y 减) → scroll 增(显示更低内容),与 on_swipe 一致 */
|
||||
if (g_drag_page_delta >= 8 || g_drag_page_delta <= -8) {
|
||||
demo_rebuild_to(g_demo_scroll + g_drag_page_delta);
|
||||
g_drag_page_delta = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* demo 页 on_swipe:LEFT=回 home;UP/DOWN=列表聚焦滚列表,否则页滚动。 */
|
||||
void demo_swipe(int dir, int dist)
|
||||
{
|
||||
if (dir == MEOW_SWIPE_LEFT) { meow_view_page_pop(); return; }
|
||||
if (dir != MEOW_SWIPE_UP && dir != MEOW_SWIPE_DOWN) return;
|
||||
if (g_drag_page || g_drag_list) return; /* 本次手势已实时跟手滚动过 */
|
||||
int del = (dir == MEOW_SWIPE_UP) ? dist : -dist; /* 手指上移 → 偏移增大 */
|
||||
if (g_demo_focus && g_dlc) {
|
||||
meow_list_scroll_by(g_dlc, del);
|
||||
g_ds.list = meow_list_scroll(g_dlc);
|
||||
meow_ui_invalidate(r_list.x, r_list.y, r_list.w, r_list.h); /* 列表区局部刷新 */
|
||||
} else {
|
||||
demo_rebuild_to(g_demo_scroll + del);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- demo 页 view(on_enter/on_leave/on_destroy 驱动进入/离开/释放)---- */
|
||||
|
||||
static void demo_page_enter(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((demo_ctrl *)ctx)->active = 1;
|
||||
g_demo = 1;
|
||||
g_demo_focus = 0;
|
||||
demo_rebuild_to(0);
|
||||
meow_log(MEOW_LOG_INFO, "demo enter scroll=0");
|
||||
}
|
||||
|
||||
static void demo_page_leave(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((demo_ctrl *)ctx)->active = 0;
|
||||
g_demo = 0;
|
||||
}
|
||||
|
||||
static void demo_page_destroy(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v; (void)ctx;
|
||||
demo_free_content(); /* 内容控件 + CUSTOM 标题/slider值 */
|
||||
chrome_free(); /* chrome(TopAppBar / NavigationBar / FAB) */
|
||||
}
|
||||
|
||||
void demo_init(void)
|
||||
{
|
||||
meow_ui_activity_push(ACT_DEMO);
|
||||
chrome_create(); /* chrome 位置/置顶在 chrome.c */
|
||||
demo_build_at(0);
|
||||
meow_ui_activity_pop();
|
||||
g_demo_scroll = 0;
|
||||
}
|
||||
|
||||
int demo_is_active(void)
|
||||
{
|
||||
return g_demo;
|
||||
}
|
||||
|
||||
/* demo view:on_create 建 chrome+内容(一次,owner=ACT_DEMO);进入时 rebuild 到顶。 */
|
||||
static void demo_page_create(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((demo_ctrl *)ctx)->view = v;
|
||||
demo_init();
|
||||
}
|
||||
|
||||
meow_view *demo_view_create(void)
|
||||
{
|
||||
static const meow_view_hooks h = {
|
||||
.on_create = demo_page_create,
|
||||
.on_enter = demo_page_enter,
|
||||
.on_leave = demo_page_leave,
|
||||
.on_destroy = demo_page_destroy,
|
||||
};
|
||||
return meow_view_create(ACT_DEMO, MEOW_VIEW_ACTIVITY, &h, &g_demo_ctrl);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* ui/full.c — 全屏页(ACT_FULL)view + 控制器。
|
||||
*
|
||||
* 无控件:进入时声明全屏+状态栏收合,绘制 accent 底 + 三行文本;点任意处/左缘左滑回 home。
|
||||
* 页面切换由 meow_view_page_push/pop 驱动 on_enter/on_leave(activity_push/pop 在 page_push/pop 内)。
|
||||
* 注:on_leave 里 activity_active() 仍为 ACT_FULL(activity_pop 在其后),故 OFF 日志的 activity
|
||||
* id 与旧 set_fullscreen(0) 略异——纯诊断日志差异,功能无变化(见报告)。
|
||||
*/
|
||||
#include "hello_internal.h"
|
||||
|
||||
static full_ctrl g_full_ctrl;
|
||||
static int g_full = 0; /* 1=处于全屏视图 */
|
||||
|
||||
void full_draw(void)
|
||||
{
|
||||
const meow_theme *th = meow_theme_get();
|
||||
meow_ui_clear(th->accent);
|
||||
meow_ui_text_center(240, 330, "FULLSCREEN ACTIVE", 28, 0xFFFFFF);
|
||||
meow_ui_text_center(240, 366, "tap anywhere = back to home", 20, 0xFFFFFF);
|
||||
meow_ui_text_center(240, 394, "(left-edge swipe also returns)", 20, 0xFFFFFF);
|
||||
meow_ui_flush();
|
||||
}
|
||||
|
||||
static void full_page_enter(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((full_ctrl *)ctx)->active = 1;
|
||||
g_full = 1;
|
||||
meow_ui_set_fullscreen(1);
|
||||
meow_ui_statusbar_set_collapsed(1);
|
||||
full_draw();
|
||||
meow_log(MEOW_LOG_INFO, "fullscreen ON (collapsed), activity->%d", meow_ui_activity_active());
|
||||
}
|
||||
|
||||
static void full_page_leave(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((full_ctrl *)ctx)->active = 0;
|
||||
g_full = 0;
|
||||
meow_ui_set_fullscreen(0);
|
||||
meow_ui_statusbar_set_collapsed(0);
|
||||
meow_log(MEOW_LOG_INFO, "fullscreen OFF (restore), activity->%d", meow_ui_activity_active());
|
||||
}
|
||||
|
||||
int full_is_active(void)
|
||||
{
|
||||
return g_full;
|
||||
}
|
||||
|
||||
meow_view *full_view_create(void)
|
||||
{
|
||||
static const meow_view_hooks h = {
|
||||
.on_enter = full_page_enter,
|
||||
.on_leave = full_page_leave,
|
||||
};
|
||||
return meow_view_create(ACT_FULL, MEOW_VIEW_ACTIVITY, &h, &g_full_ctrl);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/* ui/home.c — 主页(ACT_HOME)view + 控制器。
|
||||
*
|
||||
* 负责 home 控件(TAP ME / 6 通知行 / CANCEL LAST / FULLSCREEN / WIDGETS DEMO)+ 手绘(非注册表
|
||||
* 路径,batch① 仅 demo 迁注册表,home 保持命令式 draw+flush)+ 命中分发 + 业务监听(logic 推送)。
|
||||
* UI→业务只经 logic_taps_bump()/notif_send()/notif_cancel();业务变化经 logic_set_listener 回调
|
||||
* home_state_listener 刷新(契约 ①②)。导航到 demo/full 经 meow_view_page_push(单一入口)。
|
||||
*/
|
||||
#include "hello_internal.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static home_ctrl g_home_ctrl;
|
||||
|
||||
/* ---- home 既有控件 ---- */
|
||||
static meow_widget *g_btn;
|
||||
static meow_widget *g_nbtn[6]; /* 通知触发按钮行 */
|
||||
static meow_widget *g_cancel; /* 取消最近一条通知 */
|
||||
static meow_widget *g_fs_btn; /* FULLSCREEN 进入按钮(主界面) */
|
||||
static meow_widget *g_demo_btn; /* 「控件库 Demo」入口按钮(主界面) */
|
||||
static const char *g_notif_labels[6] = { "INFO", "MEDIA", "HIGH", "PROG", "ONGO", "TGT" };
|
||||
static char g_btn_label[32] = "TAP ME";
|
||||
|
||||
void home_redraw(void)
|
||||
{
|
||||
const meow_theme *th = meow_theme_get();
|
||||
int sb = meow_ui_statusbar_height();
|
||||
if (sb > 0) meow_ui_fill_rect(0, sb, 480, 720 - sb, th->bg);
|
||||
else meow_ui_clear(th->bg);
|
||||
meow_ui_text_center(240, sb + 8, "MEOWOS HELLO", 28, th->fg);
|
||||
meow_ui_text_center(240, sb + 38, "SDK: meow_ui.a", 20, th->dim);
|
||||
meow_widget_draw(g_btn);
|
||||
meow_ui_text_center(240, 372, "tap = send notification (see log)", 20, th->dim);
|
||||
for (int i = 0; i < 6; i++) meow_widget_draw(g_nbtn[i]);
|
||||
meow_widget_draw(g_cancel);
|
||||
meow_widget_draw(g_fs_btn);
|
||||
meow_widget_draw(g_demo_btn);
|
||||
char line[64];
|
||||
snprintf(line, sizeof line, "taps=%d uptime=%ds", logic_taps_get(), logic_secs_get());
|
||||
meow_ui_text_center(240, 516, line, 20, th->dim);
|
||||
meow_ui_text(20, 660, "left-swipe = exit", 20, th->dim);
|
||||
meow_ui_flush();
|
||||
}
|
||||
|
||||
/* 业务→UI 监听器:taps 变化 → 重建按钮 label;secs 变化 → 重绘(仅本页在前台时,否则只改业务
|
||||
* 不覆写全屏帧——例如全屏态下 logic_secs_add 仍触发,但本页 active=0 跳过 redraw)。 */
|
||||
static void home_state_listener(int ev, void *ctx)
|
||||
{
|
||||
home_ctrl *c = (home_ctrl *)ctx;
|
||||
if (ev == LOGIC_EV_TAPS) {
|
||||
char lb[32];
|
||||
snprintf(lb, sizeof lb, "TAPPED x%d", logic_taps_get());
|
||||
meow_widget_free(g_btn);
|
||||
g_btn = meow_btn_create(120, 300, 240, 64, lb);
|
||||
}
|
||||
if (!c->active) return; /* 本页不在前台(全屏):不覆写当前帧 */
|
||||
home_redraw();
|
||||
}
|
||||
|
||||
int home_on_tap(int x, int y)
|
||||
{
|
||||
if (meow_widget_hit(g_demo_btn, x, y)) { meow_view_page_push(ACT_DEMO); return 1; }
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (meow_widget_hit(g_nbtn[i], x, y)) { notif_send(i); home_redraw(); return 1; }
|
||||
}
|
||||
if (meow_widget_hit(g_cancel, x, y)) { notif_cancel(); home_redraw(); return 1; }
|
||||
if (meow_widget_hit(g_fs_btn, x, y)) { meow_view_page_push(ACT_FULL); return 1; }
|
||||
if (meow_widget_hit(g_btn, x, y)) { logic_taps_bump(); return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void home_page_create(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((home_ctrl *)ctx)->view = v;
|
||||
g_btn = meow_btn_create(120, 300, 240, 64, g_btn_label);
|
||||
for (int i = 0; i < 6; i++)
|
||||
g_nbtn[i] = meow_btn_create(3 + i * 80, 400, 74, 56, g_notif_labels[i]);
|
||||
g_cancel = meow_btn_create(36, 464, 200, 42, "CANCEL LAST");
|
||||
g_fs_btn = meow_btn_create(244, 464, 200, 42, "FULLSCREEN");
|
||||
g_demo_btn = meow_btn_create(36, 560, 408, 44, "WIDGETS DEMO");
|
||||
/* 注册业务→UI 推送监听器(biz-UI 绑定点 = 本页控制器 ctx)。 */
|
||||
logic_set_listener(home_state_listener, ctx);
|
||||
}
|
||||
|
||||
static void home_page_enter(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((home_ctrl *)ctx)->active = 1;
|
||||
home_redraw();
|
||||
}
|
||||
|
||||
static void home_page_leave(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v;
|
||||
((home_ctrl *)ctx)->active = 0; /* 默认不销毁子控件;弹回时 on_enter 重绘恢复 */
|
||||
}
|
||||
|
||||
static void home_page_destroy(meow_view *v, void *ctx)
|
||||
{
|
||||
(void)v; (void)ctx;
|
||||
meow_widget_free(g_demo_btn);
|
||||
for (int i = 0; i < 6; i++) meow_widget_free(g_nbtn[i]);
|
||||
meow_widget_free(g_cancel);
|
||||
meow_widget_free(g_fs_btn);
|
||||
meow_widget_free(g_btn);
|
||||
g_btn = g_cancel = g_fs_btn = g_demo_btn = NULL;
|
||||
for (int i = 0; i < 6; i++) g_nbtn[i] = NULL;
|
||||
}
|
||||
|
||||
meow_view *home_view_create(void)
|
||||
{
|
||||
static const meow_view_hooks h = {
|
||||
.on_create = home_page_create,
|
||||
.on_enter = home_page_enter,
|
||||
.on_leave = home_page_leave,
|
||||
.on_destroy = home_page_destroy,
|
||||
};
|
||||
return meow_view_create(ACT_HOME, MEOW_VIEW_ACTIVITY, &h, &g_home_ctrl);
|
||||
}
|
||||
Reference in new issue
Block a user