diff --git a/cmd/pad/main.go b/cmd/pad/main.go index 4bfdf96..2aaf14b 100644 --- a/cmd/pad/main.go +++ b/cmd/pad/main.go @@ -34,13 +34,15 @@ func run(w *app.Window) error { shaper := text.NewShaper(text.WithCollection(gofont.Collection())) renderer := ui.New(ui.Theme{FontSize: 14}, shaper) - // Track window dimensions in pixels (from ConfigEvent) and DP (for logic layer) + // Initial DP size from app.Size() — used before we know the scale factor + initialDPW := ui.Dp(390) + initialDPH := ui.Dp(844) + + // Track pixel dimensions from ConfigEvent (for resize handling) var pixelW, pixelH int - var dpW, dpH ui.Dp - var scale float32 = 1.0 // updated on first FrameEvent // Create logic instance with initial DP size - logic := editor.NewLogic(dpW, dpH) + logic := editor.NewLogic(initialDPW, initialDPH) // Shared state protected by mutex var mu sync.Mutex @@ -58,25 +60,21 @@ func run(w *app.Window) error { case app.DestroyEvent: return e.Err case app.ConfigEvent: - // Store pixel dimensions from ConfigEvent + // Store pixel dimensions for later conversion pixelW = e.Config.Size.X pixelH = e.Config.Size.Y - // Convert to DP using current scale (default 1.0 until first FrameEvent) - dpW = ui.ToDp(ui.Px(pixelW), scale) - dpH = ui.ToDp(ui.Px(pixelH), scale) - // Send config event to logic goroutine (in DP) + // Use initial DP size until we get the scale from FrameEvent logic.ConfigChan() <- editor.ConfigEvent{ - Width: dpW, - Height: dpH, + Width: initialDPW, + Height: initialDPH, } case app.FrameEvent: - // Update scale from the frame context gtx := app.NewContext(&ops, e) - scale = gtx.Metric.PxPerDp + scale := gtx.Metric.PxPerDp - // Reconvert pixel dimensions to DP with actual scale - dpW = ui.ToDp(ui.Px(pixelW), scale) - dpH = ui.ToDp(ui.Px(pixelH), scale) + // Convert pixel dimensions to DP using actual scale + dpW := ui.ToDp(ui.Px(pixelW), scale) + dpH := ui.ToDp(ui.Px(pixelH), scale) // Send updated config to logic goroutine logic.ConfigChan() <- editor.ConfigEvent{ diff --git a/internal/ui/render.go b/internal/ui/render.go index c4e2c8f..803220d 100644 --- a/internal/ui/render.go +++ b/internal/ui/render.go @@ -1,6 +1,7 @@ package ui import ( + "fmt" "image" "image/color" @@ -110,19 +111,19 @@ func (r *Renderer) drawStatusBar(gtx layout.Context, sb StatusBar, _ WindowConst th := material.NewTheme() th.Shaper = r.shp + fmt.Printf("[DEBUG drawStatusBar] reg=(%d, %d, %d, %d)\n", reg.X, reg.Y, reg.W, reg.H) + // Draw light gray background bgColor := color.NRGBA{R: 230, G: 230, B: 230, A: 255} - m := op.Record(gtx.Ops) clip.Rect{ Min: image.Point{X: int(r.toPx(reg.X)), Y: int(r.toPx(reg.Y))}, Max: image.Point{X: int(r.toPx(reg.X + reg.W)), Y: int(r.toPx(reg.Y + reg.H))}, - }.Op().Push(gtx.Ops) + }.Push(gtx.Ops) paint.ColorOp{Color: bgColor}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops) - call := m.Stop() - call.Add(gtx.Ops) + clip.Pop() - // Clip to status bar region (convert Dp to pixels) + // Clip to status bar region for text (convert Dp to pixels) c := clip.Rect{ Min: image.Point{X: int(r.toPx(reg.X)), Y: int(r.toPx(reg.Y))}, Max: image.Point{X: int(r.toPx(reg.X + reg.W)), Y: int(r.toPx(reg.Y + reg.H))}, @@ -185,12 +186,23 @@ func (r *Renderer) drawStatusBar(gtx layout.Context, sb StatusBar, _ WindowConst func (r *Renderer) drawBottomBar(gtx layout.Context, bb BottomBar, constraints WindowConstraints) { reg := bb.Region() + fmt.Printf("[DEBUG drawBottomBar] reg=(%d, %d, %d, %d)\n", reg.X, reg.Y, reg.W, reg.H) + fmt.Printf("[DEBUG drawBottomBar] constraints=(%d, %d, %d, %d)\n", + constraints.Min.X, constraints.Min.Y, + constraints.Max.X, constraints.Max.Y) + fmt.Printf("[DEBUG drawBottomBar] scale=%f\n", r.scale) + // Draw light gray background bgColor := color.NRGBA{R: 230, G: 230, B: 230, A: 255} m := op.Record(gtx.Ops) + bgMinX := int(r.toPx(reg.X)) + bgMinY := int(r.toPx(reg.Y)) + bgMaxX := int(r.toPx(reg.X + reg.W)) + bgMaxY := int(r.toPx(reg.Y + reg.H)) + fmt.Printf("[DEBUG drawBottomBar] bg_rect=(%d, %d, %d, %d)\n", bgMinX, bgMinY, bgMaxX, bgMaxY) clip.Rect{ - Min: image.Point{X: int(r.toPx(reg.X)), Y: int(r.toPx(reg.Y))}, - Max: image.Point{X: int(r.toPx(reg.X + reg.W)), Y: int(r.toPx(reg.Y + reg.H))}, + Min: image.Point{X: bgMinX, Y: bgMinY}, + Max: image.Point{X: bgMaxX, Y: bgMaxY}, }.Op().Push(gtx.Ops) paint.ColorOp{Color: bgColor}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops) @@ -218,6 +230,8 @@ func (r *Renderer) drawBottomBar(gtx layout.Context, bb BottomBar, constraints W bottomBarHeightPx := r.toPx(Dp(24)) marginPx := r.toPx(Dp(10)) drawYPx := Px(windowH) - bottomBarHeightPx - marginPx + fmt.Printf("[DEBUG drawBottomBar] drawY_px=%d (windowH=%d - barH=%d - margin=%d)\n", + drawYPx, windowH, bottomBarHeightPx, marginPx) // Convert draw position back to Dp for text rendering drawY := r.toDp(drawYPx) @@ -225,16 +239,19 @@ func (r *Renderer) drawBottomBar(gtx layout.Context, bb BottomBar, constraints W // Left: Cursor position cursorXPx := regXPx + r.toPx(Dp(8)) cursorXDp := r.toDp(cursorXPx) + fmt.Printf("[DEBUG drawBottomBar] cursor=(%d, %d) text=%q\n", cursorXPx, drawYPx, bb.CursorPos) r.drawText(gtx, r.shp, bb.CursorPos, r.theme.FontSize, cursorXDp, drawY, color.NRGBA{R: 0, G: 0, B: 0, A: 255}) // Center: Byte position byteXPx := regXPx + barW/2 - r.toPx(Dp(60)) byteXDp := r.toDp(byteXPx) + fmt.Printf("[DEBUG drawBottomBar] byte=(%d, %d) text=%q\n", byteXPx, drawYPx, bb.BytePos) r.drawText(gtx, r.shp, bb.BytePos, r.theme.FontSize, byteXDp, drawY, color.NRGBA{R: 0, G: 0, B: 0, A: 255}) // Right: Word wrap button wordWrapXPx := regXPx + barW - r.toPx(Dp(80)) wordWrapXDp := r.toDp(wordWrapXPx) + fmt.Printf("[DEBUG drawBottomBar] wordwrap=(%d, %d) text=%q\n", wordWrapXPx, drawYPx, "W:"+boolToString(bb.WordWrap)) r.drawText(gtx, r.shp, "W:"+boolToString(bb.WordWrap), r.theme.FontSize, wordWrapXDp, drawY, color.NRGBA{R: 0, G: 0, B: 0, A: 255}) }