Working with text adornments

In Enhancing text with basic text attributes we looked at the text object and basic attributes such as font name or emphasis. But in this snippet, the link to the page is accompanied by a triangle that appears directly in the editor. What is that? That's a special kind of an attribute called adornment.

Adornments specify interactions and visual elements inside an editor. The various kinds of adornments are modelled as subclasses of BrTextAdornmentAttribute BlTextAttribute subclass: #BrTextAdornmentAttribute instanceVariableNames: 'renderingStrategy cache alignmentMode placeholderAlignment' classVariableNames: '' package: 'Brick-Editor-Attributes' .

Let's start with an example:

text := '42 is the answer' asRopedText.
(text from: 2 to: 2)
	appendingAdornment: [ BlElement new
			background: Color red;
			size: 10@10 ].
text
  

We see a red square added in the middle of the text. Of course, that is a simple element, but key is that it is an element. Where we can have an element, we can have any element.

text := '42 is the answer' asRopedText.
(text from: 2 to: 2)
	appendingAdornment: [ (GtInspector newOn: 42)
			size: 600 @ 400;
			addAptitude: BrShadowAptitude ].
text
  

That's a neat little ability, isn't it? If you want to learn more about why that's possible, it has to do with One rendering tree.

So what happens here? BlTextNextBuilder>>#appendingAdornment: appendingAdornment: aBrTextAdornmentStencilBuilder self attribute: (BrTextAdornmentDynamicAttribute new beAppend; stencil: aBrTextAdornmentStencilBuilder) is a utility method that adds a BrTextAdornmentDynamicAttribute BrTextAdornmentAttribute subclass: #BrTextAdornmentDynamicAttribute instanceVariableNames: 'stencilBuilder' classVariableNames: '' package: 'Brick-Editor-Attributes' which allows you to embed arbitrary elements produced by the stencil block. The code below is equivalent to the one above:

text := '42 is the answer' asRopedText.
(text from: 2 to: 2)
	attribute: (BrTextAdornmentDynamicAttribute new
			beAppend;
			stencil: [ (GtInspector newOn: 42)
					size: 600 @ 400;
					addAptitude: BrShadowAptitude ]).
text
  

Until now, the adornments did not have interaction. But they are full fledged elements and can handle any interaction an element can. For example, the an expanding triangle, like the one seen next to page links can be created through TBlTextStyleable>>#expandingAdornment: expandingAdornment: aBrTextAdornmentStencilBuilder "Append a visual element defined by a given stencil builder right after a text on which I am applied. A stencil builder can also be a block in the following form: [ :aTBrTextEditorTextualPiece :anEditorElement | ] - where aText represents a piece of text after which an element should be append" self expanded: false adornment: aBrTextAdornmentStencilBuilder . In the example below we get an expanding inspector next to the number:

text := '42 is the answer' asRopedText.
(text from: 2 to: 2)
	expandingAdornment: [ (GtInspector newOn: 42)
			height: 400;
			addAptitude: BrShadowAptitude ].
text
  

Explore BrTextAdornmentAttribute BlTextAttribute subclass: #BrTextAdornmentAttribute instanceVariableNames: 'renderingStrategy cache alignmentMode placeholderAlignment' classVariableNames: '' package: 'Brick-Editor-Attributes' for more details.