Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/meow_notif_panel.h
T
MeowOS 2b17f69f24 阶段B 通知中心UI(agent-123) + 进程模型/文档完整(agent-124) + 对外README(agent-125)
- 通知中心=launcher侧系统级叠加层(§6.1③ 仅内部): meow_notif_panel.h(纯逻辑) + meow_launcherd.c(内联 draw/run_notif_center + run_menu顶部热区下滑接入) + test_notif_panel.c(56单测)
- 通知中心零旁路走 meow_settings_*; 通知列表读 meow_notif; 左缘返回复用 meow_edge_back; 局部脏区; 系统级控件无公共API(App无法自建悬浮层)
- meow_ui.a 零改动(d249c6e6); meow_launcherd=4652901a(0warn)
- FRAMEWORK_DESIGN §10 进程模型/Supervisor树(svcd服务子进程化隔离防级联崩) ; MEOW_APP_SDK §6.1 系统UI归launcher+SDK/APP进程隔离; NOTIFICATION_SYSTEM §9 归属; SYSTEM_SETTINGS/SPEC_REF/DEVELOPMENT_PLAN 补齐
- README 重写为面向第三方(进度/架构/构建/部署/SDK开发; 固件打包标注本地工具不入库, 无敏感)
- 遗留: SDK(App进程)侧通知中心/activity跳转 依赖 M3 导航栈(独立里程碑); 真机待验证
2026-08-30 15:59:23 +08:00

117 lines
4.7 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.
/* meow_notif_panel.h — 通知中心面板的纯逻辑(header-only,宿主可单测)。
*
* 定位:把通知中心面板里「无副作用、可独立判定」的部分抽成 static inline,
* 供 launcher(meow_launcherd.c 内嵌面板)与宿主单测(test_notif_panel.c)共用同一份实现,
* 避免两端漂移;绘制/触摸循环等依赖 launcher static 符号的部分留在 meow_launcherd.c 内。
*
* 不依赖 launcher 头 / SDK 头,仅 <stdint.h> <string.h> <stdio.h> <time.h> —— 纯宿主可编。
*/
#ifndef MEOW_NOTIF_PANEL_H
#define MEOW_NOTIF_PANEL_H
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
/* ---- 手势判定 ---- */
/* 左缘宽度:与 launcher meow_touch.h MEOW_EDGE_W(24) / SDK 全局左缘返回同口径。
* 顶部下滑打开通知中心时,左缘起点保留给「左缘返回」,不与其抢占(spec-ref §5.1)。 */
#ifndef MNP_EDGE_W
#define MNP_EDGE_W 24
#endif
/* 顶部热区下滑 → 打开通知中心(纯函数)。
* down_x/down_y=抬手原点;dx/dy=抬手位移(当前-原点,即 t_last - t_down);hotzone=顶部热区高
* (launcher=SB_BAR_H=28);thresh=下滑触发位移阈值(launcher=MENU_SWIPE_THRESH=65)。
* 返回 1=应打开。约束:起点不在左缘(down_x>=MNP_EDGE_W,左缘保留给返回)+ 起点落在顶部热区
* (down_y ∈ [0,hotzone))+ 向下主导(dy>=thresh 且 |dy|>|dx|)。调用方通常先判左缘返回
* (meow_edge_back)+ 本函数,两者互斥。 */
static inline int mnp_top_swipe_down(int down_x, int down_y, int dx, int dy,
int hotzone, int thresh)
{
if (down_x < MNP_EDGE_W) return 0; /* 左缘保留给返回手势 */
if (down_y < 0 || down_y >= hotzone) return 0;
if (dy < thresh) return 0; /* 未达下滑阈值 / 向上 */
int ax = dx < 0 ? -dx : dx;
return ax < dy; /* 向下主导(横向位移小于竖向) */
}
/* 竖向主导上滑(面板内关闭):dy<=-thresh 且 |dy|>|dx|。返回 1=应关闭。 */
static inline int mnp_vertical_up(int dx, int dy, int thresh)
{
if (dy > -thresh) return 0;
int ax = dx < 0 ? -dx : dx;
return ax < -dy;
}
/* ---- 滑条 ---- */
/* 滑条值映射:px(屏幕坐标)→ 值,clamp 到 [min,max]。sx=track 左缘、sw=track 宽。
* 与 launcher 设置页 s_slider_val_from_x 同构(此处参数化,供面板亮度/音量滑条与单测用)。 */
static inline int mnp_slider_val_from_x(int px, int sx, int sw, int min, int max)
{
int range = max - min;
int v = min + (range ? (px - sx) * range / sw : 0);
if (v < min) v = min;
if (v > max) v = max;
return v;
}
/* ---- 亮度 clamp ---- */
/* 亮度 clamp:下限 vmin(=display.brightness_min,≥1 防黑屏)、上限 100(防闪屏)。
* vmin<1 时钳到 1。与 SYSTEM_SETTINGS §1 / spec-ref A-3 一致(旧文档 25 为陈旧值)。 */
static inline int mnp_brightness_clamp(int v, int vmin)
{
if (vmin < 1) vmin = 1;
if (v < vmin) v = vmin;
if (v > 100) v = 100;
return v;
}
/* ---- 时间显示 ---- */
/* 通知时间(created_ms 墙钟 epoch ms)→ 显示串。
* <60s「刚刚」;<60min「N分钟前」;否则本地「HH:MM」。now_ms=当前墙钟 epoch ms。 */
static inline void mnp_time_ago(uint64_t created_ms, uint64_t now_ms, char *buf, int len)
{
if (!buf || len <= 0) return;
if (now_ms < created_ms) now_ms = created_ms; /* 时钟回拨防御 */
uint64_t diff = now_ms - created_ms;
if (diff < 60000u) { if (len >= 1) snprintf(buf, (size_t)len, "刚刚"); return; }
if (diff < 3600000u) {
snprintf(buf, (size_t)len, "%llu分钟前", (unsigned long long)(diff / 60000u));
return;
}
time_t t = (time_t)(created_ms / 1000u);
struct tm tm;
if (localtime_r(&t, &tm))
snprintf(buf, (size_t)len, "%02d:%02d", tm.tm_hour, tm.tm_min);
else if (len >= 1) snprintf(buf, (size_t)len, "--:--");
}
/* ---- 列表命中 ---- */
/* 通知列表行命中:y 为绝对纵坐标;list_top/list_bot 为列表区上下缘;row_h 为行高。
* 返回行号(0 起);越界返回 -1。 */
static inline int mnp_row_at(int y, int list_top, int list_bot, int row_h)
{
if (y < list_top || y >= list_bot) return -1;
int r = (y - list_top) / row_h;
return r;
}
/* 列表滚动 clainmp:把 scroll 钳到 [0, total-view]。content 高度=total(总行数*row_h)。 */
static inline int mnp_scroll_clamp(int scroll, int total, int view)
{
if (total <= view) return 0;
int mx = total - view;
if (scroll < 0) scroll = 0;
if (scroll > mx) scroll = mx;
return scroll;
}
#endif /* MEOW_NOTIF_PANEL_H */