Files
2026-02-24 01:39:10 +08:00

8.5 KiB
Raw Permalink Blame History

你是一个资深嵌入式 GUI 工程师,请用 LVGL 8.xC/C++)实现一个“GNSS Sky Plot(卫星天空图)”页面。 屏幕分辨率:横屏 480(w) × 222(h)。 要求:严格按下面给出的像素布局绘制;不要自作主张改布局;不要改元素文案;颜色体系必须围绕主色 0xEBA341,并与暖色工程风格一致;所有控件必须可复用、可刷新数据。

============================================================

  1. 页面总体布局(像素级) ============================================================
  • 页面根容器 root:尺寸 480×222,背景色为浅暖米色(见样式 token)。

  • 分三块: A. 顶部 TopBar:高度 30px,占满宽 480 B. 内容区 Content:高度 222-30=192pxy=30

    • 左侧 SkyPlotPanelx=8, y=38, w=277, h=176
    • 右侧 StatusPanelx=293, y=38, w=179, h=176 注:Content 区顶部留 8px 间距,因此两个 panel 的 y=30+8=38;左右 panel 之间留 8px 间距。
  • 全局圆角:8px

  • 全局描边:2px(主色强调边)

============================================================ 2) 样式与颜色 token(必须使用,统一风格)

主色(Amber): #EBA341 (0xEBA341) 主色深(AmberDark): #C98118 背景(WarmBG): #F6E6C6 面板底(PanelBG): #FAF0D8 分隔线(Line): #E7C98F 文字主(Text): #6B4A1E 文字弱(TextDim): #8A6A3A 警告(Warn): #B94A2C 成功(Ok): #3E7D3E 信息蓝(Info): #2D6FB6

星座颜色(用于 SYS/图例): GPS #E3B11F GLN #2D6FB6 GAL #3E7D3E BD #B94A2C

SNR 状态颜色(用于点的外环/填充): SNR_GOOD#3E7D3E SNR_FAIR#8FBF4D SNR_WEAK#C18B2C NOT_USED#B94A2C IN_VIEW #6E6E6E (灰)

字体:

  • 标题/栏标题:20px(或 LVGL 内置近似字号)
  • 表头:14px
  • 列表内容:16px
  • 底部 summary14px

============================================================ 3) TopBar(高度30

TopBar 容器:x=0,y=0,w=480,h=30,背景 WarmBG,底部分隔线 2px Line。 左侧标题:

  • label_title:改为 Summary 文本: "USE: 7/18|HDOP: 1.6|FIX: 3D"
  • USE/HDOP/FIX 三段使用不同颜色,整体与主题协调

右侧电量显示(仅占位,不实现电量算法):

  • battery_iconx=410,y=6,w=26,h=14,描边 2px TextDim,填充透明,右侧小凸点 3×6。
  • label_battx=442,y=5,文本 "100%",色 TextDim,字号 18。

============================================================ 4) 左侧 SkyPlotPanelx=8,y=38,w=292,h=176

面板容器:

  • panel_sky:圆角 10,背景 PanelBG,描边 2px AmberDark。

内部绘制一个“天空圆图”:

  • 圆图外接正方形区域 sky_areax=10,y=2,w=170,h=170(相对于 panel_sky => 圆心 C = (10+85, 2+85) = (95,87) 相对 panel_sky 内部坐标 => 半径 R = 82(留出描边与文字空间)

绘制内容(使用 lv_canvas 或自绘对象都可以,但必须呈现): a) 外圆(地平线 0°):圆环描边 Line 2px b) 3 条同心圆(30°/60°/90°):

  • r=R*2/3(约55
  • r=R*1/3(约27
  • r=0(中心点) 圆线使用 Line 1px 虚线效果(如做不到虚线,用细实线也可以) c) 十字方位线:N-S 与 E-W 两条线穿过圆心,线色 Line 1px d) 方位文字:
  • "N" 放在圆上方:中心对齐于圆心x,y=2-2(贴近圆外)
  • "E" 放右侧:x=10+170+8,y=95-10
  • "W" 放左侧:x=2,y=95-10(在圆左边空白处) 文字色 Text,字号 18 e) 仰角刻度文字:
  • 将刻度改为“指向 10 点半方向”:在圆心到 10:30 方向的斜线处依次标 "90°"(靠近外圈)、"60°"r=55处)、"30°"r=27处)
  • 文本沿该斜线排列,整体视觉连线指向 10 点半方向 文字色 TextDim,字号 16 f) 圆心附近标注:
  • label_horizon:放在圆心略下:文本 "0° Horizon",色 TextDim,字号 12

卫星点绘制(动态):

  • 每颗卫星用一个小圆点对象 sat_dot(建议 lv_obj + 圆角=半径)
  • 点半径:10px(直径20
  • 点内显示卫星 ID(两位或三位数字),文字白色或深棕(根据底色自动取对比度,优先白)
  • 点的位置由 (azimuth, elevation) 映射到圆内: r = R * (1 - elevation/90) x = Cx + r * sin(azimuth) y = Cy - r * cos(azimuth) (azimuth: 0°=N, 90°=E)
  • 点填充颜色:按星座(GPS/GLN/GAL/BD
  • 点外环/小标:按 SNR 状态(GOOD/FAIR/WEAK/NOT_USED/IN_VIEW):
    • GOOD/FAIR/WEAK:用对应颜色做 2px 外环
    • NOT_USED:外环 Warn
    • IN_VIEW:外环 灰
  • 若该卫星 used_in_fix=true,在点旁边增加小标签 "USE"
    • use_tag:圆角 6,背景 Ok,文字白色,字号 12
    • 位置:贴点左下角偏移(dx=-12, dy=12),避免遮挡数字

图例(在 SkyPlotPanel 内右下角区域):

  • legend_sys(星座图例)放在圆图右侧、靠下:
    • 小色块 10×10 + 文本(GPS/GLONASS/Galileo/BeiDou
    • 位置:x=190,y=105 起,行高 15
  • legend_snrSNR 图例)放在 legend_sys 上方、与其左对齐(SkyPlotPanel 右上角区域):
    • 文本顺序: "SNR Good" "SNR Weak" "Not Used" "In View"
    • 用小圆点示意(直径10+ 文本
    • 位置:x=190 起,纵向排布(行高 15),整体位于 legend_sys 上方;与 legend_sys 间距 6px;整体上移 30px;小圆点与文字排布规则同 legend_sys(色块 y+4,文字 x+14
    • 文本色 TextDim,字号 12

============================================================ 5) 右侧 StatusPanelx=293,y=38,w=179,h=176

面板容器:

  • panel_status:圆角 10,背景 PanelBG,描边 2px AmberDark

标题条(高度 26):

  • headerx=0,y=0,w=179,h=26,背景 Amber,圆角上半部保持
  • label:居中 "SATELLITE STATUS",文字色 #2A1A05,字号 14 加粗

表头行(高度 22y=26):

  • 背景:#F2D9A5
  • 列:ID / SYS / ELEV / SNR / USE
  • 列宽(像素):ID=24, SYS=38, ELEV=39, SNR=38, USED=39ELEV=USEDSNR=SYS
  • 文本居中,色 TextDim,字号 12

数据列表区(y=48 到 y=176,高度 128):

  • 以“固定行高”方式渲染,行高 17px,可显示 7 行(剩余滚动/分页不实现也可,但必须结构预留)
  • 每行 5 列对齐表头
  • 行底部分隔线 1px Line
  • SYS 文本颜色按星座色(GPS/GLN/GAL/BD
  • USED 列:若 used=true 显示 "YES" 颜色 Ok;否则 "NO" 颜色 Warn
  • 其它列文字色 Text
  • 当卫星数量超过可显示行数时,列表按以下优先级排序显示:USED=YES 优先,SNR 高优先,其次仰角高,再按 PRN/SVID 升序

底部 Summary 区移除,空间全部让给数据列表区

============================================================ 6) 数据结构与刷新接口(必须提供)

定义数据结构(示例):

  • struct SatInfo { int id; // PRN/SVID enum Sys {GPS, GLN, GAL, BD} sys; float azimuth; // 0..359 deg float elevation; // 0..90 deg int snr; // dB-Hz bool used; enum SNRState {GOOD, FAIR, WEAK, NOT_USED, IN_VIEW} snr_state; };

  • struct GnssStatus { int sats_in_use; int sats_in_view; float hdop; enum Fix {NOFIX, FIX2D, FIX3D} fix; };

必须实现两个刷新函数(供上层调用):

  • void ui_gnss_skyplot_set_sats(const SatInfo* sats, int count); -> 更新圆图卫星点(创建/复用对象),更新右侧表格前 N 行
  • void ui_gnss_skyplot_set_status(GnssStatus st); -> 更新底部 summary 文本与 FIX 颜色

============================================================ 7) 交互(最小)

  • 左上角允许预留 Back 按钮位置(但本需求不必须实现)。
  • 页面不需要触摸交互;仅需要刷新显示。
  • Backspace 键行为:触发 TopBar 的 Back 按钮逻辑,与其它页面一致。

============================================================ 8) 交付物要求

  • 提供一个函数 ui_gnss_skyplot_create(lv_obj_t* parent) 返回页面根对象。
  • 所有对象指针保存在静态/结构体中,支持重复进入页面不泄漏。
  • 不要使用外部图片资源;全部用 LVGL 绘制。
  • 输出代码应可直接编译(伪代码不接受)。

按以上要求生成完整 LVGL 页面代码。