|
25 | 25 | ' extending above the metadata rows. Person photos are exempt because their info rows |
26 | 26 | ' are short and don't reach the right edge where the photo sits. |
27 | 27 | const LOGO_MAX_DISPLAY_HEIGHT = 336 |
| 28 | +' First-frame estimate for the button row's total rendered height. Used by anchorDateLabel() |
| 29 | +' before boundingRect() has settled (it reports height=0 during initial render). Observed to |
| 30 | +' land around 130 px for the typical 2-line-label icon button. A later renderTracking callback |
| 31 | +' replaces this with the real measured height once layout completes. |
| 32 | +const ESTIMATED_BUTTON_ROW_HEIGHT_PX = 130 |
28 | 33 |
|
29 | 34 | sub init() |
30 | 35 | m.log = new log.Logger("ItemDetails") |
|
2210 | 2215 | dateAdded.toLocalTime() |
2211 | 2216 | m.dateCreatedLabel.text = translate(translationKeys.LabelAdded) + " " + dateAdded.AsDateString("short-month-no-weekday") + " " + formatTime(dateAdded) |
2212 | 2217 |
|
2213 | | - ' Set X position only — Y is deferred to anchorDateLabel() which runs after the |
2214 | | - ' button group layout settles (via renderTracking observer). |
2215 | | - ' Preserve the existing Y so that on refresh the label keeps its correct position |
2216 | | - ' from the previous positioning cycle rather than resetting to 0 (top of screen). |
| 2218 | + ' Set X here; Y is computed by anchorDateLabel() which handles both the initial |
| 2219 | + ' placement (using the button group's XML translation + a safe height estimate) and |
| 2220 | + ' later refinements when the button group's actual rendered height is known. Calling |
| 2221 | + ' it here guarantees the label is correctly positioned on the very first render — |
| 2222 | + ' no flash at the top of the screen. |
2217 | 2223 | m.dateCreatedLabel.translation = [1920 - 96 - 450, m.dateCreatedLabel.translation[1]] |
2218 | 2224 | m.dateCreatedLabel.visible = true |
| 2225 | + anchorDateLabel() |
2219 | 2226 | end sub |
2220 | 2227 |
|
2221 | | -' anchorDateLabel: Derive the date label's Y position from the button group's rendered rect. |
| 2228 | +' anchorDateLabel: Derive the date label's Y position from the button group's position. |
2222 | 2229 | ' Returns dateLabelY so callers (e.g. logo positioning) can use it without duplicating the math. |
2223 | | -' Safe to call multiple times — idempotent. |
2224 | | -' @return {float} dateLabelY — the Y coordinate used for the date label |
2225 | | -function anchorDateLabel() as float |
| 2230 | +' Safe to call multiple times — idempotent, and safe to call BEFORE the button group has |
| 2231 | +' finished laying out: falls back to the group's fixed translation + ESTIMATED_BUTTON_ROW_HEIGHT_PX |
| 2232 | +' so the label never lands off-screen. A later renderTracking callback refines the position |
| 2233 | +' once the real rendered height is known. |
| 2234 | +' @return {integer} dateLabelY — the Y coordinate used for the date label |
| 2235 | +function anchorDateLabel() as integer |
| 2236 | + buttonY = m.buttonGrp.translation[1] |
| 2237 | + buttonHeight = ESTIMATED_BUTTON_ROW_HEIGHT_PX |
| 2238 | + |
| 2239 | + ' Refine with the measured height once layout has settled. Ignore the degenerate 0-size |
| 2240 | + ' bounding rect reported during the initial render — that's what was pushing the label |
| 2241 | + ' to y=-30 on the Series detail screen. |
2226 | 2242 | buttonRect = m.buttonGrp.boundingRect() |
2227 | | - buttonBottom = buttonRect.y + buttonRect.height |
2228 | | - dateLabelY = buttonBottom - 30 |
| 2243 | + if buttonRect.height > 0 |
| 2244 | + buttonHeight = buttonRect.height |
| 2245 | + end if |
| 2246 | + |
| 2247 | + dateLabelY = buttonY + buttonHeight - 30 |
2229 | 2248 |
|
2230 | 2249 | if isValid(m.dateCreatedLabel) and m.dateCreatedLabel.visible |
2231 | 2250 | m.dateCreatedLabel.translation = [m.dateCreatedLabel.translation[0], dateLabelY] |
|
0 commit comments