Files
2026-08-09 22:20:01 +08:00

125 lines
4.4 KiB
C
Raw Permalink 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.
/* deshab/ui.h - 窗口装饰与色板
*
* 整合 desktop_app.h 的色板常量与 da_draw_titlebar/draw_statusbar,
* 以及 LINUXAPP.CNF 解析契约,统一前缀为 dsb_。
*
* 独立工具应用全屏运行时的窗口装饰:标题栏 + 关闭按钮 + 状态栏。
*/
#ifndef DESHAB_UI_H
#define DESHAB_UI_H
#include "types.h"
#include "app.h"
#include "fb.h"
#include "font.h"
/* ---- 色板(与 deshab_ui.h DP_* 一致) ---- */
#define DSB_BG_PRIMARY 0xFF0A1428u /* DP_ABYSS_900 */
#define DSB_BG_SECONDARY 0xFF0F1E38u /* DP_ABYSS_800 */
#define DSB_BG_TERTIARY 0xFF162848u /* DP_ABYSS_700 */
#define DSB_TEXT_PRIMARY 0xFFE8E8F0u /* DP_NEUTRAL_700 */
#define DSB_TEXT_DIM 0xFF6A6A88u /* DP_NEUTRAL_300 */
#define DSB_ACCENT 0xFF00A8CCu /* DP_SEAL_500 */
#define DSB_ACCENT_LIGHT 0xFF44CCF0u /* DP_SEAL_300 */
#define DSB_BORDER 0xFF284888u /* DP_ABYSS_500 */
#define DSB_BORDER_FOCUS 0xFF44CCF0u /* DP_SEAL_300 */
#define DSB_CURSOR_COLOR 0xFF00A8CCu /* DP_SEAL_500 */
#define DSB_PROMPT_COLOR 0xFF44CCF0u /* DP_SEAL_300 */
#define DSB_SUCCESS 0xFF40C880u /* DP_SUCCESS */
#define DSB_ERROR 0xFFFF4466u /* DP_ERROR */
#define DSB_WARNING 0xFFF0A030u /* DP_WARNING */
/* ---- 窗口装饰尺寸 ---- */
#define DSB_TITLEBAR_H 28
#define DSB_BORDER_W 2
#define DSB_STATUSBAR_H 20
static inline void dsb_draw_titlebar(dsb_app_context *ac, const char *title, i64 w) {
dsb_fill_rect(ac, 0, 0, w, DSB_TITLEBAR_H, DSB_BG_SECONDARY);
dsb_draw_string(ac, title, 8, (DSB_TITLEBAR_H - 18) / 2, DSB_TEXT_PRIMARY, DSB_BG_SECONDARY, 12);
/* 关闭按钮 */
dsb_fill_rounded_rect(ac, w - 28, 4, 24, 20, DSB_ERROR, 4);
dsb_draw_string(ac, "X", w - 20, 5, 0xFF0A1428u, DSB_ERROR, 12);
/* 底部分隔线 */
dsb_fill_rect(ac, 0, DSB_TITLEBAR_H, w, 1, DSB_ACCENT);
}
static inline void dsb_draw_statusbar(dsb_app_context *ac, const char *text, i64 w, i64 h) {
i64 y = h - DSB_STATUSBAR_H;
dsb_fill_rect(ac, 0, y, w, DSB_STATUSBAR_H, DSB_BG_SECONDARY);
dsb_draw_string(ac, text, 4, y + 1, DSB_TEXT_DIM, DSB_BG_SECONDARY, 12);
/* 顶部分隔线 */
dsb_fill_rect(ac, 0, y, w, 1, DSB_BORDER);
}
/* ---- Linux 桌面应用配置契约(LINUXAPP.CNF) ----
*
* desktop.elf 启动时从 FAT32 根目录读取 LINUXAPP.CNF(8.3 名 LINUXAPPCNF),
* 每行注册一个 Linux 应用图标:
* 显示名|linux命令
* 示例:
* NEOFETCH|/usr/bin/neofetch
* HTOP|/usr/bin/htop
* 规则:空行与 # 开头的行被忽略;显示名 <= 11 字符,命令 <= 63 字符。 */
#define DSB_LINUXAPP_CNF_83 "LINUXAPPCNF" /* FAT32 8.3 名 */
#define DSB_LINUXAPP_MAX 8
#define DSB_LINUXAPP_NAME_CAP 12
#define DSB_LINUXAPP_CMD_CAP 64
typedef struct {
char name[DSB_LINUXAPP_NAME_CAP];
char cmd[DSB_LINUXAPP_CMD_CAP];
} dsb_linux_app;
/* 解析 LINUXAPP.CNF 文本(允许非 NUL 结尾,按 size 截断)。
* 返回有效条目数(<= max)。 */
static inline int dsb_linuxapp_parse(const char *text, u32 size, dsb_linux_app *out, int max) {
int count = 0;
u32 pos = 0;
while (pos < size && count < max) {
char line[96];
int ll = 0;
while (pos < size && text[pos] != '\n') {
char c = text[pos++];
if (c == '\r') continue;
if (ll < 95) line[ll++] = c;
}
if (pos < size && text[pos] == '\n') pos++;
line[ll] = 0;
while (ll > 0 && (line[ll - 1] == ' ' || line[ll - 1] == '\t')) line[--ll] = 0;
int s = 0;
while (line[s] == ' ' || line[s] == '\t') s++;
if (line[s] == 0 || line[s] == '#') continue;
int bar = s;
while (line[bar] && line[bar] != '|') bar++;
if (line[bar] != '|') continue;
int ne = bar;
while (ne > s && (line[ne - 1] == ' ' || line[ne - 1] == '\t')) ne--;
if (ne <= s) continue;
int cs = bar + 1;
while (line[cs] == ' ' || line[cs] == '\t') cs++;
if (line[cs] == 0) continue;
int ni = 0;
for (int k = s; k < ne && ni < DSB_LINUXAPP_NAME_CAP - 1; k++)
out[count].name[ni++] = line[k];
out[count].name[ni] = 0;
int ci = 0;
for (int k = cs; line[k] && ci < DSB_LINUXAPP_CMD_CAP - 1; k++)
out[count].cmd[ci++] = line[k];
out[count].cmd[ci] = 0;
count++;
}
return count;
}
#endif /* DESHAB_UI_H */