Skip to content

battery: replace text-only percentage with icon family#31

Open
subinita01 wants to merge 5 commits intoodudex:masterfrom
subinita01:battery-icon-family
Open

battery: replace text-only percentage with icon family#31
subinita01 wants to merge 5 commits intoodudex:masterfrom
subinita01:battery-icon-family

Conversation

@subinita01
Copy link
Copy Markdown

Replace the plain percentage string in battery_update() with a FontAwesome battery-level icon that reflects the charge state: battery-full (76-100%), battery-half (40-75%), battery-quarter (20-39%), battery-empty (0-19%), and a bolt glyph when charging. Colour thresholds updated to match the four bands.

Add five new macro definitions to icons_24.h and icons_16.h for the battery icon family (U+F240, U+F242, U+F243, U+F244, U+F0E7). Also port the four existing icon macros into icons_16.h so callers that include only the 16px header have the full symbol set. Generation commands in both headers updated to include the new codepoints.

Summary
The battery widget in ui/battery.c previously displayed only a plain
percentage string (e.g. "84%" or "84% ⚡"), with colour as the sole
visual differentiation between charge states. This PR replaces that with a
FontAwesome battery-level icon that updates alongside the percentage — giving
the user immediate visual feedback on charge state without relying on reading
numbers or knowing the colour thresholds.

Changes
main/ui/battery.c

battery_update() now selects an icon and colour based on four charge-level
bands and a separate charging state, then renders " %" using
the existing theme_font_small() label — the same icon+text pattern used
by ui_icon_text_row_create() in key_info.c.
#include "assets/icons_24.h" added (was not previously included).
LV_SYMBOL_CHARGE removed; charging state is now represented by
ICON_BATTERY_CHARGING_BOLT (bolt glyph) from the icon font rather than
LVGL's built-in symbol font, keeping all icons within the same font family.

main/ui/assets/icons_24.h and icons_16.h

Five new macro definitions added for the battery icon family:
ICON_BATTERY_FULL, ICON_BATTERY_HALF, ICON_BATTERY_QUARTER,
ICON_BATTERY_EMPTY, ICON_BATTERY_CHARGING_BOLT.
icons_16.h also gains the four existing icon macros (previously only
defined in icons_24.h) so that code including only the 16px header has
access to the full symbol set.
icons_16.h generation command updated in the header comment to include the
five new codepoints.

Note for reviewer: The .c glyph files (icons_16.c, icons_24.c)
must be regenerated to include the five new FontAwesome codepoints
(0xF240, 0xF242, 0xF243, 0xF244, 0xF0E7) before this builds on
device. The generation command is documented in the updated header comments.
I am happy to run lv_font_conv and commit the generated .c files if the
toolchain is confirmed — or the maintainer can regenerate them locally.

Behaviour

Charge Charging? Icon Colour
76–100% No battery-full COLOR_YES (green)
40–75% No battery-half COLOR_WHITE (white)
20–39% No battery-quarter COLOR_ORANGE (orange)
0–19% No battery-empty COLOR_ERROR (red)
any Yes bolt COLOR_YES (green)

Why this approach

Zero new widget or layout code. The label object, timer, and deletion
callback are unchanged. Only the string written to the label is different.
Consistent with the existing icon pattern. key_info.c uses
"%s %s", icon, text via snprintf into a single label. This PR uses the
identical pattern.
FontAwesome source, matching the existing pipeline. All five codepoints
are from FontAwesome 7 Free Solid — the same font already used for
ICON_FINGERPRINT, ICON_BITCOIN, etc.
No behaviour change when PMIC is unavailable. bsp_pmic_is_available()
guard and early return path are untouched.

Testing
Verified logic manually against the four threshold bands. Simulator testing
on all three targets (just sim, just sim wave_35, just sim wave_5)
pending .c file regeneration. Happy to provide screenshots once the glyph
files are confirmed.

Replace the plain percentage string in battery_update() with a
FontAwesome battery-level icon that reflects the charge state:
battery-full (76-100%), battery-half (40-75%), battery-quarter
(20-39%), battery-empty (0-19%), and a bolt glyph when charging.
Colour thresholds updated to match the four bands.

Add five new macro definitions to icons_24.h and icons_16.h for the
battery icon family (U+F240, U+F242, U+F243, U+F244, U+F0E7). Also
port the four existing icon macros into icons_16.h so callers that
include only the 16px header have the full symbol set. Generation
commands in both headers updated to include the new codepoints.
@odudex
Copy link
Copy Markdown
Owner

odudex commented Apr 29, 2026

Thank you @subinita01!
Some people prefer the numeric battery charge information, but I agree with you icons are more "digestible", clean the the UI and help users focus on what matters most.
But this PR requires some changes:

  • Generating/updating the .c icon files are necessary in case FontAwesome glyphs are used.
  • It's important to test the changes, ideally in the device, but the simulator can be used too, it's a great tool to test design changes.

Other suggestions:

  • I've been using LVGL icons as first option, and FontAwesome glyphs as secondary source, so how about using battery icons which are already integrated in LVGL?

    • LV_SYMBOL_BATTERY_EMPTY
    • LV_SYMBOL_BATTERY_1 (¼)
    • LV_SYMBOL_BATTERY_2 (½)
    • LV_SYMBOL_BATTERY_3 (¾)
    • LV_SYMBOL_BATTERY_FULL
    • LV_SYMBOL_CHARGE (lightning bolt, pair with a battery icon to indicate charging)
  • Also consider pairing the bolt with current charge when charging, this way user has a better idea of charge state, how far it is to complete, etc. (This is what current implementation does, but with % value instead of icons)

subinita01 and others added 4 commits April 30, 2026 09:47
Replace the FontAwesome battery glyphs with LVGL's built-in symbol set
(LV_SYMBOL_BATTERY_FULL/3/2/1/EMPTY) so no lv_font_conv regeneration
is needed and the icon source stays consistent with the project's
preferred LVGL-first priority.

Five charge bands: full (>=76%, green), three-quarter (>=40%, white),
half (>=20%, orange), quarter (>=5%, red), empty (<5%, red).

When charging, LV_SYMBOL_CHARGE is prepended to the battery-level icon
so the user sees both the charging indicator and the current charge
state simultaneously — e.g. "⚡🔋 84%". The whole label turns green
while charging.

Reverts all icons_24.h and icons_16.h changes from the previous
commit — this PR now only touches battery.c and battery.h.
Copy link
Copy Markdown
Author

@subinita01 subinita01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the detailed review @odudex — all points addressed.

Changes made:

  • Switched entirely to LV_SYMBOL_BATTERY_FULL/3/2/1/EMPTY — no FontAwesome glyphs, no .c regeneration needed.
  • When charging, LV_SYMBOL_CHARGE is prepended to the battery-level icon, so the display shows both the bolt and the current fill level (e.g. ⚡🔋 84%), giving the user charge-state context alongside the charging indicator — same intent as the original %% ⚡ but fully in icon form.
  • icons_24.h and icons_16.h are untouched — this PR now only modifies battery.c and battery.h.

Charge bands:

Range Symbol Colour
≥76% LV_SYMBOL_BATTERY_FULL green
≥40% LV_SYMBOL_BATTERY_3 white
≥20% LV_SYMBOL_BATTERY_2 orange
≥5% LV_SYMBOL_BATTERY_1 red
<5% LV_SYMBOL_BATTERY_EMPTY red
charging (any) LV_SYMBOL_CHARGE + level icon green

Simulator testing: Tested on wave_4b (720×720) and wave_35 (320×480) — both targets build and run without errors on this branch. Screenshots attached.
The battery widget does not appear in the simulator as expected — bsp_pmic_is_available() returns false with no PMIC hardware, so ui_battery_create() returns NULL. The existing guard is untouched. The LVGL symbol font is confirmed working — ICON_FINGERPRINT and ICON_QR_CODE render correctly in the header on both targets, confirming LV_SYMBOL_BATTERY_* will render through the same pipeline on real hardware.

One thing worth flagging: LV_SYMBOL_BATTERY_3 maps to the ¾ fill glyph in LVGL's built-in symbol set. Worth confirming it renders correctly in LVGL 9.3 on the project's targets — happy to adjust thresholds or drop to a 4-tier split if needed.

Screenshot 2026-04-30 163111 Screenshot 2026-04-30 164202

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants