# The Interface Kit: BTextView

Derived from: public BView

Declared in: be/interface/TextView.h

Library: libbe.so

## Overview

A BTextView object displays text on-screen, and provides these text manipulating features:

- It lets the user enter, select, and edit text from the keyboard and mouse.

- It supports standard Cut, Copy, Paste, Delete, and Select All editing commands

- It provides an Undo mechanism.

  By default, a BTextView displays all its text in a single font and color. The `SetStylable()` turns on support for multiple character formats.

  Paragraph formats--such as alignment and tab widths--are uniform for all text the BTextView displays. These properties can be set, but the setting always applies to the entire text.

  ### Offsets

  The BTextView locates particular characters in its text buffer by offsets from the beginning of the data. The offsets count bytes, not characters, and begin at 0. A single character is identified by the offset of the first byte of the character. A group of characters--the current selection, for example--is delimited by the offsets that bound its first and last characters; all characters beginning with the first offset up to, but not including, the last offset are part of the group.

  For example, suppose the BTextView contains the following text in Unicode UTF-8 encoding,

  |  | The BeOS(TM) is . . .

  and "BeOS(TM) " is selected. `GetSelection()` would return 4 and 11 as the offsets that enclose the selection. The character 'B' occupies the fourth byte of text and the space following the trademark symbol is the eleventh byte of text. The characters in "BeOS" are each encoded in one byte, but '(TM) ' takes up three bytes in UTF-8. Thus the five-character selection occupies 7 bytes (and offsets) of text.

  Although offsets count bytes, they can also be thought of as designating positions between characters. The position at the beginning of the text is offset 0, the position between the space and the 'B' in the example above is at offset 4, the position between the '(TM) ' and the space is at offset 11, and so on. Thus, even if no characters are selected, the insertion point (and location of the caret) can still be designated by an offset.

  Most BTextView functions expect the offsets they're passed to mark positions between characters; the results are not defined if a character-internal offset is specified instead.

  ### Graphics Primitives

  The BTextView's mechanism for formatting and drawing text uses the graphics primitives it inherits from the BView class. However, it largely presents its own API for determining the appearance of the text it draws. You should not attempt to affect the BTextView by calling primitive BView functions like `MovePen()`, `SetFont()`, or `SetHighColor()`. Instead, use BTextView functions like `SetFontAndColor()` and let the object take care of formatting and drawing the text.

  The one inherited function that can influence the BTextView is `SetViewColor()`. This function determines the background against which the text is drawn and the color that is used in antialiasing calculations.

  ### Resizing

  A BTextView can be made to resize itself to exactly fit the text that the user enters. This is sometimes appropriate for small one-line text fields. See the `MakeResizable()` function.

  ### BTextView and BScrollBars

  If you add scrollbars to control the position of the BTextView's document--this includes using a BTextView as the target of a BScrollView--the BTextView will update the scrollbars for you. (Note that it doesn't own the scrollbars; you still have to delete them yourself if you created them.) When the BTextView is first displayed and thereafter resized, the scrollbars' ranges, step sizes, and scroller positions and proportions are automatically reset to reflect the BTextView object's bounds. Attempts to set these parameters directly (through `BScrollBar::SetRange()` etc.), are worse than ignored; they're actually applied, and then (at some point) the BTextView will notice the change in the scrollbars and reset them. Looks like flicker to me.

  ### Shortcuts and Menu Items

  When it's the focus view for its window, a BTextView automatically responds to a set of keyboard shortcuts:

  - Command+x cuts text and copies it to the clipboard
  - Command+c copies text to the clipboard without cutting it
  - Command+v pastes text taken from the clipboard
  - Command+a selects all of the text in the BTextView
  - Command+z undoes the previous action

  If you create menu items for these actions, you have to assign the BMenuItem shortcuts and command constants yourself:

  Action | Constant | Shortcut
  Cut | `B_CUT` | Command+x
  Copy | `B_COPY` | Command+c
  Paste | `B_PASTE` | Command+v
  Select all | `B_SELECT_ALL` | Command+a
  Undo | `B_UNDO` | Command+z

  ### Scripting Support

  The BTextView class responds to the following scripting messages, though it doesn't give them a suite name:

  |  | Property name: "Text" for the text assigned to the BTextView Specifiers: `B_RANGE_SPECIFIER` and `B_REVERSE_RANGE_SPECIFIER` Messages: `B_SET_PROPERTY` and `B_GET_PROPERTY` Data type: a null-terminated character string (`B_STRING_TYPE`)
  |  | Property name: "text_run_array" for character formats in a range of text Specifiers: `B_RANGE_SPECIFIER` and `B_REVERSE_RANGE_SPECIFIER` Messages: `B_SET_PROPERTY` and `B_GET_PROPERTY` Data type: a `text_run_array` structure
  |  | Property name: "selection" for the text that's currently selected Specifiers: `B_DIRECT_SPECIFIER` Messages: `B_SET_PROPERTY` and `B_GET_PROPERTY` Data type: `int32` offsets to the beginning and end of the selection

  The "index" in a specifier for the "Text" and "text_run_array" properties is a byte offset to the first byte of a character. The "range" similarly counts bytes, not characters.

  The "range" for both `B_RANGE_SPECIFIER` and `B_REVERSE_RANGE_SPECIFIER` specifiers counts bytes from the "index" toward the end of the list--even if the index counts in reverse from the end of the list forward.

  If a `B_SET_PROPERTY` message for the "Text" property lacks a "data" entry, the BTextView deletes the range of bytes specified. However, if "data" is provided, the BTextView inserts the number of bytes specified. In other words, for a deletion, the "range" entry in the specifier counts bytes in the BTextView beginning at the specified index; for an insertion the "range" entry counts bytes in the "data" entry beginning with the first byte.

  See "Scripting" in The Application Kit chapter for more on scripting messages.

  ## Hook Functions

  `AcceptsDrop()`
  Determines whether a BMessage that's dragged to the BTextView has data that the object can insert; can be reimplemented to prevent the BTextView from accepting dropped text or to allow it to accept data it currently doesn't understand.

  `AcceptsPaste()`
  Determines whether the BTextView can take data from the clipboard; can be reimplemented to prevent text from being pasted or to make the BTextView accept data it currently doesn't understand.

  `CanEndLine()`
  Determines where a line can end; can be overridden to follow a different criterion than the default.

  `DeleteText()`
  Deletes characters from the text; can be augmented to preview the deletions and accept or reject them before the text is removed from the display. This function is called to carry out all deletions.

  `FindWord()`
  Finds the boundaries of a word when the user double-clicks; can be overridden to redefine what a word is or to provide a definition of a word for other languages.

  `GetDragParameters()`
  Invoked when a drag is initiated. You can override the function to supply parameters, such as a bitmap, that are used during the drag.

  `InsertText()`
  Inserts new characters into the text; can be augmented to preview the characters the user types, pastes, or drops and accept or reject them before they're added to the display. All insertions pass through this function.

  `Undo()`
  Invoked when the object gets a `B_UNDO` message. You can augment or replace the default undo response by implementing this function.

  ## Constructor and Destructor

  ### BTextView()

            BTextView(BRect frame, const char *name, BRect textRect,
               uint32 resizingMode, uint32 flags)
            BTextView(BRect frame, const char *name, BRect textRect,
               const BFont *font, const rgb_color *color,
               uint32 resizingMode, uint32 flags)
            BTextView(BMessage *archive)

  Initializes the BTextView to the frame rectangle, stated in its eventual parent's coordinate system, assigns it an identifying name, sets its resizing behavior to resizingMode and its drawing behavior with flags. These four arguments--frame, name, resizingMode, and flags--are identical to those declared for the BView class and are passed to the BView constructor. The frame, name, and resizingMode arguments are passed to the BView class unchanged, but two flags are added to the flags argument--`B_FRAME_EVENTS`, so that the BTextView can reformat the text when it's resized, and `B_PULSE_NEEDED`, so that the caret marking the insertion point can "blink" in time with `B_PULSE` messages. Later, `AttachedToWindow()` will set the window's pulse rate to 500,000 microseconds.

  The text rectangle, textRect, is stated in the BTextView's coordinate system. It determines where text in placed within the view's bounds rectangle:

  - The first line of text is placed at the top of the text rectangle. As additional lines of text are entered into the view, the text grows downward and may actually extend beyond the bottom of the rectangle.

  - The left and right sides of the text rectangle determine where lines of text are placed within the view. Lines can be aligned to either side of the rectangle, or they can be centered between the two sides. See the `SetAlignment()` function.

  - When lines wrap on word boundaries, the width of the text rectangle determines the maximum length of a line; each line of text can be as long as the rectangle is wide. When word wrapping isn't turned on, lines can extend beyond the boundaries of the text rectangle. See the `SetWordWrap()` function.

  The bottom of the text rectangle is ignored; it doesn't limit the amount of text the view can contain. The text can be limited by the number of characters, but not by the number of lines.

  If a default font is provided, the BTextView will display its text in that font, unless another font is later set. Similarly, if a default color is specified, the text will be displayed in that color, unless the color is subsequently changed. If the font is `NULL` or not specified, the BTextView uses the system plain font, `be_plain_font`. If the color pointer is `NULL` or not specified, the text is drawn in black.

  The constructor establishes the following default properties for a new BTextView:

  - The text is selectable and editable. (See `MakeSelectable()` and `MakeEditable()`.)

  - Multiple character formats are not permitted. (See `SetStylable()`.)

  - The text is left-aligned. (See `SetAlignment()`.)

  - The tab width is 28.0 coordinate units. (See `SetTabWidth()`.)

  - Word wrapping is turned on. (See `SetWordWrap()`.)

  - Automatic indenting is turned off. (See `SetAutoindent()`.)

  - The maximum amount of data is permitted. (See `SetMaxBytes()`.)

  - The view doesn't grow to accommodate more characters. (See `MakeResizable()`.)

  - All characters the user may type are acceptable. (See `DisallowChar()`.)

  See also: `AttachedToWindow()`, `SetFontAndColor()`, the BView constructor

  ### ~BTextView()

            virtual ~BTextView()

  Frees the memory the BTextView allocated to hold the text and to store information about it.

  ## Static Functions

  ### FlattenRunArray(), UnflattenRunArray()

            static void *FlattenRunArray(const text_run_array *runs, int32 *numBytes = NULL)

            static text_run_array *UnflattenRunArray(const void *data, int32 *numBytes = NULL)

  These functions flatten and unflatten a `text_run_array` structure so that it can be treated as an untyped stream of bytes. A `text_run_array` that's saved on-disk will be valid when the user reboots the machine only if it's saved as flat data. Both functions return pointers to memory they allocate (with `malloc()`). The caller is responsible for freeing the memory when it's no longer needed.

  `FlattenRunArray()` flattens the runs `text_run_array` and returns the flat data. `UnflattenRunArray()` reconstructs a `text_run_array` from previously flattened data and returns a pointer to the structure.

  If a numBytes argument is provided, both functions place the number of bytes they allocated for the data in the variable that numBytes refers to.

  See also: `SetRunArray()`

  ### Instantiate()

            static BTextView *Instantiate(BMessage *archive)

  Returns a new BTextView object, allocated by `new` and created by the version of the constructor that takes a BMessage archive. However, if the archive doesn't contain data for a BTextView object, the return value will be `NULL`.

  See also: `BArchivable::Instantiate()`, `Archive()`

  ### UnflattenRunArray() see FlattenRunArray()

  ## Member Functions

  ### AcceptsDrop(), AcceptsPaste()

            virtual bool AcceptsDrop(const BMessage *message)

            virtual bool AcceptsPaste(BClipboard *clipboard)

  These functions look at the data in their arguments, and return `true` if its "acceptable." The default implementations return `true` if both of the following are true:

  - the BTextView is editable
  - the message or clipboard contains `B_MIME_TYPE` data stored under the name "text/plain".

  If the data isn't acceptable, the drop or paste operation is aborted.

  `AcceptsDrop()` is invoked in two places: When a message is dragged over the BTextView, and when the message is dropped on the object. `AcceptsPaste()` is called when a `B_PASTE` message is received. If you augment these functions to accept more types, you'll also have to augment the `MessageReceived()` and `Paste()` functions to insert the text found in message or clipboard.

  ### Alignment() see SetAlignment()

  ### AllowChar() see DisallowChar()

  ### AttachedToWindow()

            virtual void AttachedToWindow(void)

  Completes the initialization of the BTextView object after it becomes attached to a window. This function sets up the object so that it can correctly format text and display it. Among other things, it sets the drawing mode to `B_OP_COPY`. If the BTextView is targeted by scroll bars, it adjusts them so that they're accurately set up for scrolling the text.

  Because the BTextView uses pulses to animate (or "blink") the caret, the vertical line that marks the current insertion point, this function also enables pulsing in the window and fixes the pulse rate at 2 per second.

  `AttachedToWindow()` is called for you when the BTextView becomes part a window's view hierarchy; you shouldn't call it yourself, though you can override it. A function that's implemented by a derived class should begin by incorporating the BTextView version:

         void MyText::AttachedToWindow()
         {
             BTextView::AttachedToWindow()
             . . .
         }

  If it doesn't, the BTextView won't be able to properly display the text.

  See also: `BView::AttachedToWindow()`, `SetFontName()`

  ### ByteAt() see Text()

  ### CanEndLine()

            virtual bool CanEndLine(int32 offset)

  Returns `true` if the character at offset can be the last character in a line of text, and `false` if not. Sometimes this depends on whether the next character (if there is one) can begin a line. This function is called as the BTextView figures out where to break lines, but only if word wrapping is turned on.

  As implemented, `CanEndLine()` allows the following ASCII characters to end a line regardless of the context:

  `B_SPACE` | = | < | / | &
  `B_TAB` | + | > | \\ | *
  `B_ENTER` | - | ^ | | | '\\0'

  The default implementation also understands the line-ending conventions for Chinese and Japanese. Because these languages are written without the spaces that typically end lines in other languages, lines can potentially break anywhere. However, certain characters are prohibited from ending a line and others are prohibited from beginning a new line. `CanEndLine()` prevents lines from ending either on a prohibited ending character or on the character before a prohibited beginning character.

  Derived classes can override this function to apply different criteria for where lines end, possibly looking at the context of the offset character. You can also augment the current implementation so that it understands the conventions for other languages.

  If you override this function to look to the left or right of the character at offset, be sure to check that you haven't stepped beyond the range of the text. For example, this version of the function makes sure that the first hyphen of a pair doesn't break a line:

         bool MyTextView::CanEndLine(int32 offset)
         {
             if ( ByteAt[offset] == '-' ) {
                 if ( TextLength() - offset > 1 ) {
                     if ( ByteAt[offset + 1] == '-' )
                         return false;
                 }
             }
             return (baseClass::CanEndLine(offset));
         }

  See also: `SetWordWrap()`

  ### ColorSpace() see SetColorSpace()

  ### Copy() see Cut()

  ### CountLines() see GoToLine()

  ### CurrentLine() see GoToLine()

  ### Cut(), Copy(), Paste()

            virtual void Cut(BClipboard *clipboard)

            virtual void Copy(BClipboard *clipboard)

            virtual void Paste(BClipboard *clipboard)

  These functions implement the standard cut, copy, and paste commands. `Cut()` and `Copy()` both copy the current selection to the specified clipboard; `Cut()` also deletes the text from the BTextView and removes it from the display. The text is entered in the clipboard as `B_MIME_TYPE` data under the name "text/plain". `Paste()` looks in the clipboard for just this type of data and pastes it into the text--but only if `AcceptsPaste()` returns `true`. The new text replaces the current selection, or is placed at the site of the current insertion point.

  If the BTextView supports multiple character formats, `Cut()` and `Copy()` also place a `text_run_array` structure describing the formats of the copied text in the clipboard--as `B_MIME_TYPE` data under the name "application/x-vnd.Be-text_run_array". If the BTextView that takes text from the clipboard supports multiple formats, `Paste()` looks for the `text_run_array` in the clipboard and sets the formats of the pasted text accordingly.

  In most cases, the clipboard argument will be identical to the global `be_clipboard` object.

  See also: `AcceptsPaste()`, Shortcuts and Menu Items in the overview

  ### Delete() see Insert()

  ### DeleteText() see InsertText()

  ### DetachedFromWindow()

            virtual void DetachedFromWindow(void)

  Resets the cursor to the standard hand image (`B_HAND_CURSOR`) if it's above the BTextView when the BTextView is removed from the window.

  See also: `BView::DetachedFromWindow()`

  ### DisallowChar(), AllowChar()

            void DisallowChar(uint32 aChar)

            void AllowChar(uint32 aChar)

  These functions inform the BTextView whether the user should be allowed to enter aChar into the text. By default, all characters are allowed. Call `DisallowChar()` for each character you want to prevent the BTextView from accepting, preferably when first setting up the object. Although declared as `uint32`, aChar must be a character encoded in a single byte; it can't be a 16-bit Unicode value or a multibyte UTF-8 string.

  `AllowChar()` reverses the effect of `DisallowChar()`.

  Alternatively, and for more control over the context in which characters are accepted or rejected, you can implement an `InsertText()` function for the BTextView. `InsertText()` is called for all insertions, including each character the user types, all text the user drags to the BTextView, and all attempts to paste from the clipboard.

  See also: `AcceptsChar()`

  ### DoesAutoindent() see SetAutoindent()

  ### DoesUndo() see SetDoesUndo()

  ### DoesWordWrap() see SetWordWrap()

  ### Draw()

            virtual void Draw(BRect updateRect)

  Draws the text on-screen. The Interface Kit calls this function for you whenever the text display needs to be updated--for example, whenever the user edits the text, enters new characters, or scrolls the contents of the BTextView.

  See also: `BView::Draw()`

  ### FindWord()

            virtual void FindWord(int32 offset, int32 *start, int32 *finish)

  Looks for a sequence of characters that qualifies as a word--that is, a sequence that the user can double-click to select--that includes the character at offset. This function places the offset of the word's first character in the variable that start refers to and the offset following the last character in the word in the variable that finish refers to. If the offset character can't be part of a word, the start and finish offsets will be identical.

  As implemented, this function allows the user to select a group of similar characters with a double-click. For example, in the following line of malformed text,

         "You  what!!?"

  it would allow the user to select the words "You" and "what," the group of spaces between the words, and the group of punctuation marks at the end.

  The function also defines similar groups of Japanese characters that can be selected together.

  ### FrameResized()

            virtual void FrameResized(float width, float height)

  Overrides the BView version of this function to reset the ranges of the BTextView's scroll bars and to update the sizes of their proportional knobs whenever the size of the BTextView changes.

  See also: `BView::FrameResized()`

  ### GetDragParameters()

            virtual void GetDragParameters(BMessage *drag,
               BBitmap **bitmap,
               BPoint *point,
               BHandler **handler)

  `GetDragParameters()` is called when a drag session is initiated. The values that it retrieves (by reference in the arguments) are passed on to `BView::DragMessage()`. If you don't supply a bitmap (if you set *bitmap to `NULL`), the outline rectangle version of `DragMessage()` is used.

  ### GetSelection()

            void GetSelection(int32 *start, int32 *finish)

  Provides the current selection by writing the offset before the first selected character into the variable referred to by start and the offset after the last selected character into the variable referred to by finish. If no characters are selected, both offsets will record the position of the current insertion point.

  If the text isn't selectable, both offsets will be 0.

  See also: `Select()`

  ### GetText() see Text()

  ### GetTextRegion()

            void GetTextRegion(int32 start, int32 finish, BRegion *region) const

  Calculates the region where the run of characters beginning at the start offset and ending at the finish offset would be displayed within the BTextView's coordinate system, and modifies the BRegion object passed as the third argument, region, so that it represents that region.

  See also: `TextHeight()`

  ### GoToLine(), CountLines(), CurrentLine()

            void GoToLine(int32 index)

            int32 CurrentLine(void) const

            int32 CountLines(void) const

  `GoToLine()` moves the insertion point to the beginning of the line at index. The first line has an index of 0, the second line an index of 1, and so on. If the index is out-of-range, the insertion point is moved to the beginning of the line with the nearest in-range index--that is, to either the first or the last line.

  `CurrentLine()` returns the index of the line where the first character of the selection--or the character following the insertion point--is currently located.

  `CountLines()` returns how many lines of text the BTextView currently contains.

  Like other functions that change the selection, `GoToLine()` doesn't automatically scroll the display to make the new selection visible. Call `ScrollToSelection()` to be sure that the user can see the start of the selection.

  See also: `ScrollToSelection()`

  ### Highlight()

            inline void Highlight(int32 start, int32 finish)

  Highlights (or unhighlights) the characters between the start and finish offsets. This is the function that the BTextView calls to highlight and unhighlight the current selection. You don't need to call it yourself for this purpose. It's in the public API just in case you may need to highlight a range of text in some other circumstance.

  If the text is not currently highlighted, this function highlights it. But if the text is already highlighted, it unhighlights it. If you highlight some text, be sure to unhighlight it before the next editorial change; the BTextView will not do it for you.

  See also: `Select()`, `TextRegion()`

  ### Insert(), Delete()

            void Insert(const char *text, const text_run_array *runs = NULL)
            void Insert(const char *text, int32 length, const text_run_array *runs = NULL)
            void Insert(int32 offset, const char *text, int32 length, const text_run_array *runs = NULL)

            void Delete(void)
            void Delete(int32 start, int32 finish)

  `Insert()` adds length bytes of text to the BTextView--or if a length isn't specified, all the characters of the text string up to the null character that terminates it. The text is inserted at offset--or at the beginning of the current selection if an offset isn't specified. The current selection is not deleted and the insertion is not selected.

  The inserted characters are displayed in the fonts and colors specified in the accompanying runs array, provided the BTextView allows multiple character formats. If multiple formats aren't allowed, the runs array is ignored. If multiple formats are allowed but a runs array isn't provided, the insertion is displayed in the font and color in force at the point of insertion. This generally means the font and color of the first character of the selection, or of the character immediately preceding the offset character.

  Offsets in the runs array should describe the text being inserted; in other words, the first offset should be 0. See `SetRunArray()` for a description of the `text_run_array` structure.

  `Insert()` doesn't assume responsibility for the text data or the runs array. It copies the information it needs.

  `Delete()` removes the characters bounded by the start and finish offsets from the display and deletes them from the BTextView's text, without copying them to the clipboard. If the start and finish offsets are the same, nothing is deleted. If offsets are not provided, `Delete()` deletes the current selection.

  See also: `SetText()`, `Cut()`, `SetRunArray()`

  ### InsertText(), DeleteText()

            virtual void InsertText(const char *text,
                  int32 length,
                  int32 offset,
                  const text_run_array *runs)

            virtual void DeleteText(int32 start, int32 finish)

  These protected functions are the vehicles through which the BTextView performs every insertion and deletion of text (with one exception). You can augment them in a subclass to take note of pending changes to the text, and to modify or prevent the change.

  Don't call `Insert()`, `Delete()` or any other high-level text-manipulating function in your implementation.

  `InsertText()` adds length bytes of text to the BTextView, inserting it at offset within the text buffer. The font and color of the inserted characters may be described by an accompanying runs array. If the BTextView doesn't support multiple character formats, the runs array is ignored. If multiple formats are supported but the runs array is `NULL`, the text is displayed in the font and color of the character preceding offset (or of the first character, if offset is 0.)

  The offsets in the runs data structure are relative to the inserted text; that is, the first offset in the array is 0, not offset.

  `InsertText()` is called for every insertion, except one. The exception occurs when `SetText()` takes text from a file; in this case the text goes directly from the file to the BTextView; it's not stored in a temporary buffer while `InsertText()` is called.

  `DeleteText()` removes the text bounded by the start and finish offsets. It fails if the offsets don't differ, or if the finish offset isn't greater than the start offset. This function is called for every deletion.

  See also: `Insert()`, `Delete()`

  ### IsEditable() see MakeEditable()

  ### IsSelectable() see MakeSelectable()

  ### KeyDown()

            virtual void KeyDown(const char *bytes, int32 numBytes)

  Enters text at the current selection in response to the user's typing. This function is called from the window's message loop for every report of a key-down event--typically once for every character the user types. However, it does nothing unless the BTextView is the focus view and the text it contains is editable.

  If the character encoded in the bytes string is an editing instruction, `KeyDown()` takes the appropriate action:

  - If the character is from one of the arrow keys (`B_UP_ARROW`, `B_LEFT_ARROW`, `B_DOWN_ARROW`, or `B_RIGHT_ARROW`), it extends the selection or moves the insertion point in the appropriate direction, depending on the modifiers

  - If the character is `B_BACKSPACE` or `B_DELETE`, it deletes the current selection--or the character preceding or following the current insertion point.

  - If the character comes from one of the paging keys (`B_HOME`, `B_END`, `B_PAGE_UP`, or `B_PAGE_DOWN`), it scrolls the display.

  Otherwise, it checks whether the character was registered as unacceptable (by `DisallowChar()`). If not disallowed, it calls the `InsertText()` hook function to enter the character into the text and display it. Derived classes can preview about-to-be-inserted characters by overriding `InsertText()`.

  See also: `BView::KeyDown()`, `InsertText()`, `DisallowChar()`

  ### LineAt(), PointAt(), OffsetAt()

            int32 LineAt(int32 offset) const
            int32 LIneAt(BPoint point) const

            BPoint PointAt(int32 offset, float *height = NULL) const

            int32 OffsetAt(BPoint point) const
            int32 OffsetAt(int32 index) const

  These functions translate between coordinate values, text offsets, and line indices. `LineAt()` returns the index of the line containing the character at offset in the text, or the line located at the specified point in the BTextView's coordinate system. Line indices begin at 0.

  `PointAt()` returns the coordinate location of the character at offset. The point is the left top corner of a rectangle enclosing the character and is stated in the BTextView's coordinate system. The x-coordinate of the point is the position on the baseline where the character is (or would be) drawn; its y-coordinate is the top of the line where the offset character is located. If a height argument is provided, `PointAt()` returns the height of the line by reference.

  `OffsetAt()` returns the offset to the character that begins the index line, or to the character displayed at point.

  ### LineHeight(), TextHeight()

            float LineHeight(int32 index = 0) const

            float TextHeight(int32 firstIndex, int32 lastIndex) const

  `LineHeight()` returns the height of the line of text at index, or the first line if an index isn't specified. Line indices begin at 0. The height is stated in coordinate units and depends on the font. It's the sum of how far characters can ascend above and descend below the baseline, plus the amount of leading that separates lines. If more than one font is used on the line, the ascent is taken from the tallest font and the descent and leading from the deepest.

  `TextHeight()` returns the height of the set of lines from firstIndex through lastIndex.

  Both functions reset out-of-range indices to be in-range--that is, to the index of the first or last line.

  See also: `BFont::GetHeight()`

  ### LineWidth()

            float LineWidth(int32 index = 0) const

  Returns the width of the line at index--or, if no index is given, the width of the first line. The value returned is the sum of the widths (in coordinate units) of all the characters in the line, from the first through the last, including tabs and spaces. Line indices begin at 0.

  If the index passed is out-of-range, it's reinterpreted to be the nearest in-range index--that is, as the index to the first or the last line.

  See also: `BFont::StringWidth()`

  ### MakeEditable(), IsEditable()

            void MakeEditable(bool flag = true)

            bool IsEditable(void) const

  The first of these functions sets whether the user can edit the text displayed by the BTextView; the second returns whether or not the text is currently editable. Text is editable by default.

  When text is editable but not selectable, the user can enter and delete text at the insertion point, but can't select text to make changes to more than one character at a time.

  See also: `MakeSelectable()`

  ### MakeFocus()

            virtual void MakeFocus(bool flag = true)

  Overrides the BView version of `MakeFocus()` to highlight the current selection when the BTextView becomes the focus view (when flag is `true`) and to unhighlight it when the BTextView no longer is the focus view (when flag is `false`). However, the current selection is highlighted only if the BTextView's window is the current active window.

  This function is called for you whenever the user's actions make the BTextView become the focus view, or force it to give up that status.

  See also: `BView::MakeFocus()`, `MouseDown()`

  ### MakeResizable(), IsResizable()

            void MakeResizable(bool resizable, BView *containerView = NULL)

            bool IsResizable(void) const

  `MakeResizable()` gives the BTextView the ability to automatically resize itself to fit its contents if the resizable flag is `true`, and takes away that ability if the flag is `false`. `IsResizable()` returns whether the BTextView is currently resizable.

  The frame rectangle and text rectangle of a resizable BTextView automatically grow and shrink to exactly enclose all the characters entered by the user. The object should display just a single line of text (the resizing is horizontal); if the resizable flag is `true`, `MakeResizable()` turns off line wrapping. The text can be aligned to the left, right, or center of the text rectangle.

  The containerView is a view that draws a border around the text (like a BScrollView object) and is the parent of the BTextView; it's the view that's resized to fit the text. The BTextView's resizing mode should be such that it will be resized in tandem with the container (for example, `B_FOLLOW_LEFT_RIGHT` or `B_FOLLOW_ALL_SIDES`). However, if the containerView is `NULL`, as it is by default, the BTextView itself is resized to fit the text.

  If the resizable flag is `false`, the containerView argument is ignored.

  This resizing mechanism is an alternative to the automatic resizing behavior provided in the BView class. It triggers resizing on the user's entry of text, not on a change in the parent view's size. The two schemes are incompatible; the container view (or the BTextView, if there is no container) should not automatically resize itself when its parent is resized.

  See also: `SetAlignment()`

  ### MakeSelectable(), IsSelectable()

            void MakeSelectable(bool flag = true)

            bool IsSelectable(void) const

  The first of these functions sets whether it's possible for the user to select text displayed by the BTextView; the second returns whether or not the text is currently selectable. Text is selectable by default.

  When text is selectable but not editable, the user can select one or more characters to copy to the clipboard, but can't position the insertion point (an empty selection), enter characters from the keyboard, or paste new text into the view.

  See also: `MakeEditable()`

  ### MaxBytes() see SetMaxBytes()

  ### MessageReceived()

            virtual void MessageReceived(BMessage *message)

  Augments the BView version of `MessageReceived()` to handle scripting requests, dropped data, and four editing messages--`B_CUT`, `B_COPY`, `B_PASTE`, and `B_SELECT_ALL`.

  If the message was dragged and dropped on the BTextView and it contains `B_MIME_TYPE` data under the name "text/plain", this function inserts the new text at the point where it was dropped--but only if `AcceptsDrop()` returns `true` for the message.

  This function handles `B_CUT`, `B_COPY`, `B_PASTE`, and `B_SELECT_ALL` messages by calling the `Cut()`, `Copy()`, `Paste()`, and `SelectAll()` functions. A BTextView will get these messages, even if the application doesn't send them, when it's the focus view and the user uses the Command-x, Command-c, Command-v, and Command-a shortcuts. See Shortcuts and Menu Items in the class overview for information on how to set up compatible Cut, Copy, Paste, and Select All menu items.

  To inherit this functionality, `MessageReceived()` functions implemented by derived classes should be sure to call the BTextView version.

  See also: `BView::MessageReceived()`, `AcceptsPaste()`, `BInvoker::SetMessage()`, `BInvoker::SetTarget()`, `InsertText()`

  ### MouseDown()

            virtual void MouseDown(BPoint point)

  Selects text, drags text, and positions the insertion point in response to the user's mouse actions. If the BTextView isn't already the focus view for its window, this function calls `MakeFocus()` to make it the focus view.

  `MouseDown()` is called for each mouse-down event that occurs inside the BTextView's frame rectangle.

  See also: `BView::MouseDown()`, `MakeFocus()`

  ### MouseMoved()

            virtual void MouseMoved(BPoint point, uint32 transit, BMessage *message)

  Responds to `B_MOUSE_MOVED` messages by changing the cursor to the standard I-beam image for editing text whenever the cursor enters the view and by resetting it to the standard hand image when the cursor exits the view. The cursor is changed to an I-beam for text that is selectable or editable, but only if the BTextView is the current focus view in the active window. However, when the cursor moves over the current selection, this function changes it from the I-beam back to the standard hand image. This is done to indicate that it's possible to drag and drop the current selection.

  If a message is being dragged to the BTextView, this function tests it see whether it contains textual data and tracks it to its destination.

  See also: `BView::MouseMoved()`, `AcceptsDrop()`

  ### OffsetAt() see LineAt()

  ### PointAt() see LineAt()

  ### Paste() see Cut()

  ### Pulse()

            virtual void Pulse(void)

  Turns the caret marking the current insertion point on and off when the BTextView is the focus view in the active window. `Pulse()` is called by the system at regular intervals.

  This function is first declared in the BView class.

  See also: `BView::Pulse()`

  ### ResolveSpecifier()

            virtual BHandler *ResolveSpecifier(BMessage *message, int32 index, BMessage *specifier, int32 command, const char *property)

  Resolves specifiers for the "Text", "text_run_array", and "selection" properties. See Scripting Support in the class overview and "Scripting" in The Application Kit chapter for more information.

  See also: `BHandler::ResolveSpecifier()`

  ### ScrollToOffset(), ScrollToSelection()

            virtual void ScrollToOffset(int32 offset)

            void ScrollToSelection(void)

  These functions scroll the text so that the character at offset--or the character that begins the current selection--is within the visible region of the view. If the BTextView is equipped with scroll bars, the BScrollBar objects are informed so they can update themselves.

  See also: `BView::ScrollTo()`

  ### Select()

            virtual void Select(int32 start, int32 finish)

  Selects the characters from start up to finish, where start and finish are offsets into the BTextView's text. If start and finish are the same, the selection will be empty (an insertion point). See Offsets in the class overview for a discussion of the constraints on the offset arguments.

  Normally, the selection is changed by the user. This function provides a way to change it programmatically.

  If the BTextView is the current focus view in the active window, `Select()` highlights the new selection (or displays a blinking caret at the insertion point). However, it doesn't automatically scroll the contents of the BTextView to make the new selection visible. Call `ScrollToSelection()` to be sure that the user can see the start of the selection.

  See also: `Text()`, `GetSelection()`, `ScrollToSelection()`, `GoToLine()`, `MouseDown()`

  ### SelectAll()

            void SelectAll(void)

  Selects the entire text of the BTextView, and highlights it if the BTextView is the current focus view in the active window.

  See also: `Select()`

  ### SetAlignment(), Alignment()

            void SetAlignment(alignment where)

            alignment Alignment(void) const

  These functions set the way text is aligned within the text rectangle and return the current alignment. Three settings are possible:

  `B_ALIGN_LEFT` | Each line is aligned at the left boundary of the text rectangle.
  `B_ALIGN_RIGHT` | Each line is aligned at the right boundary of the text rectangle.
  `B_ALIGN_CENTER` | Each line is centered between the left and right boundaries of the text rectangle.

  The default is `B_ALIGN_LEFT`.

  ### SetAutoindent(), DoesAutoindent()

            void SetAutoindent(bool flag)

            bool DoesAutoindent(void) const

  These functions set and return whether a new line of text is automatically indented the same as the preceding line. When set to `true` and the user types Return at the end of a line that begins with tabs or spaces, the new line will automatically indent past those tabs and spaces to the position of the first visible character.

  The default value is `false`.

  ### SetColorSpace(), ColorSpace()

            void SetColorSpace(color_space space)

            color_space ColorSpace(void) const

  These functions set and return the color space of the offscreen bitmap that buffers the drawing the BTextView does. The default color space is `B_CMAP8`.

  See also: the BBitmap class

  ### SetFontAndColor(), GetFontAndColor()

            void SetFontAndColor(int32 start, int32 finish,
               const BFont *font, uint32 properties = B_FONT_ALL, rgb_color *color = NULL)
            void SetFontAndColor(const BFont *font, uint32 properties = B_FONT_ALL, rgb_color *color = NULL)

            void GetFontAndColor(int32 offset, BFont *font, rgb_color *color = NULL) const
            void GetFontAndColor(BFont *font, uint32 *sameProperties,
               rgb_color *color = NULL, bool *sameColor = NULL) const

  These functions set and get the font and color used to display the text. If the BTextView supports multiple character formats, `SetFontAndColor()` sets the font and color of the characters bounded by the start and finish offsets. If no offsets are given, it sets the font and color of the current selection. However, if multiple character formats are not supported, `SetFontAndColor()` ignores the offsets and formats the entire text.

  `SetFontAndColor()` works like BView's `SetFont()` function. It sets the font to the attributes of the font BFont object that are enumerated by the properties mask. The mask is formed by combining the following constants:

  `B_FONT_FAMILY_AND_STYLE`
  `B_FONT_SIZE`
  `B_FONT_SHEAR`
  `B_FONT_ROTATION`
  `B_FONT_SPACING`
  `B_FONT_ENCODING`
  `B_FONT_FACE`
  `B_FONT_FLAGS`

  In addition, `B_FONT_ALL` is a shorthand for all properties of the specified font. However, the BTextView modifies the font to ensure that:

  - Characters are not rotated.
  - Antialiasing is not disabled.
  - The spacing mode is `B_BITMAP_SPACING`.
  - The character encoding is UTF-8 (`B_UNICODE_UTF8`).

  If the font argument is `NULL`, the font is not set and the properties mask is ignored.

  The color of the characters is set by a pointer to an `rgb_color` structure. If the pointer is `NULL`, as it is by default, the color is not set.

  `GetFontAndColor()` gets the font and color used to display the character at offset. It modifies the font BFont object and the color `rgb_color` structure so that they describe the font and color of the character.

  If an offset isn't specified, `GetFontAndColor()` looks at the current selection. It provides a font and color description of the first character of the selection--or the character at the insertion point if the selection is empty. It also modifies that variable that the sameProperties argument refers to so that it lists all the font properties that are uniform for all characters in the selection. Similarly, it indicates, in the variable that sameColor refers to, whether all the characters in the selection are displayed in the same color.

  See also: `BView::SetFont()`

  ### SetMaxBytes(), MaxBytes()

            void SetMaxBytes(int32 max)

            int32 MaxBytes(void) const

  These functions set and return the maximum number of bytes that the BTextView can accept. The default is the maximum number of bytes that can be designated by a signed 32-bit integer, a number sufficiently large to accommodate all uses of a BTextView. Use this function only if you need to restrict the number of characters that the user can enter in a text field.

  Note that these functions count bytes, not characters.

  ### SetRunArray(), RunArray()

            void SetRunArray(int32 start, int32 finish, const text_run_array *runs)

            text_run_array *RunArray(int32 start, int32 finish, int32 *length = NULL)

  These functions set and return the font and color formats of all the characters bounded by the start and finish offsets. The formats are described by a `text_run_array` structure, which has the following fields:

  int32 `count
  ` The number of `text_run` structures in the array.

  text_run `runs`[1]
  A structure describing the font and color formats in effect at a particular offset in the BTextView's text.

  The `text_run` structure describes a run of characters that share the same font and color formats. It has three fields:

  int32 `offset
  ` An offset to the first byte of a character in the text buffer. The text run begins with this character; it continues until another run begins.

  BFont `font
  ` The font that's used to display the run of characters beginning at the specified offset.

  rgb_color `color
  ` The color that's used to display the run of characters beginning at the specified offset.

  The first offset of the first `text_run` in the array passed to `SetRunArray()` should be 0; the array returned by `RunArray()` also begins at offset 0.

  If the BTextView doesn't support multiple character formats, `SetRunArray()` ignores the start and finish offsets and sets the entire text to the font and color of the first `text_run` in the array. Similarly, `RunArray()` returns a `text_run_array` with one `text_run` describing the entire text.

  `RunArray()` returns a pointer to memory that it allocated (using `malloc()`). It puts the number of bytes that it allocated in the variable that the length argument points to. Although `RunArray()` allocated the memory, the caller is responsible for freeing it when the returned `text_run_array` is no longer needed.

  `SetRunArray()` doesn't assume responsibility for the runs data it's passed; it's up to the caller to free it.

  See also: `SetFontAndColor()`

  ### SetStylable(), IsStylable()

            void SetStylable(bool stylable)

            bool IsStylable(void) const

  `SetStylable()` sets whether the BTextView permits multiple character formats. If the stylable flag is `true`, the functions that set the font and color of the text can apply to particular characters in the text buffer. If the flag is `false`, those functions apply only to the entire text. When `SetStylable()` is called to turn off support for multiple formats, all the text is reformatted in the font and color of the first character.

  `IsStylable()` returns whether multiple formats are permitted. By default, they're not.

  See also: `SetFontAndColor()`, `SetRunArray()`

  ### SetTabWidth(), TabWidth()

            void SetTabWidth(float width)

            float TabWidth(void) const

  These functions set the distance between tab stops to width coordinate units and return the current tab width. Tabs cannot be removed nor can they be individually set; all tabs have a uniform width. The default tab width is 28.0 coordinate units.

  ### SetText()

            void SetText(const char *text, int32 length, const text_run_array *runs = NULL)
            void SetText(const char *text, const text_run_array *runs = NULL)
            void SetText(BFile *file, int32 offset, int32 length,
               const text_run_array *runs = NULL)

  Removes any text currently in the BTextView and copies new text from a text buffer or from a file to replace it. This function copies length bytes of text from the buffer--or all the bytes in the buffer, up to the null character, if a length isn't specified. Or it copies length bytes from the file beginning at the offset byte. If the text or file is `NULL` or length is 0, it empties the BTextView without replacing the text.

  If a runs `text_run_array` is provided, it will be used to set the font and color formats of the new text--provided that the BTextView permits multiple character formats. If not, the runs array is ignored.

  The BTextView doesn't assume ownership of the text buffer, the file, or the runs array; you can delete them when `SetText()` returns.

  Text taken from a file is inserted directly into the text, bypassing the `InsertText()` function. In other words, you won't receive an `InsertText()` notification for text taken from a file.

  This function is typically used to set the text initially displayed in the view. If the BTextView is already attached to a window, it's updated to show its new contents.

  See also: `Text()`, `TextLength()`

  ### SetTextRect(), TextRect()

            void SetTextRect(BRect rect)

            BRect TextRect(void) const

  `SetTextRect()` makes rect the BTextView's text rectangle--the rectangle that locates where text is placed within the view. This replaces the text rectangle originally set in the BTextView constructor. The layout of the text is recalculated to fit the new rectangle, and the text is redisplayed.

  `TextRect()` returns the current text rectangle.

  See also: the BTextView constructor

  ### SetWordWrap(), DoesWordWrap()

            void SetWordWrap(bool flag)

            bool DoesWordWrap(void) const

  These functions set and return whether the BTextView wraps lines on word boundaries, thus pushing entire words that don't fit at the end of a line to the next line. When word wrapping is turned on, the BTextView calls `CanEndLine()` to determine exactly where a line can break. If word wrapping is off, lines break only on a newline character (where the user types Return).

  By default, word wrapping is turned on (`DoesWordWrap()` returns `true`).

  See also: `SetTextRect()`, `CanEndLine()`

  ### TabWidth() see SetTabWidth()

  ### Text(), GetText(), ByteAt()

            const char *Text(void) const

            void GetText(int32 offset, int32 length, char *buffer) const

            uchar ByteAt(int32 offset) const

  These functions reveal the text contained in the BTextView.

  `Text()` returns a pointer to the text, which may be a pointer to an empty string if the BTextView is empty. The returned pointer can be used to read the text, but not to alter it (use `SetText()`, `Insert()`, `Delete()`, and other BTextView functions to do that).

  `GetText()` copies up to length bytes of the text into buffer, beginning with the byte at offset, and adds a null terminator ('\\0'). Fewer than length bytes are copied if there aren't that many between the specified offset and the end of the text. This function doesn't make any attempt to ensure that only full character specifications are copied; it's up to the caller to make sure that a character begins at offset and that the last byte copied isn't in the middle of a multibyte character. The results won't be reliable if the offset is out-of-range.

  `ByteAt()` returns the byte located at offset. The offset doesn't have to be to the first byte of a character.

  The pointer that `Text()` returns is to the BTextView's internal representation of the text. When it returns, the text string is guaranteed to be null-terminated and without gaps. However, the BTextView may have had to manipulate the text to get it in that condition. Therefore, there may be a performance price to pay if `Text()` is called frequently. If you're going to copy the text, it's more efficient to have `GetText()` do it for you. If you're going to index into the text, it may be more efficient to call `ByteAt()`.

  The pointer that `Text()` returns may no longer be valid after the user or the program next changes the text. Even if valid, the string may no longer be null-terminated and gaps may appear.

  See also: `TextLength()`

  ### TextHeight() see LineHeight()

  ### TextLength()

            int32 TextLength(void) const

  Returns the number of bytes of text data the BTextView currently contains--the number of bytes in the string that `Text()` returns (not counting the null terminator).

  See also: `Text()`, `SetMaxBytes()`

  ### TextRect() see SetTextRect()

  ### SetDoesUndo(), DoesUndo(), UndoState(), Undo(), undo_state

            void SetDoesUndo(bool sayIt)

            bool DoesUndo(void) const

            undo_state UndoState(bool *isRedo) const

            virtual void Undo(BClipboard *clipboard)

            enum undo_state {}

  These functions and enum comprise BTextView's undo world. The operations that BTextView can undo are described in the `undo_state` table, below. The default undo mechanism is one operation deep: Udoing undoes the previous (undo-able) operation; a second (immediate) undo redoes the operation.

  You call `SetDoesUndo()` to enable or disable the undo machinery for this object. By default, undo is enabled. The ability to undo is also controlled by the object's editability (`MakeEditable()`), but this is a tautology, since in order to have something to undo you have to have been able to edit the object in the first place.

  `DoesUndo()` tells you whether the object is "undoable" as set by `SetDoesUndo()`. It doesn't take editability into consideration.

  UndoState() tells you what the previous action was (as represented by the constants listed below). This is the action that will be undone if the object is told to undo. The isRedo value that's returned by reference is set to `true` if the previous action occurred because of an undo.

  Constant | Meaning
  `B_UNDO_UNAVAILABLE` | Nothing to undo
  `B_UNDO_TYPING` | Text was inserted or deleted
  `B_UNDO_CUT` | Selection was cut
  `B_UNDO_PASTE` | Text was pasted
  `B_UNDO_CLEAR` | Selection was cleared
  `B_UNDO_DROP` | Message was dropped

  The `Undo()` hook function is called when the BTextView receives a `B_UNDO` message. (By default, `B_UNDO` is bound to the window's Command+z shortcut; Undo menu items need to set up the binding explicitly.) The clipboard argument is a pointer to the `be_clipboard`; if you're using a custom clipboard in your BTextView subclass, you should pass along your clipboard when you invoke the inherited version of `Undo()`.

  Don't try to do too much in a subclass implementation of Undo(). In particular, you probably won't get too far if you're trying to "broaden" the undo tree.

  ### Undo() see SetDoesUndo()

  ### UndoState() see SetDoesUndo()

  ### WindowActivated()

            virtual void WindowActivated(bool flag)

  Highlights the current selection when the BTextView's window becomes the active window (when flag is `true`)--provided that the BTextView is the current focus view--and removes the highlighting when the window ceases to be the active window (when flag is `false`).

  If the current selection is empty (if it's an insertion point), it's highlighted by turning the caret on and off (blinking it).

  The Interface Kit calls this function for you whenever the BTextView's window becomes the active window or it loses that status.

  See also: `BView::WindowActivated()`, `MakeFocus()`

  ## Archived Fields

  The `Archive()` function adds the following fields to its BMessage argument:

  Field | Type code | Meaning
  "_text" | `B_STRING_TYPE` | The BTextView's text.
  "_align" | `B_INT32_TYPE` | The text `alignment`.
  "_tab" | `B_FLOAT_TYPE` | The tab width.
  "_col_sp" | `B_INT32_TYPE` | Color space.
  "_trect" | `B_RECT_TYPE` | The text rectangle.
  "_max" | `B_INT32_TYPE` | The maximum size (a la `SetMaxBytes()`).
  "_sel" (array) | `B_INT32_TYPE` | index 0: selection start; index 1: selection end
  "_dis_ch" (array) | `B_RAW_TYPE` | Disallowed characters.
  "_runs" | `B_RAW_TYPE` | Flattened run array.
  "_stylable" | `B_BOOL_TYPE` | `true` == is stylable.
  "_auto_in" | `B_BOOL_TYPE` | `true` == autoindent on
  "_wrap" | `B_BOOL_TYPE` | `true` == word wrapping on
  "_nsel" | `B_BOOL_TYPE` | `true` == not selectable
  "_nedit" | `B_BOOL_TYPE` | `true` == not editable

  Some of these fields may not be present if the setting they represent isn't used, or is the default value. For example, if word wrapping is off, the "_wrap" field won't be found in the archive.

  The Be Book, in lovely HTML, for BeOS Release 3.

  Copyright © 1998 Be, Inc. All rights reserved.

  Last modified March 26, 1998.