Adventures in TextInputCanvas : 5

OK So we left off last time with some rudimentary text input - you could pound keys and they’d get entered. But no newlines enters, etc and certainly not text selection, cursor movement by keyboard etc

And this is where the DoCommand event comes into play.
There are a LOT of things that DoCommand is used for.
If, In the DoCommand event you type

    select case self.

and press tab after the period you will see an enormous list of constants named cmd something. This is only a partial list

There’s no nice simple way to quickly get all these in the IDE
But you can get the from the TextnputCanvas.cpp source file on github starting at line 103. You’ll need to do some replacements but thats the whole list (I’ll incldue the list at the end of this post)
The nice thing is that each “group” says where in the Apple documentation the items come from so you can use that as something of a reference as well. You can read the various sections and entries about what each is supposed to do.

For now we’re only going to handle a couple simple commands :slight_smile:
So lets add, to the DoCommand event handler,

Select case command
  Case CmdInsertNewline
  Case CmdInsertNewlineIgnoringFieldEditor
end select

CmdInsertNewLine is straightforward enough. You need to insert a newline (or however you’re representing a newline). In our implementation we’ll just use a EndOfLine. Careful if you’re doing this on Windows where an EndOfLine is 2 characters as that could cause some measuring issues down the road since TextInputCanvas seems to assume that and end of line is one character with some events and measuring. It doesnt have to be but some things will seem that way.

CmdInsertNewLineIgnoringFieldEditor is, in typical Apple fashion, woefully undocumented now.
The explanation of what a Field editor is is too long for this small article but you can read about it here.

CmdInsertNewLine is sent when the text input canvas has focus and you press enter OR return. CmdInsertNewLineIgnoringFieldEditor is sent when the field has focus and you press Option-Enter or Option-Return on macOS.
Suffice to say that, for our purposes, both inserts of a newline should be handled similarly and should insert an EndOfLine and cause a redraw.

And there is one more that we should probably handle similarly : CmdInsertLineBreak.
This one is sent on macOS when a Ctrl-Return or Ctrl-Enter is pressed.

For each of these we’re just going to add an EndOfline and see how things go

for now our select case in DoCommand looks like

select case command

Case CmdInsertNewline
  mTextBuffer = mTextBuffer + EndOfLine
Case CmdInsertNewlineIgnoringFieldEditor
  mTextBuffer = mTextBuffer + EndOfLine
Case CmdInsertLineBreak
  mTextBuffer = mTextBuffer + EndOfLine

end select  

And now we can type like mad, and press enter, return etc and get new lines.

Onwards !

The complete list of commands that can be sent to the DoCommand Event of the TextInputCanvas

select case command
	// NSResponder: Selection movement and scrolling
case CmdMoveForward
case CmdMoveRight
case CmdMoveBackward
case CmdMoveLeft
case CmdMoveUp
case CmdMoveDown
case CmdMoveWordForward
case CmdMoveWordBackward
case CmdMoveToBeginningOfLine
case CmdMoveToEndOfLine
case CmdMoveToBeginningOfParagraph
case CmdMoveToEndOfParagraph
case CmdMoveToEndOfDocument
case CmdMoveToBeginningOfDocument
case CmdPageDown
case CmdPageUp
case CmdCenterSelectionInVisibleArea
	// NSResponder: Selection movement and scrolling
case CmdMoveBackwardAndModifySelection
case CmdMoveForwardAndModifySelection
case CmdMoveWordForwardAndModifySelection
case CmdMoveWordBackwardAndModifySelection
case CmdMoveUpAndModifySelection
case CmdMoveDownAndModifySelection
	// NSResponder: Selection movement and scrolling
case CmdMoveToBeginningOfLineAndModifySelection
case CmdMoveToEndOfLineAndModifySelection
case CmdMoveToBeginningOfParagraphAndModifySelection
case CmdMoveToEndOfParagraphAndModifySelection
case CmdMoveToEndOfDocumentAndModifySelection
case CmdMoveToBeginningOfDocumentAndModifySelection
case CmdPageDownAndModifySelection
case CmdPageUpAndModifySelection
case CmdMoveParagraphForwardAndModifySelection
case CmdMoveParagraphBackwardAndModifySelection

	// NSResponder: Selection movement and scrolling (added in 10.3)
case CmdMoveWordRight
case CmdMoveWordLeft
case CmdMoveRightAndModifySelection
case CmdMoveLeftAndModifySelection
case CmdMoveWordRightAndModifySelection
case CmdMoveWordLeftAndModifySelection

	// NSResponder: Selection movement and scrolling (added in 10.6)
case CmdMoveToLeftEndOfLine
case CmdMoveToRightEndOfLine
case CmdMoveToLeftEndOfLineAndModifySelection
case CmdMoveToRightEndOfLineAndModifySelection
	// NSResponder: Selection movement and scrolling
case CmdScrollPageUp
case CmdScrollPageDown
case CmdScrollLineUp
case CmdScrollLineDown

	// NSResponder: Selection movement and scrolling
case CmdScrollToBeginningOfDocument
case CmdScrollToEndOfDocument

	// NSResponder: Graphical Element transposition
case CmdTranspose
case CmdTransposeWords

	// NSResponder: Selections
case CmdSelectAll
case CmdSelectParagraph
case CmdSelectLine
case CmdSelectWord
	// NSResponder: Insertions and Indentations
case CmdIndent
case CmdInsertTab
case CmdInsertBacktab
case CmdInsertNewline
case CmdInsertParagraphSeparator
case CmdInsertNewlineIgnoringFieldEditor
case CmdInsertTabIgnoringFieldEditor
case CmdInsertLineBreak
case CmdInsertContainerBreak
case CmdInsertSingleQuoteIgnoringSubstitution
case CmdInsertDoubleQuoteIgnoringSubstitution
	// NSResponder: Case changes
case CmdChangeCaseOfLetter
case CmdUppercaseWord
case CmdLowercaseWord
case CmdCapitalizeWord
	// NSResponder: Deletions
case CmdDeleteForward
case CmdDeleteBackward
case CmdDeleteBackwardByDecomposingPreviousCharacter
case CmdDeleteWordForward
case CmdDeleteWordBackward
case CmdDeleteToBeginningOfLine
case CmdDeleteToEndOfLine
case CmdDeleteToBeginningOfParagraph
case CmdDeleteToEndOfParagraph
case CmdYank
	// NSResponder: Completion
case CmdComplete
	// NSResponder: Mark/Point manipulation
case CmdSetMark
case CmdDeleteToMark
case CmdSelectToMark
case CmdSwapWithMark
	// NSResponder: Cancellation
case CmdCancelOperation

	// NSResponder: Writing Direction
case CmdMakeBaseWritingDirectionNatural
case CmdMakeBaseWritingDirectionLeftToRight
case CmdMakeBaseWritingDirectionRightToLeft
case CmdMakeTextWritingDirectionNatural
case CmdMakeTextWritingDirectionLeftToRight
case CmdMakeTextWritingDirectionRightToLeft

	// Not part of NSResponder, something custom we need for Windows
case CmdToggleOverwriteMode
case CmdCopy
case CmdCut
case CmdPaste
case CmdUndo