ご存知の通り、Flash CS5からテキストフィールドは従来のTextFieldと、Text Layout Frameworkを実装したTLFTextFieldが扱えるようになりました。
Text Layout Frameworkは、Flash Player 10から実装されているFlash Text Engineを扱いやすいようにコンポーネント化したフレームワークなんだけど、Flash Text Engineはもとい、Text Layout Frameworkすらも、もうわけわからないってくらい、プロパティ、メソッドが多すぎて痺れます。
しかし、強力なテキスト管理機能を有した新しいテキストエンジンが今後の主流になっていくだろうし、テキストの扱いは地味ながら間違いなく多用するものなので習得せにゃならんだろうと思います。
という訳で、使える機会があれば少しづつ移行しているのだけれど、新しいものってことで実際にコケたところや試したことをエントリーしていこうかと。
とりあえず、先日転んだところで、TLFTextFieldのこと。
TLFTextFieldに関しては、正直今までのTextFieldと変わらないじゃん!わけないよ!くらいに思っていたら、小一時間悩み続けていたという話。
TextFieldでは、一部HTMLのタグが使えました。さらにスタイルシートによる、一部スタイルの指定ができました。
たとえばこんな感じ。aタグにスタイルを指定して、linkとlink:hoverにカラーを適用できます。Flashで外部更新可能なニュースを作ったりする時に使いますよね。
package{
import flash.display.Sprite;
import flash.text.*;
public class TextFieldStyle extends Sprite{
public function TextFieldStyle(){
XML.ignoreComments = true;
XML.ignoreProcessingInstructions= true;
XML.ignoreWhitespace = true;
XML.prettyIndent = 0;
XML.prettyPrinting = false;
var doc:XML = <div>これはTextFieldです。ここを押すと<a href="http://blog.nipx.jp" target="_blank">リンク</a>します。</div>;
var style:StyleSheet = new StyleSheet();
style.setStyle( "a",{ color:"#4371A0" } );
style.setStyle( "a:hover",{ color:"#6F8F0F" } );
var field:TextField = new TextField();
field.x = 250;
field.y = 10;
field.width = 0;
field.height = 0;
field.autoSize = TextFieldAutoSize.CENTER;
field.wordWrap = false;
field.condenseWhite = true;
field.styleSheet = style;
field.htmlText = doc.toString();
addChild( field );
}
}
}
This movie requires Flash Player 10.0.0
TLFTextFieldでも同じようにHTMLタグが利用できます。
package{
import fl.text.TLFTextField;
import flash.display.Sprite;
import flash.text.*;
public class TLFTextFieldStyle extends Sprite{
public function TLFTextFieldStyle(){
XML.ignoreComments = true;
XML.ignoreProcessingInstructions= true;
XML.ignoreWhitespace = true;
XML.prettyIndent = 0;
XML.prettyPrinting = false;
var doc:XML = <div>これはTLFTextFieldです。ここを押すと<a href="http://blog.nipx.jp" target="_blank">リンク</a>します。</div>;
var style:StyleSheet = new StyleSheet();
style.setStyle( "a",{ color:"#4371A0" } );
style.setStyle( "a:hover",{ color:"#6F8F0F" } );
var field:TLFTextField = new TLFTextField();
field.x = 250;
field.y = 10;
field.width = 0;
field.height = 0;
field.autoSize = TextFieldAutoSize.CENTER;
field.wordWrap = false;
field.condenseWhite = true;
field.styleSheet = style;
field.htmlText = doc.toXMLString();
addChild( field );
}
}
}
This movie requires Flash Player 10.0.0
しかし、aタグのスタイル指定が適用されていません。そうTLFTextFieldは、TextFieldと共通の使い勝手の同じプロパティが多数あるけど、中身は別物。styleSheetプロパティについては、
ってことで、styleSheetのプロパティはあるけれど常に無意味。スタイルシートはサポートされない。
そもそも、HTMLタグはサポートされるものの、TLFTextFieldのhtmlTextでは、
aタグの疑似クラスからしてサポートされていないみたい。
ええ!?それじゃあ劣化してんじゃん?って思うのは浅はかだったというもの。そこはしっかりText Layout Frameworkでサポートされています。魔のText Layout Frameworkで。
TLFTextField.textFlowのプロパティにそれらしきものを見つけたところから迷走しだす。
一連のヘルプを読み、
Text Layout Framework の使用
野中先生の解説を読み、
ActionScript 3.0でFlash Professional CS5の Text Layout Frameworkを使う
TLFTextField.textFlowのTextFlowを直接定義したり入れ替えたりと散々まさぐって、それで今回の指定はできたんですけど、なんともまどろっこしい。TLFTextField使う意味ないじゃん!
後にそんなことをせずとも出来ることに気づいた。
TLFTextField.tlfMarkupプロパティ。あるじゃん!これに記述を入れれば出来ました。
package{
import fl.text.TLFTextField;
import flash.display.Sprite;
import flash.text.*;
import flashx.textLayout.conversion.*;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.TextLayoutFormat;
public class TLFTextFieldStyle1 extends Sprite{
public function TLFTextFieldStyle1(){
XML.ignoreComments = true;
XML.ignoreProcessingInstructions= true;
XML.ignoreWhitespace = true;
XML.prettyIndent = 0;
XML.prettyPrinting = false;
var doc:XML = <div>これはTLFTextFieldです。ここを押すと<a href="http://blog.nipx.jp" target="_blank">リンク</a>します。</div>;
var field:TLFTextField = new TLFTextField();
field.x = stage.stageWidth/2;
field.y = 10;
field.width = 0;
field.height = 0;
field.autoSize = TextFieldAutoSize.CENTER;
field.wordWrap = false;
field.multiline = false;
field.condenseWhite = true;
//変換
var flow:TextFlow = TextConverter.importToFlow( doc.toXMLString(), TextConverter.TEXT_FIELD_HTML_FORMAT );
var markup:XML = TextConverter.export( flow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.XML_TYPE ) as XML;
field.tlfMarkup = markup;
//リンクフォーマット
var linkNormalFormat:TextLayoutFormat = new TextLayoutFormat();
linkNormalFormat.color = 0x4371A0;
var linkHoverFormat:TextLayoutFormat = new TextLayoutFormat();
linkHoverFormat.color = 0x6F8F0F;
field.textFlow.linkNormalFormat = linkNormalFormat;
field.textFlow.linkHoverFormat = linkHoverFormat;
//更新
field.textFlow.invalidateAllFormats();
field.textFlow.flowComposer.updateAllControllers();
addChild( field );
}
}
}
This movie requires Flash Player 10.0.0
とりあえず今回要件を満たすには、テキストはTextLayout マークアップ形式で記述する必要があります。
この形式で記述するなら、たとえば、
var doc:XML = <TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span>これはTLFTextFieldです。ここを押すと</span><a href="http://blog.nipx.jp" target="_blank">リンク</a><span>します。</span></p></TextFlow>;
のように記述しなければいけない。この例でも<span>の記述がなんだかめんどくさいと思うんだよね。
外部ファイルでメンテナンスできることを前程に考えているんで、知識のないひとに記述してもらうのはますます厳しい。
なので、元の、
var doc:XML = <div>これはTLFTextFieldです。ここを押すと<a href="http://blog.nipx.jp" target="_blank">リンク</a>します。</div>;
を変換する方法で考えます。
記述をTextFlowに変換したりTextFlowをマークアップに変換したりする、TextConverterクラスがあるのですが、直接この記述を、
var doc:XML = <div>これはTLFTextFieldです。ここを押すと<a href="http://blog.nipx.jp" target="_blank">リンク</a>します。</div>;
var flow:TextFlow = TextConverter.importToFlow( doc, TextConverter.TEXT_LAYOUT_FORMAT);
のようにしても変換できません。
一旦、TextConverter.TEXT_FIELD_HTML_FORMATに変換してから、再度TextConverter.TEXT_LAYOUT_FORMATの記述に書き出します。
var flow:TextFlow = TextConverter.importToFlow( doc.toXMLString(), TextConverter.TEXT_FIELD_HTML_FORMAT );
var markup:XML = TextConverter.export( flow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.XML_TYPE ) as XML;
field.tlfMarkup = markup;
TLFTextFieldのtextFlowではリンクのフォーマットを指定して、最後に更新する。
invalidateAllFormats()が重要。これを実行しないと新しいフォーマットが適用されなかった。
var linkNormalFormat:TextLayoutFormat = new TextLayoutFormat();
linkNormalFormat.color = 0x4371A0;
var linkHoverFormat:TextLayoutFormat = new TextLayoutFormat();
linkHoverFormat.color = 0x6F8F0F;
field.textFlow.linkNormalFormat = linkNormalFormat;
field.textFlow.linkHoverFormat = linkHoverFormat;
field.textFlow.invalidateAllFormats();
field.textFlow.flowComposer.updateAllControllers();