diff --git a/doc/shaper_usage.md b/doc/shaper_usage.md index 8e83bfb..ad87634 100644 --- a/doc/shaper_usage.md +++ b/doc/shaper_usage.md @@ -573,13 +573,11 @@ With `LineHeightScale = 1.2`: `visualGap ≈ 0.2 * lineHeight` (20% padding) ## 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 -// gtx.Constraints.Max.Y is in physical pixels. -// Convert to DP using gtx.Metric.PxPerDp. scale := gtx.Metric.PxPerDp bottomBarHeightPx := int(24 * scale) marginPx := int(10 * scale) @@ -587,7 +585,27 @@ drawYPx := gtx.Constraints.Max.Y - bottomBarHeightPx - marginPx 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