Pad/internal/editor/state.go
Greg Pomerantz b8c6878f46 Introduce distinct Dp/Px types to prevent coordinate mixing at compile time
- Add ui.Dp and ui.Px as distinct named types
- Logic layer works exclusively in Dp (positions, sizes, regions)
- Renderer converts Dp→Px at Gio interop boundaries
- Capture gtx.Constraints once at start of Draw() for consistent positioning
- main.go converts app.ConfigEvent pixels to Dp before passing to logic layer
- Update documentation with new coordinate system architecture
2026-05-09 18:40:47 -04:00

73 lines
1.9 KiB
Go

package editor
import (
"pad/internal/ui"
)
// State holds all application state owned by the logic goroutine.
// All dimensions are in device-independent pixels (Dp).
type State struct {
ScreenWidth ui.Dp
ScreenHeight ui.Dp
Elems []ui.Element
}
// NewState creates a new State with initial editor layout.
// screenWidth and screenHeight are in device-independent pixels (Dp).
func NewState(screenWidth, screenHeight ui.Dp) *State {
return &State{
ScreenWidth: screenWidth,
ScreenHeight: screenHeight,
Elems: EditorLayout(screenWidth, screenHeight),
}
}
// EditorLayout computes regions for the editor page.
// It takes screen dimensions in Dp and returns []Element with regions in Dp.
// This function works exclusively in Dp — no pixel conversions.
func EditorLayout(screenWidth, screenHeight ui.Dp) []ui.Element {
// Margin to avoid clipping on macOS round corners
margin := ui.Dp(10)
// Compute StatusBar region
statusBarHeight := ui.Dp(48)
statusBarRegion := ui.Region{
X: margin,
Y: margin,
W: screenWidth - margin*2,
H: statusBarHeight,
}
// Compute BottomBar region (fixed height, at bottom of screen)
bottomBarHeight := ui.Dp(24)
bottomBarY := screenHeight - margin - bottomBarHeight
bottomBarRegion := ui.Region{
X: margin,
Y: bottomBarY,
W: screenWidth - margin*2,
H: bottomBarHeight,
}
// Create StatusBar with mocked filename
statusBar := ui.NewStatusBar(
statusBarRegion,
"very_long_filename_that_does_not_fit_on_a_single_line_and_it_just_keeps_on_going_and_going_and_going_and_going_and_going.txt",
false, // FilenameExp
true, // CutCopy
false, // Copy
true, // Paste
false, // ConflictIcon
true, // Search
)
// Create BottomBar with mocked data
bottomBar := ui.NewBottomBar(
bottomBarRegion,
"Ln 47, Col 12",
"1024 / 50000",
true, // WordWrap
)
return []ui.Element{statusBar, bottomBar}
}