Bullet Points and Text Alignment in the Text Layout Framework

I don’t have enough time right now to go into too much detail so I’m afraid this post will just consist of pointers and no real code samples, but I wanted to say that bullet points, although technically un-supported in the Text Layout Framework right now…

I don’t have enough time right now to go into too much detail so I’m afraid this post will just consist of pointers and no real code samples, but I wanted to say that bullet points, although technically un-supported in the Text Layout Framework right now (in terms of <li> tags), are possible. Text alignment is already supported, and you can build a pretty solid text editor that uses these, as well as all the kinds of formatting you’d expect from colour to font weight.

In my case I have a further requirement where the editor needs to work on the whole TextFlow (imagine a user is moving/operating on the entire block of text, that might contain several paragraphs, spans, and a mixture of formatting, alignment and styling), but also on a particular selection, when the user places the carat between two characters, or selects a range of text (again that range might go over multiple different paragraphs). This is similar to the sizable TextBoxes in Microsoft Word.

When you cater for these two modes of operation, the overall experience is a lot more natural. So even if you can’t display the current alignment/bullet point type in your editor because they have selected a range that contains different types, you can default to the overall styles and still allow the user to operate on whole ranges at once.

Now for some pointers on using bullet points in TLF. First of all the bullets themselves… as long as you are embedding your font(s) you can use the following unicode characters inside your SpanElements:

public static const CIRCLE_BULLET:String = "u2022";
public static const SQUARE_BULLET:String = "u25A0";
public static const DIAMOND_BULLET:String = "u25C6";

At runtime you can add, replace or remove these via SpanElement.text and SpanElement.replaceText(). It’s also worth considering whitespace preceeding/trailing the bullet, I make sure this is removed/added if not already.

Now for indentation, which may or may not be desired. One way to do this is to set the marginLeft property of the ParagraphElement that wraps the given SpanElement. You can grab the ParagraphElement for any FlowElement (including Spans) with FlowElement.getParagraph(). Remember these properties are write-only, to read these values you have to use the Edit/SelectionManager’s getCommonParagraphFormat() methods.

The trickiest part of working with the Text Layout Framework in edit mode is providing a good experience with regards to selections. As I explained my code has two situations to deal with, either the user is operating on the entire TextFlow, or a selection, either way these can incorporate a varied collection of sub-elements such as several ParagraphElements each with SpanElements, InlineGraphicElements, TabElements and so on.

To work with selections you need to add an event listener to the TextFlow for SelectionEvent. This is the only object I’ve found that gives you the selected ElementRange. The ElementRange provides useful information such as the firstLeaf (e.g. a SpanElement) the firstParagraph (a ParagraphElement) and lastParagraph in the selected range.

Using the firstLeaf value provides you access to the Span (be sure to test it is a Span), and so you can use the technique described to insert/remove/change bullets. And by using the FlowElement’s getNextSibling() method on the firstParagraph property, you can run through the TextFlow’s “DOM” finding all siblings in the selection (stopping at lastParagraph), and apply the leftMargin, or textAlign depending on what you need to apply.

If you find having selectable bullet points is a pain, I’m hoping “real” bullets/lists will be fully supported in later builds of TLF, but you may also want to look at using inline images (sacrificing bullet colour) if this method doesn’t suit your need.

I haven’t spoken about applying formatting such as bold/italic, colour or fontFamily. But this is much more straightforward and you can find all you need in the EditManager class, which has various applyXYZFormatting() methods that do just this (on the current selection).

3 thoughts on “Bullet Points and Text Alignment in the Text Layout Framework”

  1. Tanks for this article Richard, I’m working on a custom editor which needs bullet points, so this came in very handy!

    In your approach, the bullet graphic (or character) is editable. While this isn’t the end of the world, I wonder if you might have a trick up your sleeve for making this a non editable feature. Right now all I can come up with is some really nasty solutions like having the graphic below the textflow as a Sprite or so, and update it whenever edits are made… ugh…

  2. Yeah I think using the InlineGraphicElement is probably the best way to do this right now, but I’m keeping mine editable. I’m hoping built-in lists will be supported before I go live though. Another way would be to listen to the delete/backspace keys and just undo the deletion if it’s a bullet character.

  3. As this is the only result I found on Google concerning this problem I’ll post my solution here.

    My approach was to utilize the TextFlow’s TextFlowLines. Iterating over those elements I could then create and position bullet characters (a seperate SimpleText containing only that character) in relation to the TextFlowLine’s y property. I guess that property was introduced in one of the recent nightly versions. The function to retrieve a line is:

    anyTLFelement.textFlow.flowComposer.getLineAt(i)

    One can also check if a TextFlowLine belongs to an already “bulleted” ParagraphElement through the paragraph property. This allows you to skip adding a bullet for that line.

    Finally a bullet’s style can easily be adjusted to match its paragraph by reading the properties of the current ParagraphElement.

    The above steps are done on every update making this the “update while editing” solution but having non-editable bullets was important for my project.

Comments are closed.