Squeak Class Documentation category index | class index  
 
TextMorph
  category: Morphic-Basic
  superclass: RectangleMorph
  subclasses: TextMorphForEditView StringMorphEditor EToyTextNode TextPlusMorph ShowEmptyTextMorph ClipboardMorph

TextMorphs support display of text with emphasis. They also support reasonable text-editing capabilities, as well as embedded hot links, and the ability to embed submorphs in the text.

Late in life, TextMorph was made a subclass of BorderedMorph to provide border and background color if desired. In order to keep things compatible, protocols have been redirected so that color (preferably textColor) relates to the text, and backgroundColor relates to the inner fill color.

Text display is clipped to the innerBounds of the rectangle, and text composition is normally performed within a rectangle which is innerBounds inset by the margins parameter.

If text has been embedded in another object, one can elect to fill the owner's shape, in which case the text will be laid out in the shape of the owner's shadow image (including any submorphs other than the text). One can also elect to have the text avoid occlusions, in which case it will avoid the bounds of any sibling morphs that appear in front of it. It may be necessary to update bounds in order for the text runaround to notice the presence of a new occluding shape.

The optional autoFitContents property enables the following feature: if the text contents changes, then the bounds of the morph will be adjusted to fit the minimum rectangle that encloses the text (plus any margins specified). Similarly, any attempt to change the size of the morph will be resisted if this parameter is set. Except...

If the wrapFlag parameter is true, then text will be wrapped at word boundaries based on the composition width (innerBounds insetBy: margins) width. Thus an attempt to resize the morph in autofit mode, if it changes the width, will cause the text to be recomposed with the new width, and then the bounds will be reset to the minimum enclosing rectangle. Similarly, if the text contents are changed with the wrapFlag set to true, word wrap will be performed based on the current compostion width, after which the bounds will be set (or not), based on the autoFitcontents property.

Yet to do:
Make a comprehensive control for the eyedropper, with border width and color, inner color and text color, and margin widths.

instance methods
  accessing
  asText
autoFit:
backgroundColor
backgroundColor:
borderWidth:
contents
contents:
contents:wrappedTo:
contentsAsIs:
contentsWrapped:
crAction
crAction:
currentDataValue
editor
fillStyle
fillStyle:
fontName:size:
getCharacters
getFirstCharacter
hasTranslucentColor
isAutoFit
isWrapped
margins
margins:
newContents:
setCharacters:
setFirstCharacter:
setNumericValue:
text
textColor
textColor:
textStyle
userString
wrapFlag:

  alignment
  centered
justified
leftFlush
rightFlush

  anchors
  acceptDroppingMorph:event:
addMorphFront:fromWorldPosition:
privateRemoveMorph:

  card & stack
  basicType
couldHoldSeparateDataForEachInstance
newContents:fromCard:
setNewContentsFrom:
variableDocks

  containment
  fillingOnOff
occlusionsOnOff
ownerChanged
privateOwner:
recognizerArena
setContainer:

  copying
  veryDeepFixupWith:
veryDeepInner:

  drawing
  debugDrawLineRectsOn:
drawNullTextOn:
drawOn:

  editing
  acceptContents
cancelEdits
chooseAlignment
chooseEmphasis
chooseEmphasisOrAlignment
chooseFont
chooseStyle
clearTypeIn
cornerStyle:
enterClickableRegion:
handleEdit:
handleInteraction:fromEvent:
handleKeystroke:
handleMouseMove:
handlesKeyboard:
handlesMouseDown:
hasFocus
hasUnacceptedEdits:
keyStroke:
keyboardFocusChange:
mouseDown:
mouseMove:
mouseUp:
passKeyboardFocusTo:
xeqLinkText:withParameter:

  genie-dispatching
  gestureHandler
handleGesture:
lastGesture
lastGesture:
setAlignment:

  genie-processing
  defaultGestureDictionaryOrName

  geometry
  areasRemainingToFill:
bounds
container
containsPoint:
defaultLineHeight
extent:
goBehind
layoutChanged
minimumExtent
privateMoveBy:
textBounds

  initialization
  beAllFont:
configureForKids
copy
defaultColor
initialize
releaseCachedState
setTextStyle:
string:fontName:size:
string:fontName:size:wrap:

  linked frames
  addPredecessor:
addSuccessor:
firstCharacterIndex
firstInChain
isLinkedTo:
lastCharacterIndex
predecessor
recomposeChain
startingIndex
successor
withSuccessorsDo:

  menu
  addCustomMenuItems:hand:
autoFitOnOff
autoFitString
changeMargins:
changeTextColor
followCurve
reverseCurveDirection
setCurveBaseline:
shiftedYellowButtonActivity
wrapOnOff
wrapString
yellowButtonActivity

  object fileIn
  convertToCurrentVersion:refStream:

  printing
  fullPrintOn:

  private
  adjustLineIndicesBy:
clippingRectangle
composeToBounds
compositionRectangle
delete
fit
installEditor
installEditorToReplace:
loadCachedState
paragraph
paragraphClass
predecessor:successor:
predecessorChanged
releaseEditor
releaseParagraph
releaseParagraphReally
selectionChanged
setDefaultContentsIfNil
setPredecessor:
setSuccessor:
text:textStyle:
text:textStyle:wrap:color:predecessor:successor:
updateFromParagraph
updateReferencesUsing:
wouldAcceptKeyboardFocusUponTab

  scripting access
  getAllButFirstCharacter
getNumericValue
setAllButFirstCharacter:

class methods
  class initialization
  initialize

  parts bin
  authoringPrototype
borderedPrototype
descriptionForPartsBin
exampleBackgroundField
exampleBackgroundLabel
fancyPrototype
supplementaryPartsDescriptions

  scripting
  additionsToViewerCategories

  user interface
  includeInNewMorphMenu

instance methods
  accessing top  
 

asText


 

autoFit:


 

backgroundColor


 

backgroundColor:


 

borderWidth:


 

contents


 

contents:


 

contents:wrappedTo:

Accept new text contents. Lay it out, wrapping to width.
Then fit my height to the result.


 

contentsAsIs:

Accept new text contents with line breaks only as in the text.
Fit my width and height to the result.


 

contentsWrapped:

Accept new text contents. Lay it out, wrapping within my current width.
Then fit my height to the result.


 

crAction

Return the action to perform when encountering a CR in the input


 

crAction:

Return the action to perform when encountering a CR in the input


 

currentDataValue

Answer the current data value held by the receiver


 

editor

Return my current editor, or install a new one.


 

fillStyle

Return the current fillStyle of the receiver.


 

fillStyle:

Set the current fillStyle of the receiver.


 

fontName:size:


 

getCharacters

obtain a string value from the receiver


 

getFirstCharacter

obtain the first character from the receiver if it is empty, return a black dot


 

hasTranslucentColor

Overridden from BorderedMorph to test backgroundColor instead of (text) color.


 

isAutoFit


 

isWrapped


 

margins


 

margins:

newMargins can be a number, point or rectangle, as allowed by, eg, insetBy:.


 

newContents:

Accept new text contents.


 

setCharacters:

obtain a string value from the receiver


 

setFirstCharacter:

Set the first character of the receiver as indicated


 

setNumericValue:

Set the contents of the receiver to be a string obtained from aValue


 

text


 

textColor


 

textColor:


 

textStyle


 

userString

Do I have a text string to be searched on?


 

wrapFlag:

Change whether contents are wrapped to the container.


  alignment top  
 

centered


 

justified


 

leftFlush


 

rightFlush


  anchors top  
 

acceptDroppingMorph:event:

This message is sent when a morph is dropped onto me.


 

addMorphFront:fromWorldPosition:

Overridden for more specific re-layout and positioning


 

privateRemoveMorph:

Private! Should only be used by methods that maintain the ower/submorph invariant.


  card & stack top  
 

basicType

Answer a symbol representing the inherent type I hold


 

couldHoldSeparateDataForEachInstance

Answer whether this type of morph is inherently capable of holding separate data for each instance ('card data')


 

newContents:fromCard:

Accept new text contents.


 

setNewContentsFrom:

Using stringOrTextOrNil as a guide, set the receiver's contents afresh. If the input parameter is nil, the a default value stored in a property of the receiver, if any, will supply the new initial content. This method is only called when a VariableDock is attempting to put a new value. This is still messy and ill-understood and not ready for prime time.


 

variableDocks

Answer a list of VariableDock objects for docking up my data with an instance held in my containing playfield


  containment top  
 

fillingOnOff

Establish a container for this text, with opposite filling status


 

occlusionsOnOff

Establish a container for this text, with opposite occlusion avoidance status


 

ownerChanged

The receiver's owner, some kind of a pasteup, has changed its layout.


 

privateOwner:

Nil the container when text gets extracted


 

recognizerArena

Answer the rectangular area, in world coordinates, that the character recognizer should regard as its tablet


 

setContainer:

Adopt (or abandon) container shape


  copying top  
 

veryDeepFixupWith:

If target and arguments fields were weakly copied, fix them here. If
they were in the tree being copied, fix them up, otherwise point to the
originals!


 

veryDeepInner:

Copy all of my instance variables. Some need to be not copied at all, but shared.
Warning!! Every instance variable defined in this class must be handled.
We must also implement veryDeepFixupWith:. See DeepCopier class comment.


  drawing top  
 

debugDrawLineRectsOn:

Shows where text line rectangles are


 

drawNullTextOn:

make null text frame visible


 

drawOn:


  editing top  
 

acceptContents

The message is sent when the user hits enter or Cmd-S.
Accept the current contents and end editing.
This default implementation does nothing.


 

cancelEdits

The message is sent when the user hits enter or Cmd-L.
Cancel the current contents and end editing.
This default implementation does nothing.


 

chooseAlignment


 

chooseEmphasis


 

chooseEmphasisOrAlignment


 

chooseFont


 

chooseStyle


 

clearTypeIn


 

cornerStyle:

set the receiver's corner style as indicated. TextMorphs don't know what to make of this, but are gracious enough not to generate an error


 

enterClickableRegion:


 

handleEdit:

Ensure that changed areas get suitably redrawn


 

handleInteraction:fromEvent:

Perform the changes in interactionBlock, noting any change in selection
and possibly a change in the size of the paragraph (ar 9/22/2001 - added for TextPrintIts)


 

handleKeystroke:

System level event handling.


 

handleMouseMove:

Re-implemented to allow for mouse-up move events


 

handlesKeyboard:

Return true if the receiver wishes to handle the given keyboard event


 

handlesMouseDown:

Do I want to receive mouseDown events (mouseDown:, mouseMove:, mouseUp:)?


 

hasFocus


 

hasUnacceptedEdits:

Ignored here, but noted in TextMorphForEditView


 

keyStroke:

Handle a keystroke event.


 

keyboardFocusChange:

The message is sent to a morph when its keyboard focus change. The given argument indicates that the receiver is gaining keyboard focus (versus losing) the keyboard focus. Morphs that accept keystrokes should change their appearance in some way when they are the current keyboard focus. This default implementation does nothing.


 

mouseDown:

Make this TextMorph be the keyboard input focus, if it isn't already,
and repond to the text selection gesture.


 

mouseMove:

Handle a mouse move event. The default response is to let my eventHandler, if any, handle it.


 

mouseUp:

Handle a mouse up event. The default response is to let my eventHandler, if any, handle it.


 

passKeyboardFocusTo:


 

xeqLinkText:withParameter:


  genie-dispatching top  
 

gestureHandler

If the TextMorph is part of a pane (like PluggableTextMorph), return it


 

handleGesture:

Handle the gesture and store the last handled gesture as lastGestureEvent.
lastGestureEvent is used for undoing gestures


 

lastGesture


 

lastGesture:

Store lastGestureEvent if it is undoable.


 

setAlignment:

Sets the alignment of the TextMorph accoding to the cursorPoint of MorphicGestureEvent.
If the point is at the left, it's left alignment. If in the center or or at the right, it's centered
resp. right alignment.
This is only one example of a tousands of possibilities how to integrate the gesure
recognizer into the system


  genie-processing top  
 

defaultGestureDictionaryOrName

This method returns the default gesture dictionary name for the instances
of a Morph class. (It's also possible to directly return a dictionary but it's much
more flexible to return the name).
This generic implementation returns the class name if there is a dictionary
exported under this name. If not, it tries the name of the superclass, etc.


  geometry top  
 

areasRemainingToFill:

Overridden from BorderedMorph to test backgroundColor instead of (text) color.


 

bounds

Return the bounds of this morph.


 

container

Return the container for composing this text. There are four cases:
1. container is specified as, eg, an arbitrary shape,
2. container is specified as the bound rectangle, because
this morph is linked to others,
3. container is nil, and wrap is true -- grow downward as necessary,
4. container is nil, and wrap is false -- grow in 2D as nexessary.


 

containsPoint:


 

defaultLineHeight


 

extent:


 

goBehind

We need to save the container, as it knows about fill and run-around


 

layoutChanged

self releaseParagraph.


 

minimumExtent

This returns the minimum extent that the morph may be shrunk to. Not honored in too many places yet, but respected by the resizeToFit feature, at least. copied up from SystemWindow 6/00


 

privateMoveBy:

Private! Use 'position:' instead.


 

textBounds


  initialization top  
 

beAllFont:


 

configureForKids


 

copy

Answer another instance just like the receiver. Subclasses typically
override this method; they typically do not override shallowCopy.


 

defaultColor

Return the default fill style for the receiver


 

initialize


 

releaseCachedState

Release any state that can be recomputed on demand, such as the pixel values for a color gradient or the editor state for a TextMorph. This method may be called to save space when a morph becomes inaccessible. Implementations of this method should do 'super releaseCachedState'.


 

setTextStyle:


 

string:fontName:size:


 

string:fontName:size:wrap:


  linked frames top  
 

addPredecessor:


 

addSuccessor:


 

firstCharacterIndex


 

firstInChain

Return the first morph in a chain of textMorphs


 

isLinkedTo:


 

lastCharacterIndex


 

predecessor


 

recomposeChain

Recompose this textMorph and all that follow it.


 

startingIndex


 

successor


 

withSuccessorsDo:

Evaluate aBlock for each morph in my successor chain


  menu top  
 

addCustomMenuItems:hand:

Add morph-specific items to the given menu which was invoked by the given hand. This method provides is invoked both from the halo-menu and from the control-menu regimes.


 

autoFitOnOff


 

autoFitString

Answer the string to put in a menu that will invite the user to switch autoFit mode


 

changeMargins:


 

changeTextColor

Change the color of the receiver -- triggered, e.g. from a menu


 

followCurve


 

reverseCurveDirection


 

setCurveBaseline:


 

shiftedYellowButtonActivity

Supply the normal 'code pane' menu to use its text editing commands from a menu.


 

wrapOnOff


 

wrapString

Answer the string to put in a menu that will invite the user to switch autoFit mode


 

yellowButtonActivity

Supply the normal 'code pane' menu to use its text editing commands from a menu.


  object fileIn top  
 

convertToCurrentVersion:refStream:

subclasses should implement if they wish to convert old instances to modern ones


  printing top  
 

fullPrintOn:


  private top  
 

adjustLineIndicesBy:


 

clippingRectangle


 

composeToBounds

Compose my text to fit my bounds.
If any text lies outside my bounds, it will be clipped, or
if I have successors, it will be shown in the successors.


 

compositionRectangle


 

delete

Remove the receiver as a submorph of its owner and make its new owner be nil.


 

fit

Adjust my bounds to fit the text. Should be a no-op if autoFit is not specified.
Required after the text changes,
or if wrapFlag is true and the user attempts to change the extent.


 

installEditor


 

installEditorToReplace:

Install an editor for my paragraph. This constitutes 'hasFocus'.
If priorEditor is not nil, then initialize the new editor from its state.
We may want to rework this so it actually uses the prior editor.


 

loadCachedState

Prepare for fast response -- next page of a book?


 

paragraph

Paragraph instantiation is lazy -- create it only when needed


 

paragraphClass


 

predecessor:successor:

Private -- for use only in morphic duplication


 

predecessorChanged


 

releaseEditor

Release the editor for my paragraph. This morph no longer 'hasFocus'.


 

releaseParagraph

a slight kludge so subclasses can have a bit more control over whether the paragraph really
gets released. important for GeeMail since the selection needs to be accessible even if the
hand is outside me


 

releaseParagraphReally

a slight kludge so subclasses can have a bit more control over whether the paragraph really
gets released. important for GeeMail since the selection needs to be accessible even if the
hand is outside me


 

selectionChanged


 

setDefaultContentsIfNil

Set the default contents


 

setPredecessor:


 

setSuccessor:


 

text:textStyle:

Private -- for use only in morphic duplication


 

text:textStyle:wrap:color:predecessor:successor:

Private -- for use only in morphic duplication


 

updateFromParagraph

A change has taken place in my paragraph, as a result of editing and I must be updated. If a line break causes recomposition of the current paragraph, or it the selection has entered a different paragraph, then the current editor will be released, and must be reinstalled with the resulting new paragraph, while retaining any editor state, such as selection, undo state, and current typing emphasis.


 

updateReferencesUsing:

Update intra-morph references within a composite morph that has
been copied. For example, if a button refers to morph X in the orginal
composite then the copy of that button in the new composite should refer to
the copy of X in new composite, not the original X. This default
implementation updates the contents of any morph-bearing slot. It may be
overridden to avoid this behavior if so desired.


 

wouldAcceptKeyboardFocusUponTab

Answer whether the receiver might accept keyboard focus if tab were hit in some container playfield


  scripting access top  
 

getAllButFirstCharacter

Obtain all but the first character from the receiver; if that would be empty, return a black dot


 

getNumericValue

Obtain a numeric value from the receiver; if no digits, return zero


 

setAllButFirstCharacter:

Set all but the first char of the receiver to the source


class methods
  class initialization top  
 

initialize

TextMorph initialize


  parts bin top  
 

authoringPrototype

Answer an instance of the receiver suitable for placing in a parts bin for authors


 

borderedPrototype


 

descriptionForPartsBin

If the receiver is a member of a class that would like to be represented in a parts bin, answer the name by which it should be known, and a documentation string to be provided, for example, as balloon help. When the 'nativitySelector' is sent to the 'globalReceiver', it is expected that some kind of Morph will result. The parameters used in the implementation below are for documentation purposes only!


 

exampleBackgroundField

Answer a background field for a parts bin


 

exampleBackgroundLabel

Answer a background label for a parts bin


 

fancyPrototype


 

supplementaryPartsDescriptions

Answer a list of DescriptionForPartsBin objects that characterize objects that this class wishes to contribute to Stationery bins *other* than by the standard default #newStandAlone protocol


  scripting top  
 

additionsToViewerCategories

Answer a list of (<categoryName> <list of category specs>) pairs that characterize the phrases this kind of morph wishes to add to various Viewer categories.


  user interface top  
 

includeInNewMorphMenu

Return true for all classes that can be instantiated from the menu