Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/statusbar.c
T
MeowOS e6f0b665e3 refactor(launcher): 拆分 meow_launcherd.c(9778行)→meow_launcherd/ 多文件(agent-149)
- 14 模块 .c + meow_launcher_internal.h(642): util/font_theme/fb_compositor/settings_page/power_menu/notif_center/app_launcher/main_menu/audio/backlight/net/keys/about/statusbar; meow_launcherd.c 已删
- 按行逐字搬移(0-diff), 118函数提升非static+47组extern(内部头), #if0退役区不编入(源码留.pre_split.bak)
- 关于本机小改: 作者 AskaEth/17 + info/item[13]防越界 + s_dd_modal 超高滚动(clamp/触摸滚动/音量键跟随/裁剪, 仅超高启用)
- build_launcher.sh 编译列表→模块; 文档/注释引用 meow_launcherd.c→模块/目录
- 编译0warning/-Wall -Wextra告警集与原文一致(77条无新增)/qemu-mipsel冒烟一致(--scan/--sysdump); launcher=c0799357(505KB; md5因多文件重编译与原文异,非回归依据)
- 备份 meow_launcherd.c.pre_split.bak/meow_launcherd.pre_split.bak; M2.69(0.7.64)已推卡并用户验证OK
2026-08-30 21:38:30 +08:00

112 lines
6.3 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.
/* statusbar.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/
/* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/
#include "meow_launcher_internal.h"
int g_sb_icon_cy = SB_ICON_CY;
/* 状态栏文字垂直锚 y(行首升线顶):(栏高-行高)/2 把文字垂直居中于 28px 栏;
* 下限 1 防极端行高(>栏高)时算出负 y 溢出顶端(不越界优先)。 */
/* 状态栏 MD3 图标 blit:把 sb_icons.h 的 32x32 单通道 alpha 位图画进状态栏(fb = SDK back_buf)。
* x = 图标槽左缘(槽宽 SB_ICON_SIZE);fg = 24-bit RGB 前景色(主题 on_surface / on_surface_variant)。
* M2.46-2 视觉对齐(音量图标小一圈/下边距、图标与文字垂直中心):
* - 先求该位图 ink 边界(阈值 32,忽略近透明抗锯齿);按 ink 边界在槽内水平居中,并把 ink 垂直
* 中心对齐到全局 g_sb_icon_cy(==状态栏文字中心),→ 所有图标共用同一光学中线,不再「偏下」。
* - ink_h>0 时对 ink 做等比缩放(绘制时最近邻采样,源位图不变)到该 ink 高:主图标统一用
* SB_ICON_INK,音量(volume_up ink 较矮)随之放大到与电量/亮度一致 → 不显「小一圈」。
* - ink_h==0 保持位图自然 ink 尺寸(仅居中):用于 WiFi 强弱档——较短 ink(少一格)本身即
* 「信号弱」语义,不可被等比拉大。
* 像素 = 前景与背景按 alpha 软边混合(a<8 跳过透明;a>=240 直写前景;其余按 a>>4 在 565 空间
* 插值),与 blit_pm_icon 同构——暗/亮主题下图标随状态栏底色一起换色。 */
void sb_blit_icon(int icon_idx, int x, uint32_t fg, int ink_h)
{
const unsigned char *src = sb_icons[icon_idx].data;
uint16_t col = rgb565(fg);
/* 1) ink 边界(含空图兜底) */
int minx = SB_ICON_SIZE, miny = SB_ICON_SIZE, maxx = -1, maxy = -1;
for (int i = 0; i < SB_ICON_SIZE * SB_ICON_SIZE; i++) {
if (src[i] >= 32) {
int xx = i % SB_ICON_SIZE, yy = i / SB_ICON_SIZE;
if (xx < minx) minx = xx; if (xx > maxx) maxx = xx;
if (yy < miny) miny = yy; if (yy > maxy) maxy = yy;
}
}
if (maxx < minx || maxy < miny) { minx = miny = 0; maxx = maxy = SB_ICON_SIZE - 1; }
int ink_w = maxx - minx + 1, ink_h_n = maxy - miny + 1;
int t_h = (ink_h > 0) ? ink_h : ink_h_n; /* 目标 ink 高 */
int t_w = ink_w * t_h / ink_h_n; if (t_w < 1) t_w = 1;
if (t_w > SB_ICON_SIZE * 2) t_w = SB_ICON_SIZE * 2; /* 防御:等比极端上限 */
/* 2) 目标框左上:水平居中于 32px 槽;垂直中心 = g_sb_icon_cy */
int x0 = x + (SB_ICON_SIZE - t_w) / 2;
int y0 = g_sb_icon_cy - t_h / 2;
/* 3) 最近邻采样映射:目标 (dx,dy) ← 源 ink (minx+dx*ink_w/t_w, miny+dy*ink_h_n/t_h) */
for (int dy = 0; dy < t_h; dy++) {
int ty = y0 + dy;
if (ty < 0 || ty >= fb_yres) continue;
int sy = miny + (dy * ink_h_n) / t_h;
uint16_t *row = (uint16_t *)fb + ty * (fb_line / 2);
for (int dx = 0; dx < t_w; dx++) {
int tx = x0 + dx;
if (tx < 0 || tx >= fb_xres) continue;
int sx = minx + (dx * ink_w) / t_w;
int a = src[sy * SB_ICON_SIZE + sx];
if (a < 8) continue; /* 透明像素跳过 */
uint16_t bg = row[tx];
if (a >= 240) { row[tx] = col; continue; }
int a4 = a >> 4; /* 0..15 */
int r = ((col >> 11) * a4 + ((bg >> 11) & 0x1F) * (16 - a4)) >> 4;
int g = (((col >> 5) & 0x3F) * a4 + ((bg >> 5) & 0x3F) * (16 - a4)) >> 4;
int b = ((col & 0x1F) * a4 + (bg & 0x1F) * (16 - a4)) >> 4;
row[tx] = (uint16_t)((r << 11) | (g << 5) | b);
}
}
}
/* ---- Stage-One 状态栏收敛:launcher 不再自绘状态栏,统一由 SDK 全局状态栏绘制 ----
* launcher 系统界面(主界面/设置页/电源菜单/通知中心)顶部 28px 状态栏改由 SDK 的
* meow_ui_sys_statusbar_render()(present() 时合成,z 最顶)绘制。launcher 侧只保留三个
* 入口(paint_sb_clock/paint_sb_right/draw_statusbar,调用点遍布主界面/设置页/通知中心/
* 音量/亮度/主题变更/1s 时钟),其职责从「自绘」改为「把权威状态喂进 SDK + 标脏顶条」。
* 依据(devdocs/plan/LAUNCHER_SDK_REWRITE.md):
* - launcher 不跑 SDK 事件循环 → SDK 的 meow_ui_sys_refresh() 不在 launcher 触发,数据
* 必须由 launcher 喂。g_sys(meow_sys_refresh/light + 事件路径维护)是权威源,尤其
* 亮度/音量(写入方=launcher)。
* - SDK 主题是缓存的 → 喂前 meow_theme_reload() 逼重读 settings,状态栏跟手 launcher 换肤。
* - 标脏顶条 (0,0,xres,28) → present() 时 SDK 重画顶条;SDK 只在「数据变(force)/顶条被触及/
* 收合过渡」才重画,天然满足「状态栏只在变化时重绘」。 */
static void sb_sdk_refresh(void)
{
meow_theme_reload(); /* SDK 状态栏主题随 launcher 换肤(重读 settings) */
meow_ui_feed f;
f.batt = g_sys.batt;
f.charging = g_sys.charging;
f.wifi_on = g_sys.wifi_on;
f.wifi_connected = g_sys.wifi_connected;
f.wifi_level = g_sys.wifi_level;
f.bt_seen = g_sys.bt_seen;
f.bt_on = g_sys.bt_on;
f.vol = g_sys.vol;
f.brightness = g_sys.brightness;
meow_ui_sys_feed(&f); /* 权威快照喂入 + 置 force(顶条必重画) */
meow_dirty_add(0, SB_BAR_Y, fb_xres, SB_BAR_H); /* 标脏顶条 → present() 时 SDK 重画 */
}
/* 三个入口(调用点不动):现在驱动 SDK 全局状态栏(唯一绘制者),不再自绘。 */
void paint_sb_clock(void) { sb_sdk_refresh(); }
void paint_sb_right(void) { sb_sdk_refresh(); }
void draw_statusbar(void) { sb_sdk_refresh(); } /* 对齐原语义:整条状态栏 → SDK 绘制 */
/* 上次读到的 App 顶条模式(用于在 launch_app waitpid 循环里判「模式新变 → 立即叠一次」)。
* 高整文件作用域;每次启动 App 前重置为 -1(强制首帧同步一次)。 */
int g_sb_mode_last = -1;