diff --git a/widget/editor.go b/widget/editor.go index 684520ec..026f5ee4 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -485,6 +485,17 @@ func (e *Editor) Focused() bool { return e.focused } +// calculateViewSize determines the size of the current visible content, +// ensuring that even if there is no text content, some space is reserved +// for the caret. +func (e *Editor) calculateViewSize(gtx layout.Context) image.Point { + base := e.dims.Size + if caretWidth := e.caretWidth(gtx); base.X < caretWidth { + base.X = caretWidth + } + return gtx.Constraints.Constrain(base) +} + // Layout lays out the editor. If content is not nil, it is laid out on top. func (e *Editor) Layout(gtx layout.Context, sh text.Shaper, font text.Font, size unit.Value, content layout.Widget) layout.Dimensions { if e.locale != gtx.Locale { @@ -518,7 +529,7 @@ func (e *Editor) Layout(gtx layout.Context, sh text.Shaper, font text.Font, size e.processEvents(gtx) e.makeValid() - if viewSize := gtx.Constraints.Constrain(e.dims.Size); viewSize != e.viewSize { + if viewSize := e.calculateViewSize(gtx); viewSize != e.viewSize { e.viewSize = viewSize e.invalidate() } @@ -749,14 +760,21 @@ func (e *Editor) PaintText(gtx layout.Context) { } } -func (e *Editor) PaintCaret(gtx layout.Context) { - if !e.caret.on { - return - } +// caretWidth returns the width occupied by the caret for the current +// gtx. +func (e *Editor) caretWidth(gtx layout.Context) int { carWidth2 := gtx.Px(unit.Dp(1)) / 2 if carWidth2 < 1 { carWidth2 = 1 } + return carWidth2 +} + +func (e *Editor) PaintCaret(gtx layout.Context) { + if !e.caret.on { + return + } + carWidth2 := e.caretWidth(gtx) caretPos, carAsc, carDesc := e.caretInfo() carRect := image.Rectangle{ diff --git a/widget/editor_test.go b/widget/editor_test.go index cec9bc9b..1344ca27 100644 --- a/widget/editor_test.go +++ b/widget/editor_test.go @@ -36,6 +36,26 @@ var english = system.Locale{ Direction: system.LTR, } +// TestEditorZeroDimensions ensures that an empty editor still reserves +// space for displaying its caret when the constraints allow for it. +func TestEditorZeroDimensions(t *testing.T) { + gtx := layout.Context{ + Ops: new(op.Ops), + Constraints: layout.Constraints{ + Max: image.Pt(100, 100), + }, + Locale: english, + } + cache := text.NewCache(gofont.Collection()) + fontSize := unit.Px(10) + font := text.Font{} + e := new(Editor) + dims := e.Layout(gtx, cache, font, fontSize, nil) + if dims.Size.X < 1 || dims.Size.Y < 1 { + t.Errorf("expected empty editor to occupy enough space to display cursor, but returned dimensions %v", dims) + } +} + func TestEditorConfigurations(t *testing.T) { gtx := layout.Context{ Ops: new(op.Ops),