package ui import ( "image/color" "opslag.de/schobers/geom" ) type TextOverflow int const ( TextOverflowClip TextOverflow = iota TextOverflowEllipsis ) type Label struct { ControlBase Text string TextOverflow TextOverflow DropShadow color.Color desired CachedValue } func BuildLabel(text string, fn func(*Label)) *Label { var l = &Label{Text: text} if fn != nil { fn(l) } return l } func (l *Label) hashDesiredSize(ctx Context) string { return l.FontName(ctx) + l.Text } func (l *Label) desiredSize(ctx Context) interface{} { font := l.ActualFont(ctx) width := font.WidthOf(l.Text) height := font.Height() pad := l.ActualTextPadding(ctx) return geom.PtF32(pad.Left+width+pad.Right, pad.Top+height+pad.Bottom) } func (l *Label) DesiredSize(ctx Context, _ geom.PointF32) geom.PointF32 { return l.desired.GetContext(ctx, l.desiredSize, l.hashDesiredSize).(geom.PointF32) } func (l *Label) getLabelTopLeft(ctx Context) geom.PointF32 { pad := l.ActualTextPadding(ctx) bounds := pad.InsetRect(l.bounds) switch l.TextAlignment { case AlignRight: return geom.PtF32(bounds.Max.X, bounds.Min.Y) case AlignCenter: return geom.PtF32(.5*(bounds.Min.X+bounds.Max.X), bounds.Min.Y) default: return bounds.Min } } func (l *Label) Render(ctx Context) { l.RenderBackground(ctx) fontColor := l.TextColor(ctx) font := l.ActualFont(ctx) topLeft := l.getLabelTopLeft(ctx) text := l.Text availableWidth := l.bounds.Dx() if l.TextOverflow == TextOverflowEllipsis { text = fitTextEllipsis(font, text, availableWidth) } if l.DropShadow != nil { ctx.Renderer().TextAlign(font, topLeft.Add2D(1, 1), l.DropShadow, text, l.TextAlignment) } ctx.Renderer().TextAlign(font, topLeft, fontColor, text, l.TextAlignment) }