Files
gio/widget/material/label.go
T
Chris Waldon e768fe347a widget/material: export LabelStyle.Shaper and document fields
We panic when someone constructs a literal LabelStyle because they cannot possibly
populate the shaper field. The resulting error is cryptic, and unusual within Gio
because most style types are safe to construct literally. This commit enables
creating literal LabelStyles by exporting the Shaper field, and also documents
the purposes of all of the fields.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2023-04-01 07:50:47 -06:00

138 lines
3.8 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
package material
import (
"image/color"
"gioui.org/internal/f32color"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/paint"
"gioui.org/text"
"gioui.org/unit"
"gioui.org/widget"
)
// LabelStyle configures the presentation of text. If the State field is set, the
// label will be laid out as interactive (able to be selected and copied). Otherwise,
// the label will be non-interactive.
type LabelStyle struct {
// Face defines the text style.
Font text.Font
// Color is the text color.
Color color.NRGBA
// SelectionColor is the color of the background for selected text.
SelectionColor color.NRGBA
// Alignment specify the text alignment.
Alignment text.Alignment
// MaxLines limits the number of lines. Zero means no limit.
MaxLines int
// Truncator is the text that will be shown at the end of the final
// line if MaxLines is exceeded. Defaults to "…" if empty.
Truncator string
// Text is the content displayed by the label.
Text string
// TextSize determines the size of the text glyphs.
TextSize unit.Sp
// Shaper is the text shaper used to display this labe. This field is automatically
// set using by all constructor functions. If constructing a LabelStyle literal, you
// must provide a Shaper or displaying text will panic.
Shaper *text.Shaper
// State provides text selection state for the label. If not set, the label cannot
// be selected or copied interactively.
State *widget.Selectable
}
func H1(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize*96.0/16.0, txt)
label.Font.Weight = text.Light
return label
}
func H2(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize*60.0/16.0, txt)
label.Font.Weight = text.Light
return label
}
func H3(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*48.0/16.0, txt)
}
func H4(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*34.0/16.0, txt)
}
func H5(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*24.0/16.0, txt)
}
func H6(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize*20.0/16.0, txt)
label.Font.Weight = text.Medium
return label
}
func Subtitle1(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*16.0/16.0, txt)
}
func Subtitle2(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize*14.0/16.0, txt)
label.Font.Weight = text.Medium
return label
}
func Body1(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize, txt)
}
func Body2(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*14.0/16.0, txt)
}
func Caption(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*12.0/16.0, txt)
}
func Overline(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize*10.0/16.0, txt)
}
func Label(th *Theme, size unit.Sp, txt string) LabelStyle {
return LabelStyle{
Text: txt,
Color: th.Palette.Fg,
SelectionColor: f32color.MulAlpha(th.Palette.ContrastBg, 0x60),
TextSize: size,
Shaper: th.Shaper,
}
}
func (l LabelStyle) Layout(gtx layout.Context) layout.Dimensions {
textColorMacro := op.Record(gtx.Ops)
paint.ColorOp{Color: l.Color}.Add(gtx.Ops)
textColor := textColorMacro.Stop()
selectColorMacro := op.Record(gtx.Ops)
paint.ColorOp{Color: l.SelectionColor}.Add(gtx.Ops)
selectColor := selectColorMacro.Stop()
if l.State != nil {
if l.State.Text() != l.Text {
l.State.SetText(l.Text)
}
l.State.Alignment = l.Alignment
l.State.MaxLines = l.MaxLines
l.State.Truncator = l.Truncator
return l.State.Layout(gtx, l.Shaper, l.Font, l.TextSize, textColor, selectColor)
}
tl := widget.Label{
Alignment: l.Alignment,
MaxLines: l.MaxLines,
Truncator: l.Truncator,
}
return tl.Layout(gtx, l.Shaper, l.Font, l.TextSize, l.Text, textColor)
}