Before reading this sample, review the Input sample MouseInteractors for more information on the input system.
TTextView's basic operation is somewhat incompatible with disjoint selections, and no attempt has been made here to address this. Most notably, deleting text with the backspace key only deletes the first range of the selection; and holding down the Shift key while clicking on the first or only range of the selection will start dragging the selected text, rather than extending the selection.
CustomTextSelectorMain.C differs from previous text editing samples only in that it instantiates TSampleTextView instead of TSimpleTextView.
TSampleSelectTextInteractor, defined in SampleSelectTextInteractor.h and SampleSelectTextInteractor.C, derives from TSimpleSelectTextInteractor only because this is required by the interface of HandleCreateSelectTextInteractor. In all significant respects it is a complete replacement for that class and uses no functionality of that class.
The abstract class TSelectState, and the concrete classes TSetSelectState, TExtendSelectState, TDisjointSelectState and TExtendDisjointSelectState are implementation details of this sample and have no corellary in the standard CommonPoint(TM) classes. They are used to encapsulate the state-specific information used during different kinds of interaction. The interactor creates a specific instance of TSelectState in its Setup member function, and in MouseDown and MouseMoved uses this object to determine the new selection, if any.
TSelectState is defined in SampleSelectTextInteractor.h and SampleSelectTextInteractor.C. TSetSelectState and TExtendSelectState are defined in StandardSelectStates.h and StandardSelectState.C. TDisjointSelectState and TExtendDisjointSelectState are defined in DisjointSelectStates.h and DisjointSelectStates.C.
The select state constructor also instantiates a TTextChunkIterator based on the passed-in reference. The default reference (see the Setup member function of TSampleSelectTextInteractor) creates an empty iterator, and the select state is constructed so that an empty iterator defaults to character selection. Other standard iterators are word and sentence selection iterators, available via the static member function on TTextChunkIterator, defined in BreakWord.h. A reference is passed to the select state constructor rather than the iterator itself, because the TTextChunkIterator constructor requires a non-NIL pointer to the text, and this in turn requires the read entry--which does not exist until the select state constructor is called.
The interactor uses the member functions of TextView to convert the mouse location (in local coordinates) to an insertion offset, and to get and set the text selection. The interactor manages the selection as a TTextArea, and lets the view convert between this and its own derived classes of TTextSelection. This allows different views with different selection types to use the same interactor.
TTextArea can represent either an insertion offset or a text region. Although several useful set operations are only defined on regions, regions cannot be used for such operations because they may not contain ranges of zero length. So several member functions in the sample (for example, TSetSelectState::ExtendArea, TExtendDisjointSelectState ::Setup) must take care to test areas for special cases and direct the computations of the new area accordingly.