9.6 KiB
You are a senior embedded GUI engineer. Please use LVGL 8.x (C/C++) to implement a "GNSS Sky Plot (Satellite Sky Map)" page. Screen resolution: landscape 480(w) × 222(h). Requirements: Draw strictly according to the pixel layout given below; do not change the layout on your own; do not change element copy; the color system must revolve around the main color 0xEBA341 and be consistent with the warm color engineering style; all controls must be reusable and data refreshable.
============================================================
- Overall page layout (pixel level) ============================================================
-
Page root container root: size 480×222, background color is light warm beige (see style token).
-
Divided into three parts: A. Top TopBar: height 30px, full width 480 B. Content area Content: height 222-30=192px, y=30
-
left SkyPlotPanel: x=8, y=38, w=277, h=176
-
right StatusPanel: x=293, y=38, w=179, h=176 Note: Leave 8px spacing at the top of the Content area, so y=30+8=38 for the two panels; leave 8px spacing between the left and right panels.
-
Global rounded corners: 8px
-
Global stroke: 2px (main color emphasizes the edge)
============================================================ 2) Style and color token (must be used, unified style)
Main color (Amber): #EBA341 (0xEBA341) Main color dark (AmberDark): #C98118 Background (WarmBG): #F6E6C6 Panel bottom (PanelBG): #FAF0D8 Line: #E7C98F Text: #6B4A1E TextDim: #8A6A3A Warn: #B94A2C Success (Ok): #3E7D3E Information blue (Info): #2D6FB6
Constellation color (for SYS/legend): GPS: #E3B11F GLN: #2D6FB6 GAL: #3E7D3E BD: #B94A2C
SNR status color (for outer ring/padding of points): SNR_GOOD:#3E7D3E SNR_FAIR:#8FBF4D SNR_WEAK:#C18B2C NOT_USED:#B94A2C IN_VIEW: #6E6E6E (gray)
Font:
- Title/column header: 20px (or LVGL Built-in approximate font size)
- Header: 14px
- List content: 16px
- Bottom summary: 14px
============================================================ 3) TopBar (height 30)
TopBar container: x=0,y=0,w=480,h=30, background WarmBG, bottom divider 2px Line. Left title:
- label_title: changed to Summary text: "USE: 7/18|HDOP: 1.6|FIX: 3D"
- The three sections of USE/HDOP/FIX use different colors, and the whole is coordinated with the theme
Battery display on the right (only placeholder, does not implement the battery algorithm):
- battery_icon: x=410, y=6, w=26, h=14, stroke 2px TextDim, filled with transparent, small bump on the right 3×6.
- label_batt: x=442, y=5, text "100%", color TextDim, font size 18.
============================================================ 4) Left SkyPlotPanel (x=8,y=38,w=292,h=176)
Panel container:
- panel_sky: Rounded Corners 10, Background PanelBG, Stroke 2px AmberDark.
Draw a "sky circle chart" internally:
- Circle chart circumscribed square area sky_area: x=10, y=2, w=170, h=170 (relative to panel_sky) => Circle center C = (10+85, 2+85) = (95,87) relative to panel_sky Internal coordinates => Radius R = 82 (leaving space for stroke and text)
Drawing content (you can use lv_canvas or self-drawn objects, but they must be rendered): a) Outer circle (horizon 0°): Ring stroke Line 2px b) 3 concentric circles (30°/60°/90°):
- r=R*2/3 (about 55)
- r=R*1/3 (about 27)
- r=0 (center point) Use Line 1px dotted line effect for the circular line (if you cannot do a dotted line, you can also use a thin solid line) c) Cross bearing lines: N-S and E-W pass through the center of the circle, line color Line 1px d) Direction text:
- "N" placed above the circle: the center is aligned with the center x, y=2-2 (close to the outside of the circle)
- "E" Place on the right side: x=10+170+8,y=95-10
- "W" Place on the left side: x=2,y=95-10 (in the blank space on the left side of the circle) Text color, font size 18 e) Elevation angle scale text:
- Change the scale to "pointing to the 10:30 direction": mark "90°" (near the outer circle), "60°" (r=55), and "30°" (r=27) on the diagonal line from the center of the circle to the 10:30 direction.
- The text is arranged along the diagonal line, and the overall visual connection points to the 10 and a half direction Text color TextDim, font size 16 f) Marking near the center of the circle:
- label_horizon: placed slightly below the center of the circle: text "0° Horizon", color TextDim, font size 12
Satellite point drawing (dynamic): -Use a small dot object sat_dot for each satellite (recommended lv_obj + fillet = radius) -Point radius: 10px (diameter 20) -Display satellites within the point ID (two or three digits), text white or dark brown (contrast is automatically selected according to the background color, white is preferred) -The position of the point is mapped to the circle by (azimuth, elevation): r = R * (1 - elevation/90) x = Cx + r * sin(azimuth) y = Cy - r * cos(azimuth) (azimuth: 0°=N, 90°=E) -Point fill color: by constellation (GPS/GLN/GAL/BD)
- Click outer ring/small mark: press SNR status (GOOD/FAIR/WEAK/NOT_USED/IN_VIEW):
- GOOD/FAIR/WEAK: use the corresponding color to make a 2px outer ring
- NOT_USED: outer ring Warn
- IN_VIEW: outer ring Gray
- If the satellite used_in_fix=true, add a small label "USE" next to the point:
- use_tag: Rounded corners 6, background Ok, text white, font size 12
- Position: Offset the lower left corner of the pasting point (dx=-12, dy=12) to avoid blocking the numbers
Legend (in the lower right corner area of SkyPlotPanel):
- legend_sys (constellation legend) is placed on the right side of the circle chart, below:
- Small color block 10×10 + Text (GPS/GLONASS/Galileo/BeiDou)
- Position: starting from x=190, y=105, line height 15
- legend_snr (SNR legend) is placed above legend_sys and aligned to its left (upper right corner area of SkyPlotPanel):
- Text order: "SNR Good" "SNR Weak" "Not Used" "In View"
- Use small dots (diameter 10) + text
- Position: starting from x=190, arranged vertically (line height 15), the whole is above legend_sys; the distance from legend_sys is 6px; the whole is moved up 30px; small dots and text arrangement rules are the same as legend_sys (color block y+4, text x+14)
- text color TextDim, font size 12
============================================================ 5) Right StatusPanel (x=293, y=38, w=179, h=176)
Panel container:
- panel_status: rounded corners 10, background PanelBG, stroke 2px AmberDark
Title bar (height 26):
- header: x=0,y=0,w=179,h=26, background Amber, upper half of rounded corners maintained
- label: centered "SATELLITE STATUS", text color #2A1A05, font size 14 bold
Header row (height 22, y=26):
- Background: #F2D9A5
- Columns: ID / SYS / ELEV / SNR / USE
- Column width (pixels): ID=24, SYS=38, ELEV=39, SNR=38, USED=39 (ELEV=USED, SNR=SYS)
- Text centered, color TextDim, font size 12
Data list area (y=48 to y=176, height 128): -Rendered in "fixed row height" mode, row height 17px, 7 rows can be displayed (remaining scrolling/pagination is not implemented, but the structure must be reserved) -5 columns in each row to align the header
- Line bottom divider 1px Line
- SYS text color according to constellation color (GPS/GLN/GAL/BD)
- USED column: if used=true, display "YES" color Ok; otherwise "NO" color Warn
- Other column text colors Text
- When the number of satellites exceeds the number of rows that can be displayed, the list is displayed in the following priority order: USED=YES first, high SNR first, then high elevation, then PRN/SVID in ascending order
The summary area at the bottom is removed, and all space is given to the data list area
============================================================ 6) Data structure and refresh interface (must be provided)
Define data structure (example):
-
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; };
Must implement two refresh functions (for upper layer calls):
- void ui_gnss_skyplot_set_sats(const SatInfo* sats, int count); -> Update circular chart satellite points (create/reuse objects), update the first N rows of the right table
- void ui_gnss_skyplot_set_status(GnssStatus st); -> Update bottom summary text and FIX Color
============================================================ 7) Interaction (minimal)
- The Back button position is allowed to be reserved in the upper left corner (but this requirement does not have to be implemented).
- The page does not require touch interaction; only the display needs to be refreshed.
- Backspace key behavior: trigger the Back button logic of TopBar, consistent with other pages.
============================================================ 8) Deliverable requirements
- Provide a function ui_gnss_skyplot_create(lv_obj_t* parent) to return the page root object.
- All object pointers are stored in static/structural bodies, supporting repeated page entry without leakage.
- Do not use external image resources; draw everything with LVGL.
- Output code should be directly compilable (pseudocode is not accepted).
Generate complete LVGL page code according to the above requirements.