Constructing a text editor with custom styling for urls
Let's build an editor starting with a string like the following one:
string := 'At https://gtoolkit.com you can find more details about Glamorous Toolkit.'.
A basic editor is an instance of BrEditor
editor := BrEditor new aptitude: BrGlamorousCodeEditorAptitude. editor text: string. editor
But what about a more elaborate editing experience? For example, what if we want to have an editor that reacts to links as we type them?
The first thing we need is a way to detect the links. For our exercise, we will use a sea parser that extracts a collection with the ranges of the links:
urlParser := ('https://' asPParser token , String space asPParser negate star token) ==> [ :t | t first start -> t last stop ]. parser := (urlParser sea ==> #second) star optimize.
Let's try it quickly:
parser parse: string
Now that we have a way to detect the ranges of urls, we can create a custom styler to highlight them:
styler := BlPluggableStyler new block: [ :text | (parser parse: text asString) do: [ :each | (text from: each key to: each value) underlineDo: [:d | d color: Color blue ]; foreground: Color blue ] ]. editor := BrEditor new aptitude: BrGlamorousCodeEditorAptitude. editor styler: styler. editor text: string. editor
In this case we use a BlPluggableStyler
that we can script through a block that takes the text as argument. In that block, we use the parser and for each detected range we add TBlTextStyleable>>#underlineDo:
and TBlTextStyleable>>#foreground:
.
Highlighting links is nice, but what about seeing the webpage? One option would be to handle clicking. This can be achieved through TBlTextStyleable>>#onClick:
. Another option is to insert an expandable web browser right in the editor. That can be done through a so called adornment. Let's try both of them:
styler := BlPluggableStyler new block: [ :text | (parser parse: text asString) do: [ :each | | urlText | urlText := text from: each key to: each value. urlText foreground: Color blue; onClick: [ :aTextualPiece :aTarget :aTextEditor :anEvent | aTarget phlow spawnObject: (GtWebViewElement new url: urlText asString) ]; attribute: (BrTextHoverStylableAttribute new attribute: (BlTextDecorationAttribute new underline color: Color blue)); expandingAdornment: [ GtWebViewElement new url: urlText asString; height: 400; background: Color white; addAptitude: BrShadowAptitude ] ] ]. editor := BrEditor new aptitude: BrGlamorousCodeEditorAptitude. editor styler: styler. editor text: string. editor