@@ 52,21 52,21 @@ type Editor struct {
// all characters are allowed.
Filter string
- eventKey int
- font text.Font
- shaper *text.Shaper
- textSize fixed.Int26_6
- blinkStart time.Time
- focused bool
- rr editBuffer
- maskReader maskReader
- lastMask rune
- maxWidth int
- viewSize image.Point
- valid bool
- regions []region
- dims layout.Dimensions
- requestFocus bool
+ eventKey int
+ font text.Font
+ shaper *text.Shaper
+ textSize fixed.Int26_6
+ blinkStart time.Time
+ focused bool
+ rr editBuffer
+ maskReader maskReader
+ lastMask rune
+ maxWidth, minWidth int
+ viewSize image.Point
+ valid bool
+ regions []region
+ dims layout.Dimensions
+ requestFocus bool
// offIndex is an index of rune index to byte offsets.
offIndex []offEntry
@@ 547,10 547,15 @@ func (e *Editor) Layout(gtx layout.Context, lt *text.Shaper, font text.Font, siz
if e.SingleLine {
maxWidth = math.MaxInt
}
+ minWidth := gtx.Constraints.Min.X
if maxWidth != e.maxWidth {
e.maxWidth = maxWidth
e.invalidate()
}
+ if minWidth != e.minWidth {
+ e.minWidth = minWidth
+ e.invalidate()
+ }
if lt != e.shaper {
e.shaper = lt
e.invalidate()
@@ 891,7 896,7 @@ func (e *Editor) layoutText(lt *text.Shaper) {
Font: e.font,
PxPerEm: e.textSize,
Alignment: e.Alignment,
- }, 0, e.maxWidth, e.locale, r)
+ }, e.minWidth, e.maxWidth, e.locale, r)
for glyph, ok := it.processGlyph(lt.NextGlyph()); ok; glyph, ok = it.processGlyph(lt.NextGlyph()) {
e.index.Glyph(glyph)
}
@@ 115,7 115,7 @@ func TestEditorZeroDimensions(t *testing.T) {
func TestEditorConfigurations(t *testing.T) {
gtx := layout.Context{
Ops: new(op.Ops),
- Constraints: layout.Exact(image.Pt(100, 100)),
+ Constraints: layout.Exact(image.Pt(300, 300)),
Locale: english,
}
cache := text.NewShaper(gofont.Collection())
@@ 126,27 126,41 @@ func TestEditorConfigurations(t *testing.T) {
// Ensure that both ends of the text are reachable in all permutations
// of settings that influence layout.
- for _, lineMode := range []bool{true, false} {
+ for _, singleLine := range []bool{true, false} {
for _, alignment := range []text.Alignment{text.Start, text.Middle, text.End} {
- t.Run(fmt.Sprintf("SingleLine: %v Alignment: %v", lineMode, alignment), func(t *testing.T) {
- defer func() {
- if err := recover(); err != nil {
- t.Error(err)
+ for _, zeroMin := range []bool{true, false} {
+ t.Run(fmt.Sprintf("SingleLine: %v Alignment: %v ZeroMinConstraint: %v", singleLine, alignment, zeroMin), func(t *testing.T) {
+ defer func() {
+ if err := recover(); err != nil {
+ t.Error(err)
+ }
+ }()
+ if zeroMin {
+ gtx.Constraints.Min = image.Point{}
+ } else {
+ gtx.Constraints.Min = gtx.Constraints.Max
}
- }()
- e := new(Editor)
- e.SingleLine = lineMode
- e.Alignment = alignment
- e.SetText(sentence)
- e.SetCaret(0, 0)
- e.Layout(gtx, cache, font, fontSize, nil)
- e.SetCaret(runes, runes)
- e.Layout(gtx, cache, font, fontSize, nil)
- coords := e.CaretCoords()
- if int(coords.X) > gtx.Constraints.Max.X || int(coords.Y) > gtx.Constraints.Max.Y {
- t.Errorf("caret coordinates %v exceed constraints %v", coords, gtx.Constraints.Max)
- }
- })
+ e := new(Editor)
+ e.SingleLine = singleLine
+ e.Alignment = alignment
+ e.SetText(sentence)
+ e.SetCaret(0, 0)
+ dims := e.Layout(gtx, cache, font, fontSize, nil)
+ if dims.Size.X < gtx.Constraints.Min.X || dims.Size.Y < gtx.Constraints.Min.Y {
+ t.Errorf("expected min size %#+v, got %#+v", gtx.Constraints.Min, dims.Size)
+ }
+ coords := e.CaretCoords()
+ if halfway := float32(gtx.Constraints.Min.X) * .5; !singleLine && alignment == text.Middle && !zeroMin && coords.X != halfway {
+ t.Errorf("expected caret X to be %f, got %f", halfway, coords.X)
+ }
+ e.SetCaret(runes, runes)
+ e.Layout(gtx, cache, font, fontSize, nil)
+ coords = e.CaretCoords()
+ if int(coords.X) > gtx.Constraints.Max.X || int(coords.Y) > gtx.Constraints.Max.Y {
+ t.Errorf("caret coordinates %v exceed constraints %v", coords, gtx.Constraints.Max)
+ }
+ })
+ }
}
}
}