80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package gel
|
|
|
|
import (
|
|
"image"
|
|
|
|
"gioui.org/font"
|
|
l "gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
"gioui.org/text"
|
|
"gioui.org/unit"
|
|
|
|
"golang.org/x/image/math/fixed"
|
|
)
|
|
|
|
// Text is a widget for laying out and drawing text.
|
|
type Text struct {
|
|
*Window
|
|
// alignment specify the text alignment.
|
|
alignment text.Alignment
|
|
// maxLines limits the number of lines. Zero means no limit.
|
|
maxLines int
|
|
}
|
|
|
|
func (w *Window) Text() *Text {
|
|
return &Text{Window: w}
|
|
}
|
|
|
|
// Alignment sets the alignment for the text
|
|
func (t *Text) Alignment(alignment text.Alignment) *Text {
|
|
t.alignment = alignment
|
|
return t
|
|
}
|
|
|
|
// MaxLines sets the alignment for the text
|
|
func (t *Text) MaxLines(maxLines int) *Text {
|
|
t.maxLines = maxLines
|
|
return t
|
|
}
|
|
|
|
func (t *Text) Fn(gtx l.Context, s *text.Shaper, fnt font.Font, size unit.Sp, txt string) l.Dimensions {
|
|
cs := gtx.Constraints
|
|
textSize := fixed.I(gtx.Sp(size))
|
|
|
|
s.LayoutString(text.Parameters{
|
|
Font: fnt,
|
|
PxPerEm: textSize,
|
|
MaxLines: t.maxLines,
|
|
Alignment: t.alignment,
|
|
MaxWidth: cs.Max.X,
|
|
MinWidth: cs.Min.X,
|
|
Locale: gtx.Locale,
|
|
}, txt)
|
|
|
|
m := op.Record(gtx.Ops)
|
|
viewport := image.Rectangle{Max: cs.Max}
|
|
it := GlyphIterator{
|
|
Viewport: viewport,
|
|
MaxLines: t.maxLines,
|
|
}
|
|
var glyphs [32]text.Glyph
|
|
line := glyphs[:0]
|
|
for g, ok := s.NextGlyph(); ok; g, ok = s.NextGlyph() {
|
|
var ok bool
|
|
if line, ok = it.PaintGlyph(gtx, s, g, line); !ok {
|
|
break
|
|
}
|
|
}
|
|
call := m.Stop()
|
|
viewport.Min = viewport.Min.Add(it.Padding.Min)
|
|
viewport.Max = viewport.Max.Add(it.Padding.Max)
|
|
clipStack := clip.Rect(viewport).Push(gtx.Ops)
|
|
call.Add(gtx.Ops)
|
|
dims := l.Dimensions{Size: it.Bounds.Size()}
|
|
dims.Size = cs.Constrain(dims.Size)
|
|
dims.Baseline = dims.Size.Y - it.Baseline
|
|
clipStack.Pop()
|
|
return dims
|
|
}
|