Pad/internal/editor/state.go
Greg Pomerantz 8739bae517 refactor: unified Element interface with Draw method and Container type
- Add Draw(gtx, r *Renderer) to Element interface
- Add Container type that implements Element and holds []Element children
- Leaf types (Label, Icon, Button) implement Draw themselves
- Single recursive drawElement function in Renderer — no switch/case
- Remove StatusBar/BottomBar — replaced by Container
- Remove shaper.go — no longer needed with Gio material labels
- Simplify main.go — scale via ScaleProvider interface
- 5 files changed, shaper.go deleted
2026-05-18 11:25:43 -04:00

81 lines
2.2 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
scale float32 // pixels per DP, default 1.0
Elems []ui.Element
}
// NewState creates a new State with initial editor layout.
func NewState(screenWidth, screenHeight ui.Dp) *State {
return &State{
ScreenWidth: screenWidth,
ScreenHeight: screenHeight,
scale: 1.0,
Elems: EditorLayout(screenWidth, screenHeight),
}
}
// SetScale updates the scale factor and recomputes layout.
func (s *State) SetScale(scale float32) {
s.scale = scale
s.Elems = EditorLayout(s.ScreenWidth, s.ScreenHeight)
}
// Scale returns the current scale factor (pixels per DP).
func (s *State) Scale() float32 {
return s.scale
}
// EditorLayout computes the element tree for the editor page.
// It takes screen dimensions in Dp and returns []Element.
func EditorLayout(screenWidth, screenHeight ui.Dp) []ui.Element {
margin := ui.Dp(10)
// --- Top container: status bar ---
statusBarHeight := ui.Dp(52)
statusBarRegion := ui.Region{
X: margin, Y: margin,
W: screenWidth - margin*2,
H: statusBarHeight,
}
statusBar := ui.NewContainer(
statusBarRegion,
ui.Color{R: 230, G: 230, B: 230, A: 255},
[]ui.Element{
ui.NewIcon("cut", ui.Region{X: ui.Dp(8), Y: ui.Dp(2), W: ui.Dp(16), H: ui.Dp(16)}, ui.Dp(16)),
ui.NewLabel("Ln 47, Col 12", 12, ui.Region{X: ui.Dp(32), Y: ui.Dp(2)}),
ui.NewLabel("Ready", 12, ui.Region{X: ui.Dp(8), Y: ui.Dp(28)}),
},
)
// --- Bottom container: bottom bar ---
bottomBarHeight := ui.Dp(24)
bottomBarY := screenHeight - margin - bottomBarHeight
bottomBarRegion := ui.Region{
X: margin, Y: bottomBarY,
W: screenWidth - margin*2,
H: bottomBarHeight,
}
bottomBar := ui.NewContainer(
bottomBarRegion,
ui.Color{R: 230, G: 230, B: 230, A: 255},
[]ui.Element{
ui.NewLabel("Ln 47, Col 12", 12, ui.Region{X: ui.Dp(8), Y: ui.Dp(2)}),
ui.NewLabel("1024 / 50000", 12, ui.Region{X: ui.Dp(150), Y: ui.Dp(2)}),
ui.NewLabel("Wrap: On", 12, ui.Region{X: screenWidth - margin - ui.Dp(60), Y: ui.Dp(2)}),
},
)
return []ui.Element{statusBar, bottomBar}
}