Document BottomBar X positioning and widget constraint modification

This commit is contained in:
Greg Pomerantz 2026-05-09 18:01:57 -04:00
parent 4cf8641bbd
commit f563a515e6

View File

@ -573,13 +573,11 @@ With `LineHeightScale = 1.2`: `visualGap ≈ 0.2 * lineHeight` (20% padding)
## 9.5 Drawing Elements Inside the Visible Window ## 9.5 Drawing Elements Inside the Visible Window
When drawing elements like the BottomBar, the region Y computed from `screenHeight` may be outside the visible window area. This happens because `app.ConfigEvent` reports the **physical pixel size** of the window, which can be much larger than the requested DP size (e.g., macOS reports 1560×3376 pixels when we requested 390×844 DP). When drawing elements like the BottomBar, the region coordinates computed from `screenHeight` may be outside the visible window area. This happens because `app.ConfigEvent` reports the **physical pixel size** of the window, which can be much larger than the requested DP size (e.g., macOS reports 1560×3376 pixels when we requested 390×844 DP).
**The fix**: Use `gtx.Constraints.Max.Y` (in physical pixels) to clamp the draw position to the visible area: **Y positioning**: Use `gtx.Constraints.Max.Y` (in physical pixels) to clamp the draw position to the visible area:
```go ```go
// gtx.Constraints.Max.Y is in physical pixels.
// Convert to DP using gtx.Metric.PxPerDp.
scale := gtx.Metric.PxPerDp scale := gtx.Metric.PxPerDp
bottomBarHeightPx := int(24 * scale) bottomBarHeightPx := int(24 * scale)
marginPx := int(10 * scale) marginPx := int(10 * scale)
@ -587,7 +585,27 @@ drawYPx := gtx.Constraints.Max.Y - bottomBarHeightPx - marginPx
drawY := unit.Dp(float64(drawYPx) / float64(scale)) drawY := unit.Dp(float64(drawYPx) / float64(scale))
``` ```
**Key insight**: `gtx.Constraints.Max.X/Y` are in **physical pixels**, not DP. Always convert using `gtx.Metric.PxPerDp` when mixing pixels and DP. **X positioning**: `gtx.Constraints` are modified by previous widgets (e.g., `Min.X` changes after StatusBar draws). Use the element's own region for X positioning, clamped to `gtx.Constraints.Max.X`:
```go
regXPx := int(float32(reg.X) * scale)
windowW := gtx.Constraints.Max.X
rightXPx := regXPx + int(float32(reg.W)*scale)
if rightXPx > windowW {
rightXPx = windowW
}
barW := rightXPx - regXPx
// Now use regXPx and barW for all X positions
cursorXPx := regXPx + int(8*scale)
byteXPx := regXPx + barW/2 - int(60*scale)
wordWrapXPx := regXPx + barW - int(80*scale)
```
**Key insights**:
- `gtx.Constraints.Max.Y` is in **physical pixels** — use for Y positioning
- `gtx.Constraints.Min.X` is **modified by previous widgets** — don't use for X positioning
- Always convert DP to pixels using `gtx.Metric.PxPerDp` when mixing with pixel values
- Always clamp right edge to `gtx.Constraints.Max.X`
## 10. Summary ## 10. Summary