Skip to content

Commit ddf770b

Browse files
whereswaldoneliasnaur
authored andcommitted
widget{,/material}: surface line height manipulation
This commit surfaces fields to manipulate the line height of all label and editor types. It's unfortunate how this spreads through the API, but I don't see a good way to eliminate that right now. Signed-off-by: Chris Waldon <[email protected]>
1 parent acab582 commit ddf770b

File tree

6 files changed

+81
-19
lines changed

6 files changed

+81
-19
lines changed

widget/editor.go

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ type Editor struct {
3535
text textView
3636
// Alignment controls the alignment of text within the editor.
3737
Alignment text.Alignment
38+
// LineHeight determines the gap between baselines of text. If zero, a sensible
39+
// default will be used.
40+
LineHeight unit.Sp
41+
// LineHeightScale is multiplied by LineHeight to determine the final gap
42+
// between baselines. If zero, a sensible default will be used.
43+
LineHeightScale float32
3844
// SingleLine force the text to stay on a single line.
3945
// SingleLine also sets the scrolling direction to
4046
// horizontal.
@@ -504,6 +510,8 @@ func (e *Editor) initBuffer() {
504510
e.text.SetSource(e.buffer)
505511
}
506512
e.text.Alignment = e.Alignment
513+
e.text.LineHeight = e.LineHeight
514+
e.text.LineHeightScale = e.LineHeightScale
507515
e.text.SingleLine = e.SingleLine
508516
e.text.Mask = e.Mask
509517
e.text.WrapPolicy = e.WrapPolicy

widget/label.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ type Label struct {
3030
Truncator string
3131
// WrapPolicy configures how displayed text will be broken into lines.
3232
WrapPolicy text.WrapPolicy
33+
// LineHeight controls the distance between the baselines of lines of text.
34+
// If zero, a sensible default will be used.
35+
LineHeight unit.Sp
36+
// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
37+
// sensible default will be used.
38+
LineHeightScale float32
3339
}
3440

3541
// Layout the label with the given shaper, font, size, text, and material.
@@ -49,16 +55,19 @@ type TextInfo struct {
4955
func (l Label) LayoutDetailed(gtx layout.Context, lt *text.Shaper, font font.Font, size unit.Sp, txt string, textMaterial op.CallOp) (layout.Dimensions, TextInfo) {
5056
cs := gtx.Constraints
5157
textSize := fixed.I(gtx.Sp(size))
58+
lineHeight := fixed.I(gtx.Sp(l.LineHeight))
5259
lt.LayoutString(text.Parameters{
53-
Font: font,
54-
PxPerEm: textSize,
55-
MaxLines: l.MaxLines,
56-
Truncator: l.Truncator,
57-
Alignment: l.Alignment,
58-
WrapPolicy: l.WrapPolicy,
59-
MaxWidth: cs.Max.X,
60-
MinWidth: cs.Min.X,
61-
Locale: gtx.Locale,
60+
Font: font,
61+
PxPerEm: textSize,
62+
MaxLines: l.MaxLines,
63+
Truncator: l.Truncator,
64+
Alignment: l.Alignment,
65+
WrapPolicy: l.WrapPolicy,
66+
MaxWidth: cs.Max.X,
67+
MinWidth: cs.Min.X,
68+
Locale: gtx.Locale,
69+
LineHeight: lineHeight,
70+
LineHeightScale: l.LineHeightScale,
6271
}, txt)
6372
m := op.Record(gtx.Ops)
6473
viewport := image.Rectangle{Max: cs.Max}

widget/material/editor.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@ import (
1616
)
1717

1818
type EditorStyle struct {
19-
Font font.Font
20-
TextSize unit.Sp
19+
Font font.Font
20+
// LineHeight controls the distance between the baselines of lines of text.
21+
// If zero, a sensible default will be used.
22+
LineHeight unit.Sp
23+
// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
24+
// sensible default will be used.
25+
LineHeightScale float32
26+
TextSize unit.Sp
2127
// Color is the text color.
2228
Color color.NRGBA
2329
// Hint contains the text displayed when the editor is empty.
@@ -64,7 +70,12 @@ func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions {
6470
}
6571

6672
macro := op.Record(gtx.Ops)
67-
tl := widget.Label{Alignment: e.Editor.Alignment, MaxLines: maxlines}
73+
tl := widget.Label{
74+
Alignment: e.Editor.Alignment,
75+
MaxLines: maxlines,
76+
LineHeight: e.LineHeight,
77+
LineHeightScale: e.LineHeightScale,
78+
}
6879
dims := tl.Layout(gtx, e.shaper, e.Font, e.TextSize, e.Hint, hintColor)
6980
call := macro.Stop()
7081

@@ -74,6 +85,8 @@ func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions {
7485
if h := dims.Size.Y; gtx.Constraints.Min.Y < h {
7586
gtx.Constraints.Min.Y = h
7687
}
88+
e.Editor.LineHeight = e.LineHeight
89+
e.Editor.LineHeightScale = e.LineHeightScale
7790
dims = e.Editor.Layout(gtx, e.shaper, e.Font, e.TextSize, textColor, selectionColor)
7891
if e.Editor.Len() == 0 {
7992
call.Add(gtx.Ops)

widget/material/label.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ type LabelStyle struct {
3838
Text string
3939
// TextSize determines the size of the text glyphs.
4040
TextSize unit.Sp
41+
// LineHeight controls the distance between the baselines of lines of text.
42+
// If zero, a sensible default will be used.
43+
LineHeight unit.Sp
44+
// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
45+
// sensible default will be used.
46+
LineHeightScale float32
4147

4248
// Shaper is the text shaper used to display this labe. This field is automatically
4349
// set using by all constructor functions. If constructing a LabelStyle literal, you
@@ -132,13 +138,17 @@ func (l LabelStyle) Layout(gtx layout.Context) layout.Dimensions {
132138
l.State.MaxLines = l.MaxLines
133139
l.State.Truncator = l.Truncator
134140
l.State.WrapPolicy = l.WrapPolicy
141+
l.State.LineHeight = l.LineHeight
142+
l.State.LineHeightScale = l.LineHeightScale
135143
return l.State.Layout(gtx, l.Shaper, l.Font, l.TextSize, textColor, selectColor)
136144
}
137145
tl := widget.Label{
138-
Alignment: l.Alignment,
139-
MaxLines: l.MaxLines,
140-
Truncator: l.Truncator,
141-
WrapPolicy: l.WrapPolicy,
146+
Alignment: l.Alignment,
147+
MaxLines: l.MaxLines,
148+
Truncator: l.Truncator,
149+
WrapPolicy: l.WrapPolicy,
150+
LineHeight: l.LineHeight,
151+
LineHeightScale: l.LineHeightScale,
142152
}
143153
return tl.Layout(gtx, l.Shaper, l.Font, l.TextSize, l.Text, textColor)
144154
}

widget/selectable.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ type Selectable struct {
5959
// if text was cut off. Defaults to "…" if left empty.
6060
Truncator string
6161
// WrapPolicy configures how displayed text will be broken into lines.
62-
WrapPolicy text.WrapPolicy
63-
initialized bool
64-
source stringSource
62+
WrapPolicy text.WrapPolicy
63+
// LineHeight controls the distance between the baselines of lines of text.
64+
// If zero, a sensible default will be used.
65+
LineHeight unit.Sp
66+
// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
67+
// sensible default will be used.
68+
LineHeightScale float32
69+
initialized bool
70+
source stringSource
6571
// scratch is a buffer reused to efficiently read text out of the
6672
// textView.
6773
scratch []byte
@@ -181,6 +187,8 @@ func (l *Selectable) Truncated() bool {
181187
// paint material for the text and selection rectangles, respectively.
182188
func (l *Selectable) Layout(gtx layout.Context, lt *text.Shaper, font font.Font, size unit.Sp, textMaterial, selectionMaterial op.CallOp) layout.Dimensions {
183189
l.initialize()
190+
l.text.LineHeight = l.LineHeight
191+
l.text.LineHeightScale = l.LineHeightScale
184192
l.text.Alignment = l.Alignment
185193
l.text.MaxLines = l.MaxLines
186194
l.text.Truncator = l.Truncator

widget/text.go

+14
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ type textSource interface {
4444
// be scrolled, and for configuring and drawing text selection boxes.
4545
type textView struct {
4646
Alignment text.Alignment
47+
// LineHeight controls the distance between the baselines of lines of text.
48+
// If zero, a sensible default will be used.
49+
LineHeight unit.Sp
50+
// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
51+
// sensible default will be used.
52+
LineHeightScale float32
4753
// SingleLine forces the text to stay on a single line.
4854
// SingleLine also sets the scrolling direction to
4955
// horizontal.
@@ -273,6 +279,14 @@ func (e *textView) Update(gtx layout.Context, lt *text.Shaper, font font.Font, s
273279
e.params.WrapPolicy = e.WrapPolicy
274280
e.invalidate()
275281
}
282+
if lh := fixed.I(gtx.Sp(e.LineHeight)); lh != e.params.LineHeight {
283+
e.params.LineHeight = lh
284+
e.invalidate()
285+
}
286+
if e.LineHeightScale != e.params.LineHeightScale {
287+
e.params.LineHeightScale = e.LineHeightScale
288+
e.invalidate()
289+
}
276290

277291
e.makeValid()
278292
if eventHandling != nil {

0 commit comments

Comments
 (0)