Implementing SpellCheck (Squiggly) with the Text Layout Framework (TLF)

I’ve just posted over in the Text Layout forums how I went about implementing Squiggly with “pure” Text Layout Framework… so that’s not using TLF/FTETextField or the Spark components.This is really just an overview which should give plenty to help yo…

I’ve just posted over in the Text Layout forums how I went about implementing Squiggly with “pure” Text Layout Framework… so that’s not using TLF/FTETextField or the Spark components.

This is really just an overview which should give plenty to help you figure out the steps. I can’t paste the exact code because it’s embedded in a client project, but I do refer to some of the TLF functions throughout that you have to make use of, if anyone can suggest improvements, please drop them in the comments.

Copied from the forum post…

Find TextRanges for misspelled words:

  • Get the first Paragraph using textFlow.getFirstLeaf().getParagraph()
  • Loop through all Paragraphs using para.getNextParagraph()
  • For each, run a Regex match (/bw+b/) on para.getText()
  • Spellcheck each result using Squiggly, and for bad words store a TextRange: TextRange(textFlow, para.getAbsoluteStart()+index, para.getAbsoluteStart()+index+word.length-1); where index is incremented to the position proceeding the end of each word (match or no match).

Spellcheck class:

  • Created a static SpellCheck class which loads language dictionary (downloaded from OpenOffice website) and a UserDictionary (stored as a simple text file)
  • Added methods for checkTextFlow(textFlow:TextFlow):Array which returns an array of “bad” TextRanges, a method for getSuggestions(word:String):Array and methods for checkWord() and addUserWord().

Context menu:

  • Extend ContainerController and override menuSelectHandler()… use an instance of my CustomContainerController when creating the TextFlow:
    textFlow.flowComposer.addController( new CustomContainerController() );
  • Loop through flowComposer.numLines, obtain each TextFlowLine from flowComposer and therefore each TextLine.
  • Determine if textLine.getBounds(container).container(container.mouseX, container.mouseY) to find the line they right-clicked.
  • Get the “raw text” for the line: textLine.textBlock.content.rawText.substr(textLine.textBlockBeginIndex);
  • Find the atom clicked: textLine.getAtomIndexAtPoint(container.stage.mouseX, container.stage.mouseY).
  • Find the starting atom of the word (reverse lookup for word boundary i.e.. ” ” or first char in raw text).
  • Determine the word itself by using regex to find the first word from this starting point (/bw+b/).
  • Add ContextMenuItems for “add to dictionary” and suggested words (for the latter also store start/end atoms in ContextMenuItem.data).
  • When user clicks a suggested word, use (interactionManager as EditManager).selectRange(data.start, data.end); (interactionManager as EditManager).insertText(data.word) where “data” is the data property of the clicked ContextMenuItem.

In my “EditableTextField” class, I call my SpellCheck.checkTextFlow() to get the bad TextRanges and…

  • Loop through the badRanges array.
  • Loop from range.absoluteStart to range.absoluteEnd for each TextRange.
  • Find TextFlowLine for “i” in this loop, and therefore the TextLine: containerController.flowComposer.findLineAtPosition(i); textFlowLine.getTextLine();
  • Find atom bounds using textLine.getAtomBounds(charIndex); where charIndex is: i – textFlowLine.absoluteStart.
    Underline… drawRect( bounds.x + textLine.x, bounds.y + textLine.y + bounds.height – textLine.descent – 1, bounds.width, 3)

I’m sure there is a more elegant way, but this seems to work. I believe I read Adobe are working on Squiggly for pure TLF, if not, I hope this helps somebody get on the right track.

Flash/Flex Builder <-> Flash Professional Asset Workflows

This post discusses the various workflows for producing SWFs with the standalone compiler that use graphical assets and animations created in Flash Professional (“Flash Pro”). At time of writing the latest version of Flash Pro is CS4, with CS5 briefly ou…

This post discusses the various workflows for producing SWFs with the standalone compiler that use graphical assets and animations created in Flash Professional (“Flash Pro”). At time of writing the latest version of Flash Pro is CS4, with CS5 briefly out in beta for a short while. Specifically we look at the methods that involve exporting SWCs and using the [Embed] metatag within class files.

Recently I posted a bug report regarding the [Embed] metatag, which led me to write this post in order to find out whether people are happy with their current workflows and how well others receive projects when it comes to handovers and maintenance.

Background

So you’re building an application, a game, or a website. Immediately you have two options when it comes to setting up your Flash project. You can create an FLA file, assign a document class and get coding, or you can fire up Flash(/Flex) Builder/FDT/Flash Develop et al, create a new Flex or AS3 project and compile it using the Flex SDK compiler. Pretty much every time I’ll opt for the latter because of the increased reliability of the application, and faster compile times.

Even if you use the first option, compiling in Flash Pro itself, you may be actually editing your code in Flash Builder or some other IDE, but the point is the compiler being used in the former is Flash Pro, and in the latter mxmlc/compc the Flex SDK compilers. For the purpose of this post we’ll be looking at Flex or AS3 projects using the Flex SDK compiler, and how to get assets from a FLA, into your project.

I’ve written the following to the best of my knowledge, but there are always tips and tricks that I may be missing, perhaps an entire workflow. If you spot any inaccuracies or flaws please let me know in the comments and I’ll change it ASAP.

Why an FLA at all?

You probably already know you can embed PNGs, SVG and other file types in your classes and never go near an FLA to get graphics into a SWF. When it comes to animations, you may use TweenLite or GTween to perform transitions, but when it comes to frame-based animation, character animation, or simply buttons and panels with hand-made flourishes you may want to use an FLA to create and animate these using the powerful timeline, graphics and animation tools within Flash Pro.

It’s at this point you ask yourself, how do I get these assets from a FLA into my project if I’m not compiling my project in Flash Pro?

The Workflows

Here are 5 methods for getting assets from an FLA, into a Flex or “pure AS3″ project. I’ve excluded those which are MXML-only as this post is not about Flex specifically.

1. Publish SWC from FLA

This method involves linking library symbols to classes, so instead of “MySymbol” in the class field, you have “com.package.MyClass” which refers to a class file in one of the FLAs classpaths. You must then turn on SWC export in the FLA Publish Settings panel, and most likely turn off “Automatically declare stage instances” in the ActionScript 3 settings panel to avoid errors where your class has defined properties for items on stage. Finally add all of the required classpaths that the linked classes will be using (that could include 3rd party libraries) to avoid any compile-time errors.

When you publish the SWF it’ll also publish a SWC in the same folder. You add that SWC to your AS3 project and the classes/symbols compiled into it become available for use in your code.

Pros:

This method keeps any timeline ActionScript, great for complex, nested or multi-state animations.

Cons:

You have to compile the FLA every time you change a class linked to a symbol, in reality that can mean toggling to Flash, exporting the SWC, toggling back to Flash Builder, refreshing the project to re-build the SWC indexes and then recompiling the project here also.

You have to make sure the classes your symbols are linked to are not in the main project source directory (or any directory the project is set to reference as source code). If you don’t do this you will likely not see your graphics/animations appear because the Flex linker will find the class definition first, not the definition that is inside the SWC due to the compilation order.

You have to add all required classpaths to the FLA, possibly every classpath your project is using.

Flash Builder will not report errors in the code used and you lose the ability to Ctrl/Cmd+Click to go to source.

You don’t have access to items on stage immediately, the workaround is pretty painful (link).

Summary:

Whilst this is really the only sensible method for keeping timeline code, the cons make it a really un-intuitive and frustrating process. If anyone can suggest a way to improve this I’ll owe you quite a few beers.

2. [Embed] tag above a class declaration

Example:

Code:

package my.package {
  [Embed(source="assets/some.swf", symbol="SymbolName")]
  public class MyClass {
  // code
  }
}

Here we’re simply using the SWF produced by an FLA to store our symbols. The FLA does not link any symbols to any classes itself, the library is simply full of vanilla MovieClips. In our class files we add the [Embed] tag and that binds the symbol from the SWF to the class, so that when we create a new instance of that class, we will also get the graphics from the library symbol.

Pros:

You don’t have to re-compile the FLA unless your graphics actually change.

You can spend more time in your coding environment and not toggle back and forth between it and Flash Pro.

You get real-time compilation errors in the Problems panel of Eclipse because the code is not coming from a SWC.

Cons:

It strips ActionScript from the timeline of your symbols. If your symbol is an animation, and you had a few stop frames in there, perhaps one per labelled segment of animation, you’ll lose these and the animation will just run through on loop. What you see coders do to circumvent this is use addFrameScript(5, stop); for every stop frame, or even using lots of frame labels to act as meta-tags for code replacement (link).

Any children of the symbol lose any typing, so if you’ve added a couple of MyButton’s or a MyCustomWidget to your symbol on it’s timeline, those become plain MovieClips. This is a huge problem which relegates this method to animations only.

3. [Embed] tag above a class property declaration

This method involves using the [Embed] tag above a class property, for example:

Code:

[Embed(source="assets/some.swf", symbol="MySymbol")]
private var MySymbol:Class;
 
// later on in a function...
 
var myInstance:Sprite = new MySymbol();

So you can probably guess this is more of a composition-based approach, which works well for simple graphics, for multi-frame MovieClips you’d type myInstance as MovieClip, and tell it to stop().

With this method you’re instance will either be a SpriteAsset (extends Sprite) or a MovieClipAsset (extends MovieClip), you cannot cast it to a custom class, so for a symbol that is meant to represent a contact form, with an instance of MyButtonClass or even just some TextFields in it, this will fail.

4. Embed metatag to embed a whole SWF

There’s also another attribute available to the Embed metatag, that’s mimeType. If you remove the symbol attribute and replace it with mimeType=”application/octet-stream” it will embed the entire SWF and preserve the class associations set up in the library, i.e. you won’t have to have the instances typed to Sprite(/Asset) or MovieClip(/Asset).

When you embed a symbol from a SWF in this way, you can then use Loader to get at the classes within:

Code:

[Embed(source="assets/some.swf", mimeType="application/octet-stream")]
private var MySWF:Class;
 
// within a method
var bytes:ByteArray = (new MySWF() as ByteArray);
var loader:Loader = new Loader();
loader.loadBytes(bytes, new LoaderContext(false, ApplicationDomain.currentDomain));
 
// wait for loader to dispatch Event.COMPLETE and...
var myClass:Class = loader.contentLoaderInfo.applicationDomain.getDefinition("com.package.MyClass");
var myInstance:DisplayObject = new myClass();
// myInstance is now an instance of the class linked to it

Pros:

Great way to provide a library symbol a class/some behaviour without having to constantly re-compile the FLA.

Cons:

I think you’ll agree that’s not a great option if you have a lot of symbols or symbols which have others nested within. There are libraries to help with this, but…

No strict typing.

5. Runtime loading a SWF

Perhaps the oldest option here, loading a SWF at runtime allows you to pull out symbols/classes using the applicationDomain.getDefinition() function as described in method 3. If you’re already familiar with the getDefinitionByName() utility this works pretty much the same, but you are targeting a specific SWF’s classes.

Pros:

Great for loading content that rarely changes, such as fonts.

Cons:

Magic strings. Making a string a constant does not make it any less hacky, if you change the string in your FLA, your constant is meaningless, and you’ll only find out about it at runtime if that piece of code executes.

You’ll have to export your SWF from an FLA or using one of the other techniques which means you’ll also have some of the problems associated with those.

Feedback

So what route do you take? Please also state the type of project: application, game, website; it’s quite possible that people building applications simply never encounter these issues due to the primarily scripted animation and simple non-hierarchical graphical assets.

You may also want to consider how easy it will be to start compiling in Flash Professional in order to take advantage of CS5’s export to iPhone, this can impact your decision on which method you use.

Overall I feel that whilst choice is great, each method seems to have pretty serious downsides, and I’m yet to find one that doesn’t make for a less than pleasant rinse-and-repeat workflow. It would be nice to be able use Flash Pro to speed up the process of preparing game assets, laying stuff out on stage, animating on the timeline… but there are too many down-sides associated with this, and too many idiosyncrasies to learn just to get things working, I hope in future the two tools can be brought closer together perhaps through the new file format.

As usual, all comments welcome, unless you’re the bargain-dishwasher spammer.

Further reading

http://www.bit-101.com/blog/?p=853

http://www.bit-101.com/blog/?p=864

http://gskinner.com/blog/archives/2007/03/using_flash_sym.html

http://www.airtightinteractive.com/news/?p=327

Also the Flex Livedocs, which certainly don’t explain all of these methods in nearly enough detail or context, which makes using the Flex SDK a darker art than it could be.

Creating Drupal Sites with Flash or Flex: Update

It appears a new Views module has been released which is causing a couple of problems with the Drupal/Flash stuff, so I’ve updated the post to describe the necessary steps. Hopefully the Adobe DevNet article will also be updated soon with these changes.…

It appears a new Views module has been released which is causing a couple of problems with the Drupal/Flash stuff, so I’ve updated the post to describe the necessary steps. Hopefully the Adobe DevNet article will also be updated soon with these changes.

You can read the updated post here.

Creating Drupal Sites with Flash or Flex

I’m pleased to see that an article I wrote for Adobe DevNet has just gone live. “Creating Drupal Sites for Flash or Flex” describes the benefits of using a CMS for your Flash or Flex sites, how to set everything up, getting Flash talking to Drupal, and a…

I’m pleased to see that an article I wrote for Adobe DevNet has just gone live. “Creating Drupal Sites for Flash or Flex” describes the benefits of using a CMS for your Flash or Flex sites, how to set everything up, getting Flash talking to Drupal, and also covers the various modules available to power your site.

Drupal is probably the most popular open source CMS out there, it has an enormous user community, and the best thing of all is probably the fact that you don’t have to write any PHP or SQL to take advantage of this as a result! (Unless of course you want to, Drupal is fully extensible).

There are many ways to use Drupal with the Flash platform, ranging from simple content access, to automatically generated content that is formatted for and consumed by both Flash and non-Flash enabled devices. Without going into any more detail, please feel free to head over to the DevNet article to read more and download the source code and examples.

Update!

It appears there have been some name changes in the Services module called by Flash (“views.getView” becomes “view.get” and “node.load” becomes “node.get”) – thanks to Stan for pointing this out in the comments. As a result I’ve modified the code and provided two versions below, the download I linked-to above has also been updated. The example FLAs are also now Flash CS3 compatible.

Update 2!

It seems the new Services module also has a breaking change when it comes to generating the sitemap, you’ll see no properties on your nodes except id. Do not download the official 6.x-0.14 release, instead get the 6.x-2.x-dev development snapshot as the bug has been patched (unless the official release is newer in which case the patch will already be in). For a deeper explanation, it appears the PHP was not loading the nodes you were requesting, so the only info it could return was the ID which wasn’t a whole lot of use for a sitemap!

Compiling FFMPEG Statically on OS X (and Windows)

I was up extremely late last night figuring this out, so I made some rough notes as I went along. Hopefully they’ll save someone a small nightmare.Disclaimer: I haven’t written C code since I was in my teens, and apart from some Objective-C from the…

I was up extremely late last night figuring this out, so I made some rough notes as I went along. Hopefully they’ll save someone a small nightmare.

Disclaimer: I haven’t written C code since I was in my teens, and apart from some Objective-C from the comfort of XCode, I haven’t really done a whole lot of GCC compiling on any system, so this may not be the best way to do any of this.
Continue reading “Compiling FFMPEG Statically on OS X (and Windows)”

Flash on the Beach 2009 Tickets Now on Sale

The schedule has just gone up, new speakers have been added, and tickets are now on sale. You’ll want to get your tickets as soon as possible because the sooner you get them, the cheaper they are, and they’ll be going fast.There are options for compa…

The schedule has just gone up, new speakers have been added, and tickets are now on sale. You’ll want to get your tickets as soon as possible because the sooner you get them, the cheaper they are, and they’ll be going fast.

There are options for companies that wish to send several different employees over the course of the three days (see Flexi-pass option), as well as student tickets and single day tickets.

Flash on the Beach has offered a brilliant atmosphere and eclectic collection of speakers in the past, focusing on Flash Platform topics, but throwing into the mix anything new and exciting such as iPhone development.

Head over to the website to get yours.

Silverlight 3 Beta Release and Adobe

Yesterday, to much excitement, Microsoft released Silverlight 3 beta, and gave a run-down on the new features at the MIX09 conference. It has been a very long time since I first looked at Silverlight (here’s my post on a pre 1.0 early build I got to use…

Yesterday, to much excitement, Microsoft released Silverlight 3 beta, and gave a run-down on the new features at the MIX09 conference. It has been a very long time since I first looked at Silverlight (here’s my post on a pre 1.0 early build I got to use over in Redmond), and I’ve used both Silverlight and WPF since (which will eventually be two in the same IMHO), one app for the BBC was demo’d at the MIX07 keynote, so I’m fairly familiar with the offering and how it compares.

Just to give a run-down of the key features we’ve seen announced, I’m adding comparisons to Flash features:

Continue reading “Silverlight 3 Beta Release and Adobe”

Flex 3/4 Font Embedding: CFF-DefineFont4 vs DefineFont3

There are now two types of font embedding available to both Flash (CS4) and Flex 3 and 4. These are DefineFont3 (classic), and DefineFont4 (supporting CFF and the new text engine.)

In Flash, Flex 2 and 3 you’d traditionally embed fonts for use in the…

There are now two types of font embedding available to both Flash (CS4) and Flex 3 and 4. These are DefineFont3 (classic), and DefineFont4 (supporting CFF and the new text engine.)

In Flash, Flex 2 and 3 you’d traditionally embed fonts for use in the TextField class, whether that’s a vanilla TextField, or a component that uses the TextField class and has been set to use embedded fonts. This is DefineFont3 embedding. The steps are usually:

  1. Embed fonts in a SWF using the Flash IDE or the [Embed()] tag in Flex.
  2. Set myTextField.embedFonts = true; (or setStyle(“embedFonts”,true) for a component.)
  3. Either set myTextField.defaultTextFormat, use setTextFormat(), or setStyle().
  4. Set the text with .text or .htmlText (using CSS or the font tag).

Continue reading “Flex 3/4 Font Embedding: CFF-DefineFont4 vs DefineFont3”

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.
Continue reading “Bullet Points and Text Alignment in the Text Layout Framework”

Text Layout Framework Follow Up PureMVC Solution

In my previous post I posed the problem of using the new Text Layout Framework in an application where you already have an Undo stack/mechanism, for example in PureMVC with the Undo utility (CommandHistoryProxy).The challenge arises because the TLF a…

In my previous post I posed the problem of using the new Text Layout Framework in an application where you already have an Undo stack/mechanism, for example in PureMVC with the Undo utility (CommandHistoryProxy).

The challenge arises because the TLF already has an UndoManager, so the solution must hook into that. Added to that, in an application you’re likely to need to serialize your TextFlow to disk/server, which means de-serializing it, which means you’re storing your data outside of the TextFlow instance and needing to keep this store up to date as the user interacts with the TextFlow via the EditManager provided by the TLF.
Continue reading “Text Layout Framework Follow Up PureMVC Solution”