diff --git a/ui/textbox.go b/ui/textbox.go index 697fdd6..76f1347 100644 --- a/ui/textbox.go +++ b/ui/textbox.go @@ -37,6 +37,8 @@ type TextBox struct { Focus bool Text string Selection TextSelection + + textChanged Events } func BuildTextBox(fn func(*TextBox)) *TextBox { @@ -64,6 +66,8 @@ func (b *TextBox) DesiredSize(ctx Context, _ geom.PointF32) geom.PointF32 { return geom.PtF32(width+pad*2, height+pad*2) } +func (b *TextBox) TextChanged() *Events { return &b.textChanged } + func (b *TextBox) mousePosToCaretPos(ctx Context, e MouseEvent) int { p := b.ToControlPosition(e.Pos()) offset := p.X - b.box.bounds.Min.X @@ -93,13 +97,13 @@ func (b *TextBox) mousePosToCaretPos(ctx Context, e MouseEvent) int { return carets[2] } -func (b *TextBox) cut() string { +func (b *TextBox) cut(ctx Context) string { start, end := b.selectionRange() if end == 0 { return "" } cut := b.Text[start:end] - b.Text = b.Text[:start] + b.Text[end:] + b.updateText(ctx, b.Text[:start]+b.Text[end:]) b.Selection.Caret = start b.Selection.SetSelectionToCaret() return cut @@ -170,20 +174,20 @@ func (b *TextBox) Handle(ctx Context, e Event) bool { switch { case e.Key == KeyDelete: if b.Selection.HasSelection() { - b.cut() + b.cut(ctx) } else { caret := b.Selection.Caret if caret < len(b.Text) { - b.Text = b.Text[:caret] + b.Text[caret+1:] + b.updateText(ctx, b.Text[:caret]+b.Text[caret+1:]) } } case e.Key == KeyBackspace: if b.Selection.HasSelection() { - b.cut() + b.cut(ctx) } else { caret := b.Selection.Caret if caret > 0 { - b.Text = b.Text[:caret-1] + b.Text[caret:] + b.updateText(ctx, b.Text[:caret-1]+b.Text[caret:]) b.Selection.Caret = caret - 1 b.Selection.SetSelectionToCaret() } @@ -221,22 +225,22 @@ func (b *TextBox) Handle(ctx Context, e Event) bool { return r }, text) if err == nil { - b.cut() + b.cut(ctx) caret := b.Selection.Caret - b.Text = b.Text[:caret] + text + b.Text[caret:] + b.updateText(ctx, b.Text[:caret]+text+b.Text[caret:]) b.Selection.Caret = caret + len(text) } case KeyX: - DefaultClipboard.WriteText(b.cut()) + DefaultClipboard.WriteText(b.cut(ctx)) } } return true case *TextInputEvent: if b.Selection.HasSelection() { - b.cut() + b.cut(ctx) } caret := b.Selection.Caret - b.Text = fmt.Sprintf("%s%c%s", b.Text[:caret], e.Character, b.Text[caret:]) + b.updateText(ctx, fmt.Sprintf("%s%c%s", b.Text[:caret], e.Character, b.Text[caret:])) b.Selection.Caret = caret + 1 b.Selection.SetSelectionToCaret() return true @@ -272,3 +276,11 @@ func (b *TextBox) Render(ctx Context) { } }) } + +func (b *TextBox) updateText(ctx Context, text string) { + if b.Text == text { + return + } + b.Text = text + b.textChanged.Notify(ctx, text) +}