Skip to content

Commit 51fdbf4

Browse files
committed
feat(ui): put the homescreen and more info on one grid (v0.7.0-beta.76)
Both screens grew through a long run of single fixes, and each one moved one number without pulling its neighbours along. What was left was not a grid but a pile of individual decisions: the outer margin was 6 px in the header and 8 px in zone 3, the three values of row A sat on baselines 80, 81 and 82, and the material reserve ran 20 px into the filament column because an earlier fix pulled filament from 260 to 232 and left the width at 160. Nothing was broken, which is why it survived so long - it was only never quiet. What everything answers to now: 8 px outer margin left and right, one baseline per row whatever font sizes sit in it, 18 px from a caption's baseline to its value's baseline, captions font 12 in 4a6fa0, the swatch on the middle of its text line, and no reserved width reaching into the next column. Zone 3 splits the width in half at 8 / 244; zones 4 and 5 have to keep a slot free on the right for TARE and the burger and sit on 8 / 218 with the divider at 210. That is the one break in the grid, and it is the content asking for it. Two numbers had to be measured rather than picked. A label's baseline is y + line_height - base_line, so a constant y offset means a different optical distance for every font size - which is how more info came to have 17, 22, 22, 15 and 18 px for the same caption-and-value construction while the source read as a tidy 18, 13 and 16. And 2a4060, which the design guide asks for on row A captions, is 1.7:1 on 0a1020: a shape colour for rules and inactive bars, not a text colour. The homescreen never followed that line and was right not to. The header chips needed more than coordinates. Their widths move at runtime - "NFC" becomes "NFC!" on an error, the badge follows the backend - so fixed offsets could only ever be even for one of those states. layoutHeaderChips() packs them from the right with one gap, behind an explicit lv_obj_update_layout(), because align_to reads a width that a content-sized label only knows once the layout has run. The status bar address hangs off the scan counter for the same reason: that counter gains a digit and a fixed offset would eventually run into it. Its own width is down to 292 px, which still clears the longest string that lands there by some 45 px. The bar width was a bare 190 in three places, which is precisely why the bar and its background would have drifted apart the moment one of them was widened. It is MAIN_BAR_W now. vdiv2 was a 0 x 0 object rather than a deleted one, so zone 4 had a divider on its left and nothing on its right. It draws again.
1 parent e17c61b commit 51fdbf4

9 files changed

Lines changed: 262 additions & 164 deletions

File tree

src/app/app_state.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ lv_obj_t *lbl_hdr_scl = nullptr;
186186
lv_obj_t *lbl_hdr_scans;
187187
lv_obj_t *lbl_hdr_ip = nullptr;
188188
lv_obj_t *lbl_hdr_sm = nullptr;
189+
lv_obj_t *lbl_hdr_sd = nullptr;
189190
lv_obj_t *lbl_sm_cap = nullptr;
190191
lv_obj_t *lbl_bag_sm_diff = nullptr;
191192

src/app/app_state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ extern lv_obj_t *lbl_hdr_scl;
230230
extern lv_obj_t *lbl_hdr_scans;
231231
extern lv_obj_t *lbl_hdr_ip; // status bar address, left of the scan counter
232232
extern lv_obj_t *lbl_hdr_sm;
233+
extern lv_obj_t *lbl_hdr_sd; // header SD indicator, leftmost chip
233234
extern lv_obj_t *lbl_sm_cap; // "Spoolman:" / "FilaMan:" above the database weight
234235
extern lv_obj_t *lbl_bag_sm_diff;
235236

src/app_config.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#define FW_VERSION "v0.7.0-beta.75"
3+
#define FW_VERSION "v0.7.0-beta.76"
44
#define DONATION_URL "ko-fi.com/formfollowsfunction"
55

66
// Backlight PWM duty on GPIO45, 8 bit, straight through to LovyanGFX. Not a
@@ -17,6 +17,12 @@
1717
#define SLEEP_TIMEOUT_DEFAULT 1200000
1818
#define OFF_TIMEOUT_DEFAULT 0 // 0 = stage skipped
1919

20+
// Main screen zone 4: the fill of the remaining-filament bar is written from
21+
// two places in spoolman_lookup.cpp and created in main_screen.cpp. It used to
22+
// be a bare 190 in all three, which is how the bar and its background came to
23+
// disagree the moment one of them was widened.
24+
#define MAIN_BAR_W 194
25+
2026
#define CAL_FACTOR_DEFAULT 1.0f
2127
#define SCALE_FILTER_SIZE 8
2228

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// ============================================================
22
// SpoolmanScale – Bambu NFC Tag Reader & Decoder
33
// Board: WT32-SC01 Plus (ESP32-S3)
4-
// Version: v0.7.0-beta.75
4+
// Version: v0.7.0-beta.76
55
//
66
// Reads Bambu Lab MIFARE Classic tags, derives keys via KDF
77
// (HKDF/SHA256, master key from Bambu-Research-Group/RFID-Tag-Guide),

src/ui/header_status.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,36 @@ static lv_color_t wifiColor() {
2020
return lv_color_hex(0xe06020);
2121
}
2222

23+
// Right to left, one gap between neighbours. Fixed offsets were what made the
24+
// spacing uneven: they put the chips on a 32 px pitch while the labels differ
25+
// in width, so the gaps came out 5, 9 and 7 px. Widths also move at runtime -
26+
// "NFC" becomes "NFC!" on an error and the badge follows the backend - which
27+
// is why this runs after every text change rather than once at build time.
28+
#define HDR_CHIP_MARGIN 8
29+
#define HDR_CHIP_GAP 10
30+
31+
void layoutHeaderChips() {
32+
if (!lbl_hdr_sm) return;
33+
// A label sized to its content only knows its new width after a layout pass,
34+
// and lv_obj_align_to() reads that width. Without this the chips would be
35+
// placed from the previous text.
36+
lv_obj_update_layout(lv_obj_get_parent(lbl_hdr_sm));
37+
38+
lv_obj_align(lbl_hdr_sm, LV_ALIGN_RIGHT_MID, -HDR_CHIP_MARGIN, 0);
39+
lv_obj_t *prev = lbl_hdr_sm;
40+
lv_obj_t *chain[] = { lbl_hdr_scl, lbl_hdr_nfc, lbl_hdr_wifi, lbl_hdr_sd };
41+
for (unsigned i = 0; i < sizeof(chain) / sizeof(chain[0]); i++) {
42+
if (!chain[i]) continue;
43+
lv_obj_align_to(chain[i], prev, LV_ALIGN_OUT_LEFT_MID, -HDR_CHIP_GAP, 0);
44+
prev = chain[i];
45+
}
46+
47+
// The address follows the scan counter for the same reason: that counter
48+
// grows a digit at a time and a fixed offset would eventually collide.
49+
if (lbl_hdr_ip && lbl_hdr_scans)
50+
lv_obj_align_to(lbl_hdr_ip, lbl_hdr_scans, LV_ALIGN_OUT_LEFT_MID, -HDR_CHIP_GAP, 0);
51+
}
52+
2353
void updateHeaderStatus() {
2454
if (!lbl_hdr_wifi) return;
2555

@@ -97,4 +127,8 @@ void updateHeaderStatus() {
97127
lv_obj_add_flag(lbl_hdr_ip, LV_OBJ_FLAG_HIDDEN);
98128
}
99129
}
130+
131+
// Last: every text above is final by now, so the widths the packing reads
132+
// are the ones that will actually be drawn.
133+
layoutHeaderChips();
100134
}

src/ui/header_status.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
#pragma once
22

33
void updateHeaderStatus();
4+
5+
// Packs the header chips right to left with one gap each. Call after any
6+
// change to their texts - updateHeaderStatus() does it itself.
7+
void layoutHeaderChips();

0 commit comments

Comments
 (0)