StageXL RichTextField

Rich Text Field add-on package for StageXL - allows for multiple format ranges within a given text field.

NOTE: as of version 0.10.0-dev, StageXL_RichTextField requires a Dart 2 SDK.

Build Status


To use StageXL RichTextFields, simply import the package after importing stagexl itself...

import 'package:stagexl/stagexl.dart';
import 'package:stagexl_richtextfield/stagexl_richtextfield.dart';

void main() {

  CanvasElement canvas = querySelector("#richtext");
  Stage stage = new Stage('richtext', canvas)
    ..scaleMode = StageScaleMode.SHOW_ALL;
  RenderLoop render = new RenderLoop();
  RichTextFormat format = new RichTextFormat('Calibri, sans-serif', 25, 0x000000, align: TextFormatAlign.LEFT);
  RichTextField rtf = new RichTextField()
    ..defaultTextFormat = format
    ..text = 'Here is some sample {b}bold{/b} text.'
    ..width = stage.sourceWidth
    ..height = stage.sourceHeight
    ..wordWrap = true
    ..y = 0;



Doing it by hand

RichTextField adds startIndex and endIndex fields to the RichTextFormat class. A -1 in endIndex will anchor the format through the end of the string. These are commonly specified in the RichTextField.setFormat method, as follows:

RichTextFormat format = new RichTextFormat('Calibri, sans-serif', 25, 0x000000, align: TextFormatAlign.LEFT);
RichTextField rtf = new RichTextField('Manually setting some bold text', format, false)
    ..width = 400;

//the word "bold" above is at character positions 22 through 25
rtf.setFormat(format..bold=true, 22, 25);

As you add "ranged formats" to your RichTextField it applies logic to maintain mutually exclusive format ranges. This means that if you added italic=true from 5 through 25, and then bold=true from 10 through 15, the range from 10 to 15 will not be italicized, only bold - the original 5 to 25 italic is automatically split into two ranges, one from 5 to 9, the other from 16 to 25.

The easy way

As you can imagine, having to count character ranges simply to apply some formatting is not ideal. To address this, a simple parser is included which understand the set of "text tags" (wrapped in {}) defined below:

{b}BoldSome {b}bold{/b} text
{i}ItalicNow {i}italic{/i} text
{u}UnderlineCan do {u}underlines{/u}
{o}OverlineAnd {o}overlines{/o}
{s}StrikethroughEven {s}strikethrough{/s} text
{color=}Set colorSome {color=0xFF0000}red text{/color}
{font=}Set font{font=Georgia}Georgia{/font} on my mind
{size=+-*/}Set size{size=*2}Double{/size} and {size=-5}smaller{/size}
{preset}Apply presetI'm so {excited}excited, I just can't hide it!{/excited}

The {preset} tag bears some explanation. RichTextField also has a public Map<String, RichTextFormat> field named presets. If you have some combination of styles that you use regularly, instead of wrapping multiple tags every time, you can simply add the preset to your field and call it with a tag:

RichTextField rtf = new RichTextField()
    ..presets['excited'] = format.clone()..bold=true..italic=true..size=30..color=0xFF00FF;

Try out the sandbox example to get better acquainted.

Roll your own parser

The default included parser may not meet all of your needs. Beyond wrapping the low-level functions, the parser method itself is publically settable, so you can override with your own. (Note: this approach could use a code review to make pluggable parsers more robust).