Some basic TextArea code.

This commit is contained in:
Oliver 2022-07-27 12:48:38 +01:00
parent 73bf2902b5
commit 566470eb7a
4 changed files with 175 additions and 7 deletions

3
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-runewidth v0.0.13
github.com/rivo/uniseg v0.2.0
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
golang.org/x/text v0.3.7 // indirect
)

7
go.sum
View File

@ -9,12 +9,13 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

161
textarea.go Normal file
View File

@ -0,0 +1,161 @@
package tview
import "github.com/gdamore/tcell/v2"
var (
// NewLine is the string sequence to be inserted when hitting the Enter key
// in a TextArea. The default is "\n" but you may change it to "\r\n" if
// required.
NewLine = "\n"
)
// TextArea implements a simple text editor for multi-line text. Multi-color
// text is not supported. Text can be optionally word-wrapped to fit the
// available width.
//
// Navigation and Editing
//
// A text area is always in editing mode and no other mode exists. The following
// keys can be used to move the cursor:
//
// - Left arrow: Move left.
// - Right arrow: Move right.
// - Down arrow: Move down.
// - Up arrow: Move up.
// - Ctrl-A, Home: Move to the beginning of the current line.
// - Ctrl-E, End: Move to the end of the current line.
// - Ctrl-F, page down: Move down by one page.
// - Ctrl-B, page up: Move up by one page.
// - TODO (Shift+Ctrl-/Alt-Up arrow): Scroll the page up, leaving the cursor in its position.
// - TODO (Shift+Ctrl-/Alt-Down arrow): Scroll the page down, leaving the cursor in its position.
//
// If the mouse is enabled, clicking on a screen cell will move the cursor to
// that location or to the end of the line if past the last character. Turning
// the scroll wheel will scroll the text. Text can also be selected by moving
// the mouse while pressing the left mouse button (see below for details).
//
// Entering a character (rune) will insert it at the current cursor location.
// Subsequent characters are moved accordingly. If the cursor is outside the
// visible area, any changes to the text will move it into the visible area. The
// following keys can also be used to modify the text:
//
// - Enter: Insert a newline character (see NewLine).
// - Tab: Insert TabSize spaces.
// - Ctrl-H, Backspace: Delete one character to the left of the cursor.
// - Ctrl-D, Delete: Delete the character under the cursor (or the first
// character on the next line if the cursor is at the end of a line).
// - Ctrl-K: Delete everything under and to the right of the cursor.
// - Ctrl-W: Delete from the start of the current word to the left of the
// cursor.
// - Ctrl-U: Delete the current line, i.e. everything after the last newline
// character before the cursor up until the next newline character. This may
// span multiple lines if wrapping is enabled.
//
// Text can be selected by moving the cursor while holding the Shift key or
// dragging the mouse. When text is selected:
//
// - Entering a character (rune) will replace the selected text with the new
// character. (The Enter key is an exception, see further below.)
// - Backspace, delete: Delete the selected text.
// - Enter: Copy the selected text into the clipboard, unselect the text.
// - Ctrl-X: Copy the selected text into the clipboard and delete it.
// - Ctrl-V: Replace the selected text with the clipboard text. If no text is
// selected, the clipboard text will be inserted at the cursor location.
//
// The default clipboard is an internal text buffer, i.e. the operating system's
// clipboard is not used. The Enter key was chosen for the "copy" function
// because the Ctrl-C key is the default key to stop the application. If your
// application frees up the global Ctrl-C key and you want to bind it to the
// "copy to clipboard" function, you may use SetInputCapture() to override the
// Enter/Ctrl-C keys to implement copying to the clipboard.
//
// Similarly, if you want to implement your own clipboard (or make use of your
// operating system's clipboard), you can also use SetInputCapture() to override
// the key binds for copy, cut, and paste. The GetSelection(), ReplaceText(),
// and SetSelection() provide all the functionality needed for your own
// clipboard.
type TextArea struct {
*Box
// The text to be shown in the text area when it is empty.
placeholder string
// If set to true, lines that are longer than the available width are
// wrapped onto the next line. If set to false, any characters beyond the
// available width are discarded.
wrap bool
// If set to true and if wrap is also true, lines are split at spaces or
// after punctuation characters.
wordWrap bool
// The maximum number of bytes allowed in the text area. If 0, there is no
// limit.
maxLength int
// The index of the first line shown in the text area.
lineOffset int
// The number of cells to be skipped on each line (not used in wrap mode).
columnOffset int
// The height of the content the last time the text area was drawn.
pageSize int
// The style of the text. Background colors different from the Box's
// background color may lead to unwanted artefacts.
textStyle tcell.Style
}
// NewTextArea returns a new text area.
func NewTextArea() *TextArea {
return &TextArea{
Box: NewBox(),
wrap: true,
wordWrap: true,
textStyle: tcell.StyleDefault.Background(Styles.PrimitiveBackgroundColor).Foreground(Styles.PrimaryTextColor),
}
}
// SetWrap sets the flag that, if true, leads to lines that are longer than the
// available width being wrapped onto the next line. If false, any characters
// beyond the available width are not displayed.
func (t *TextArea) SetWrap(wrap bool) *TextArea {
//TODO: Existing text needs reformatting.
t.wrap = wrap
return t
}
// SetWordWrap sets the flag that, if true and if the "wrap" flag is also true
// (see SetWrap()), wraps the line at spaces or after punctuation marks.
//
// This flag is ignored if the "wrap" flag is false.
func (t *TextArea) SetWordWrap(wrapOnWords bool) *TextArea {
//TODO: Existing text needs reformatting.
t.wordWrap = wrapOnWords
return t
}
// SetSelection selects the text starting at index "start" and ending just
// before the index "end". Any previous selection is discarded. If "start" and
// "end" are the same, currently selected text is unselected.
func (t *TextArea) SetSelection(start, end int) *TextArea {
//TODO
return t
}
// GetSelection returns the currently selected text or an empty string if no
// text is currently selected. The start and end indices (a half-open range)
// into the text area's text are also returned.
func (t *TextArea) GetSelection() (string, int, int) {
return "", 0, 0 //TODO
}
// ReplaceText replaces the text in the given range with the given text. The
// range is half-open, that is, the character at the "end" index is not
// replaced. If the provided range overlaps with a selection, the selected text
// will be unselected.
func (t *TextArea) ReplaceText(start, end int, text string) *TextArea {
//TODO
return t
}

View File

@ -75,8 +75,12 @@ func (w TextViewWriter) HasFocus() bool {
return w.t.hasFocus
}
// TextView is a box which displays text. It implements the io.Writer interface
// so you can stream text to it. This does not trigger a redraw automatically
// TextView is a box which displays text. While the text to be displayed can be
// changed or appended to, there is no functionality that allows the user to
// edit text. For that, TextArea should be used.
//
// TextView implements the io.Writer interface so you can stream text to it,
// appending to the existing text. This does not trigger a redraw automatically
// but if a handler is installed via SetChangedFunc(), you can cause it to be
// redrawn. (See SetChangedFunc() for more details.)
//
@ -179,7 +183,8 @@ type TextView struct {
// If set to true, the text view will always remain at the end of the content.
trackEnd bool
// The number of characters to be skipped on each line (not in wrap mode).
// The number of characters to be skipped on each line (not used in wrap
// mode).
columnOffset int
// The maximum number of lines kept in the line index, effectively the