Pad/internal/ui/render.go
Greg Pomerantz 6720359360 Add Gioui scaffolding with Label and ListView rendering
- Element interface with Region() and Visible() methods
- Label and ListView element types with constructors
- Renderer that clips and draws elements in slice order
- Main app loop with Gioui window and frame events

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-07 17:45:56 -04:00

71 lines
1.5 KiB
Go

package ui
import (
"image"
"gioui.org/layout"
"gioui.org/op/clip"
"gioui.org/text"
"gioui.org/widget/material"
)
// Renderer consumes a slice of elements and draws them.
type Renderer struct {
theme Theme
shp *text.Shaper
}
// New creates a new Renderer.
func New(th Theme, shp *text.Shaper) *Renderer {
return &Renderer{theme: th, shp: shp}
}
// Draw iterates elements and draws each in slice order (back-to-front).
func (r *Renderer) Draw(gtx layout.Context, elems []Element) {
for _, e := range elems {
if !e.Visible() {
continue
}
switch v := e.(type) {
case Label:
r.drawLabel(gtx, v)
case ListView:
r.drawListView(gtx, v)
default:
// unknown element type, skip
}
}
}
func (r *Renderer) drawLabel(gtx layout.Context, l Label) {
reg := l.Region()
c := clip.Rect{
Min: image.Point{X: int(reg.X), Y: int(reg.Y)},
Max: image.Point{X: int(reg.X + reg.W), Y: int(reg.Y + reg.H)},
}.Push(gtx.Ops)
th := material.NewTheme()
th.Shaper = r.shp
size := l.FontSize
if size == 0 {
size = r.theme.FontSize
}
material.Label(th, size, l.Text).Layout(gtx)
c.Pop()
}
func (r *Renderer) drawListView(gtx layout.Context, lv ListView) {
reg := lv.Region()
c := clip.Rect{
Min: image.Point{X: int(reg.X), Y: int(reg.Y)},
Max: image.Point{X: int(reg.X + reg.W), Y: int(reg.Y + reg.H)},
}.Push(gtx.Ops)
th := material.NewTheme()
th.Shaper = r.shp
for _, item := range lv.Items {
material.Label(th, r.theme.FontSize, item.Text).Layout(gtx)
}
c.Pop()
}