状态栏正确闭环(agent-142): 系统进程统一渲染+App不画+覆盖叠加+数据唯一+MD3图标式+主题换图标
- meow_ui_sys_set_system_mode: launcher置1才渲染, App默认0→不画状态栏; app_overlay_statusbar在launch_app循环~1s叠加28px顶条(不SIGSTOP App) - 数据源唯一(launcher g_sys→meow_ui_sys_feed; wifi_level/batt/vol/bri/clock), 根治"launcher有亮度App没有" - 右侧=MD3图标+变量值(statusbar_right_str文本退役→图标簇, 复用sb_icons.h/MEOW_SB_ICON_*/meow_gfx_blit_icon); 颜色随meow_theme - ui.style换图标集(meow_ui_style/set_style读ui.style md3/miuix, MIUIx暂MD3占位) - hello最小改动(redraw非全屏只清inset=28之下, 不冲系统顶条); 开放点: App不SIGSTOP/inset28/MIUIx占位/set_statusbar系统模式门 - meow_ui.a=3da5af7b launcher=a2b1c096 hello=67075741 0warning; 宿主test_sb_statusbar ALL PASS + render PPM目检(左时钟右亮度/WiFi/蓝牙/音量/电量) - 遗留: 真机验证(无双画/数据一致/顶条叠加/inset/ui.style); 运行时fullscreen沉浸叠画待M3; MIUIx图标占位
This commit is contained in:
1 parent
2a6c4e97c5
commit
7300fc0a13
14 files changed
+731
-44
No files matched your search
+91
-31
@@ -35,6 +35,10 @@ static int g_sys_inited = 0;
|
||||
static int g_statusbar_on = 1; /* 默认显示 */
|
||||
static int g_fullscreen = 0; /* 默认非全屏 */
|
||||
static int g_statusbar_force = 0; /* 1s 刷新后置位,强制重画顶部条 */
|
||||
/* 「同一个状态栏」闭环(§3.1/FRAMEWORK_DESIGN §10.2):状态栏 = 系统级组件,仅系统进程
|
||||
* (launcher) 渲染。g_sys_render=1 表示本进程是系统 UI —— meow_ui_sys_statusbar_render /
|
||||
* present() 据此决定是否画出顶条/提示线;App 进程保持 0(不渲染)+ 仍 inset 28(launcher 叠加)。 */
|
||||
static int g_sys_render = 0; /* 1=本进程为系统 UI(渲染);0=App(不渲染,仅 inset) */
|
||||
|
||||
static uint64_t now_ms(void)
|
||||
{
|
||||
@@ -129,7 +133,9 @@ void meow_ui_sys_refresh(void)
|
||||
|
||||
char op[16];
|
||||
read_str("/sys/class/net/wlan0/operstate", op, sizeof op);
|
||||
g_sys.wifi_on = !strcmp(op, "up") ? 1 : 0;
|
||||
g_sys.wifi_connected = !strcmp(op, "up") ? 1 : 0;
|
||||
g_sys.wifi_on = g_sys.wifi_connected; /* SDK 自身读不到射频 vs 关联的区分,一起走 operstate */
|
||||
g_sys.wifi_level = -1000; /* 信号分档由 launcher 喂(唯一权威源);SDK 不读 /proc 无线 */
|
||||
|
||||
g_sys.vol = settings_vol();
|
||||
g_sys.brightness = settings_bright(); /* 兜底读 settings;launcher 喂入会覆盖(更即时) */
|
||||
@@ -159,18 +165,36 @@ const meow_sys_state *meow_ui_sys_get(void) { return &g_sys; }
|
||||
void meow_ui_sys_feed(const meow_ui_feed *f)
|
||||
{
|
||||
if (!f) return;
|
||||
g_sys.batt = f->batt;
|
||||
g_sys.charging = f->charging;
|
||||
g_sys.wifi_on = f->wifi_on;
|
||||
g_sys.bt_seen = f->bt_seen;
|
||||
g_sys.bt_on = f->bt_on;
|
||||
g_sys.vol = f->vol;
|
||||
g_sys.batt = f->batt;
|
||||
g_sys.charging = f->charging;
|
||||
g_sys.wifi_on = f->wifi_on;
|
||||
g_sys.wifi_connected = f->wifi_connected;
|
||||
g_sys.wifi_level = f->wifi_level;
|
||||
g_sys.bt_seen = f->bt_seen;
|
||||
g_sys.bt_on = f->bt_on;
|
||||
g_sys.vol = f->vol;
|
||||
if (f->brightness <= 0) g_sys.brightness = 0; /* 未知/屏关:不入顶条(>0 才显示) */
|
||||
else if (f->brightness > 100) g_sys.brightness = 100;
|
||||
else g_sys.brightness = f->brightness;
|
||||
g_statusbar_force = 1; /* 数据已变 → 顶条必重画 */
|
||||
}
|
||||
|
||||
/* ---- 系统 UI 模式(「同一个状态栏」闭环;launcher 调用)----
|
||||
* launcher(系统进程)链 meow_ui.a 后调 meow_ui_sys_set_system_mode(1):本进程渲染全局状态栏
|
||||
* (present() 前置合成 + App 前台叠加)。App 进程默认 0:不渲染状态栏、只 inset(§6.1 ③ /
|
||||
* FRAMEWORK_DESIGN §10.2)。meow_ui_sys_statusbar_active()/meow_ui_statusbar_height() 不随此
|
||||
* 开关变(App 仍报告 28px inset + 顶部热区),仅渲染路径受控。 */
|
||||
void meow_ui_sys_set_system_mode(int on)
|
||||
{
|
||||
g_sys_render = on ? 1 : 0;
|
||||
g_statusbar_force = 1; /* 切换即强制下次 present 反映(画/不画顶条) */
|
||||
}
|
||||
|
||||
int meow_ui_sys_render_enabled(void)
|
||||
{
|
||||
return g_sys_render;
|
||||
}
|
||||
|
||||
/* ---- 公共 API ---- */
|
||||
void meow_ui_set_statusbar(int visible)
|
||||
{
|
||||
@@ -225,35 +249,50 @@ int meow_ui_sys_statusbar_force(void)
|
||||
return f;
|
||||
}
|
||||
|
||||
/* 状态栏右侧信息串:batt% WIFI 蓝牙 VOL nn% 亮度nn%(同 launcher 状态栏右侧语义,文本式)。
|
||||
* mfont 就绪用 CJK「蓝牙/亮度」,否则回退 ASCII "BT/BRI"(28px 栏紧凑,避免超宽叠到时钟)。
|
||||
* 顺序与 launcher 右侧簇一致:电量 → WiFi → 蓝牙 → 音量 → 亮度。*/
|
||||
static void statusbar_right_str(char *out, size_t n)
|
||||
/* ---- 右侧信息簇(MD3 图标 + 变量值,取代文本式 statusbar_right_str)----
|
||||
* 「同一个状态栏」右侧 = 图标+值:电量图标+% / 音量图标+% / 蓝牙图标 / WiFi 图标(信号分档)/
|
||||
* 亮度图标+%(可选,与时钟不重叠才画)。图标位图来自 sb_icons.h(复用 launcher);
|
||||
* 文字=紧凑数值(%d%%),无 CJK 依赖;颜色随 meow_theme(日/夜)由主题表提供。
|
||||
* 顺序(右→左):电量(最右)→ 音量 → 蓝牙 → WiFi → 亮度。 */
|
||||
/* 注:旧文本式右侧串 statusbar_right_str 已退役为图标簇(同上),不再保留调用路径。 */
|
||||
|
||||
/* 画一个右对齐项:右边界=*xr,画完向左推进 *xr(含 MEOW_SB_XGAP 项间隙)。
|
||||
* icon>=0 画图标(可配右侧数值 txt;txt==NULL 仅图标)。文字/图标同用主题色 col。
|
||||
* ink_h 传给 meow_gfx_blit_icon(主图标用 MEOW_SB_ICON_INK 等大;WiFi 强弱档传 0 保持自然 ink)。
|
||||
* 返回该项左边缘(供亮度可选判宽)。 */
|
||||
static int sb_r_place(int *xr, int icon, const char *txt, uint32_t col, int ink_h, int ty)
|
||||
{
|
||||
char batt[16] = "", wifi[16] = "", vol[20] = "", bt[16] = "", bri[20] = "";
|
||||
if (g_sys.batt >= 0) snprintf(batt, sizeof batt, "%d%%", g_sys.batt);
|
||||
if (g_sys.wifi_on) snprintf(wifi, sizeof wifi, "WIFI");
|
||||
snprintf(vol, sizeof vol, "VOL %d%%", g_sys.vol);
|
||||
if (g_sys.bt_seen && g_sys.bt_on)
|
||||
snprintf(bt, sizeof bt, meow_gfx_mfont_ready() ? "蓝牙" : "BT");
|
||||
if (g_sys.brightness > 0) /* >0 才显示(屏常亮态);0=屏关/未知不入 */
|
||||
snprintf(bri, sizeof bri, meow_gfx_mfont_ready() ? "亮度%d%%" : "BRI %d%%", g_sys.brightness);
|
||||
out[0] = 0;
|
||||
if (batt[0]) strcat(out, batt);
|
||||
if (wifi[0]) { if (out[0]) strcat(out, " "); strcat(out, wifi); }
|
||||
if (bt[0]) { if (out[0]) strcat(out, " "); strcat(out, bt); }
|
||||
if (vol[0]) { if (out[0]) strcat(out, " "); strcat(out, vol); }
|
||||
if (bri[0]) { if (out[0]) strcat(out, " "); strcat(out, bri); }
|
||||
int iconw = (icon >= 0) ? MEOW_SB_ICON_SIZE : 0;
|
||||
int gap = (icon >= 0 && txt) ? MEOW_SB_TGAP : 0;
|
||||
int tw = txt ? meow_ui_text_width(txt, MUI_SBAR_FONT) : 0;
|
||||
int x = *xr - (iconw + gap + tw);
|
||||
if (icon >= 0) { meow_gfx_blit_icon(icon, x, 0, ink_h, col, MEOW_SB_ICON_CY); x += iconw + gap; }
|
||||
if (txt) meow_ui_text_right(*xr, ty, txt, MUI_SBAR_FONT, col);
|
||||
*xr -= (iconw + gap + tw) + MEOW_SB_XGAP;
|
||||
return *xr + MEOW_SB_XGAP;
|
||||
}
|
||||
|
||||
/* WiFi 信号分档(g_sys.wifi_connected + wifi_level)→ 图标索引。
|
||||
* 网卡关 → -1(不画);开未关联 → SB_I_WIFI_NO;已关联 → 按 dBm 分 STRONG/MEDIUM/WEAK(未知→满格)。 */
|
||||
static int sb_wifi_icon(void)
|
||||
{
|
||||
if (!g_sys.wifi_on) return MEOW_SB_ICON_WIFI_OFF;
|
||||
if (!g_sys.wifi_connected) return MEOW_SB_ICON_WIFI_NO;
|
||||
if (g_sys.wifi_level <= -1000) return MEOW_SB_ICON_WIFI_STRONG; /* 未知 → 满格 */
|
||||
if (g_sys.wifi_level >= -60) return MEOW_SB_ICON_WIFI_STRONG;
|
||||
if (g_sys.wifi_level >= -75) return MEOW_SB_ICON_WIFI_MEDIUM;
|
||||
return MEOW_SB_ICON_WIFI_WEAK;
|
||||
}
|
||||
|
||||
void meow_ui_sys_statusbar_render(void)
|
||||
{
|
||||
if (!g_sys_render) return; /* 仅系统进程(launcher)渲染;App 不画顶条 */
|
||||
if (!meow_ui_sys_statusbar_active()) return;
|
||||
const meow_theme *th = meow_theme_get();
|
||||
int w = meow_ui_width();
|
||||
int h = MUI_SBAR_H;
|
||||
|
||||
/* 整条清底:覆盖 app 可能画进顶行的内容(z 最顶) */
|
||||
/* 整条清底:覆盖 app 可能画进顶行的内容(z 最顶)。仅系统进程(launcher)渲染本函数。 */
|
||||
meow_ui_fill_rect(0, 0, w, h, th->bg);
|
||||
|
||||
/* 文字垂直锚 y:(栏高-行高)/2 居中;下限 1 防极端行高 > 栏高时负 y 溢出顶端(不越界优先)。 */
|
||||
@@ -268,11 +307,32 @@ void meow_ui_sys_statusbar_render(void)
|
||||
snprintf(timebuf, sizeof timebuf, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
meow_ui_text(8, ty, timebuf, MUI_SBAR_FONT, th->fg);
|
||||
|
||||
/* 右侧信息串:batt% WIFI 蓝牙 VOL nn% */
|
||||
char right[96];
|
||||
statusbar_right_str(right, sizeof right);
|
||||
if (right[0])
|
||||
meow_ui_text_right(w - 8, ty, right, MUI_SBAR_FONT, th->fg);
|
||||
/* 右侧 MD3 图标簇(从右端 w-8 往左)。主项色 th->fg;次级(蓝牙/弱信号)用 on_surface_variant。
|
||||
* 亮度「可选」:仅在右簇左缘与时钟右缘相距足够(MEOW_SB_CLK_MARGIN)时画,避免与时钟叠字。 */
|
||||
uint32_t col = th->fg, col2 = th->dim; /* col=主色;col2=次要色(蓝牙/分隔用 on_surface_variant=dim 近似) */
|
||||
int xr = w - 8;
|
||||
char val[16];
|
||||
if (g_sys.batt >= 0) { /* 电量:图标+%(未知不画)——最右项 */
|
||||
snprintf(val, sizeof val, "%d%%", g_sys.batt);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BATT, val, col, MEOW_SB_ICON_INK, ty);
|
||||
}
|
||||
snprintf(val, sizeof val, "%d%%", g_sys.vol);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_VOL, val, col, MEOW_SB_ICON_INK, ty); /* 音量:图标+% */
|
||||
if (g_sys.bt_seen && g_sys.bt_on) { /* 蓝牙:仅图标(上电即显示,连接态占位;多态留后续) */
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BT_CONN, NULL, col2, MEOW_SB_ICON_INK, ty);
|
||||
}
|
||||
if (g_sys.wifi_on) { /* WiFi:仅图标(关不画;开未连/分档) */
|
||||
int wco = sb_wifi_icon();
|
||||
int is_weak = (wco == MEOW_SB_ICON_WIFI_MEDIUM || wco == MEOW_SB_ICON_WIFI_WEAK);
|
||||
sb_r_place(&xr, wco, NULL, col, is_weak ? 0 : MEOW_SB_ICON_INK, ty);
|
||||
}
|
||||
if (g_sys.brightness > 0) { /* 亮度:图标+%(>0 才显示;与时钟不重叠才画) */
|
||||
int bl = (g_sys.brightness > 100) ? 100 : g_sys.brightness;
|
||||
snprintf(val, sizeof val, "%d%%", bl);
|
||||
int bw = MEOW_SB_ICON_SIZE + MEOW_SB_TGAP + meow_ui_text_width(val, MUI_SBAR_FONT) + MEOW_SB_XGAP;
|
||||
if (xr - bw > 8 + meow_ui_text_width(timebuf, MUI_SBAR_FONT) + MEOW_SB_CLK_MARGIN)
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BRIGHT, val, col, MEOW_SB_ICON_INK, ty);
|
||||
}
|
||||
|
||||
/* 分隔线(栏内最底 1px,主题次要色);内容 inset=statusbar_height()=28 从 y=28 起即干净 */
|
||||
meow_ui_fill_rect(0, h - 1, w, 1, th->dim);
|
||||
|
||||
Reference in new issue
Block a user