- 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>
71 lines
1.5 KiB
Go
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()
|
|
}
|