Posted on 2012-05-04 11:30
TWaver 阅读(2261)
评论(1) 编辑 收藏
最近有客户提到如何让Network上网元的标签垂直显示,首先想到的就是每个字符之间插入一个回车。这个用Network#labelFunction就能达到目的:
1 network.labelFunction = function (element:IElement):String {
2 var name:String = element.name;
3 if(element.getClient('vertical')) {
4 var result:String = '';
5 for(var i:int=0,n:int=name.length; i<n; i++) {
6 result += name.charAt(i) + '\n';
7 }
8 result = result.substr(0, result.length-1);
9 return result;
10 } else {
11 return name;
12 }
13 };
来段代码测试看看:
1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
3 xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
4 layout="absolute" width="100%" height="100%"
5 creationComplete="init()" backgroundColor="#FFFFFF" >
6 <mx:Script>
7 <![CDATA[
8 import twaver.Consts;
9 import twaver.ElementBox;
10 import twaver.IElement;
11 import twaver.Node;
12 import twaver.Styles;
13
14 private var box:ElementBox = new ElementBox();
15
16 private function init():void {
17 network.labelFunction = function (element:IElement):String {
18 var name:String = element.name;
19 if(element.getClient('vertical')) {
20 var result:String = '';
21 for(var i:int=0,n:int=name.length; i<n; i++) {
22 result += name.charAt(i) + '\n';
23 }
24 result = result.substr(0, result.length-1);
25 return result;
26 } else {
27 return name;
28 }
29 };
30
31 var node1:Node = new Node();
32 node1.location = new Point(100, 100);
33 node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
34 node1.setClient('vertical', true);
35 node1.name = '竖向文字Vertical Text';
36 box.add(node1);
37
38 network.elementBox = box;
39 }
40 ]]>
41 </mx:Script>
42 <twaver:Network id="network" width="100%" height="100%" />
43 </mx:Application>
运行效果如下:
上面的方法很容易让文字垂直显示,但效果不是很理想,中英文混合时,英文也被一个字母一个字母地分开了。有没有更好的方案?答案是肯定的,借助于Flex的Flash Text Engine (FTE)和Text Layout Framework (TLF),可以很容易地让文字从上到下显示。
先来看看一个小例子,设置TextLayoutFormat的blockProgression属性为BlockProgression.RL即可:
1 package {
2 import flash.display.Sprite;
3
4 import flashx.textLayout.container.ContainerController;
5 import flashx.textLayout.conversion.TextConverter;
6 import flashx.textLayout.elements.TextFlow;
7 import flashx.textLayout.formats.BlockProgression;
8 import flashx.textLayout.formats.TextLayoutFormat;
9
10 public class StaticHelloWorld extends Sprite {
11 public function StaticHelloWorld() {
12 var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
13 textLayoutFormat.lineHeight = 30;
14 textLayoutFormat.locale = 'zh';
15 textLayoutFormat.blockProgression = BlockProgression.RL;
16
17 var text:String = "测试竖向文字,再看看English如何?";
18 var textFlow:TextFlow = TextConverter.importToFlow(text, TextConverter.PLAIN_TEXT_FORMAT);
19 textFlow.hostFormat = textLayoutFormat;
20 textFlow.flowComposer.addController(new ContainerController(this, 25, 200));
21 textFlow.flowComposer.updateAllControllers();
22 }
23 }
24 }
运行效果如下:
的确这样效果就好多了,英文不会被一个字母一个字母地打断,然后我们自定义一个Attachment:
1 package {
2 import flash.display.Sprite;
3 import flash.text.engine.FontPosture;
4 import flash.text.engine.FontWeight;
5
6 import flashx.textLayout.container.ContainerController;
7 import flashx.textLayout.elements.ParagraphElement;
8 import flashx.textLayout.elements.SpanElement;
9 import flashx.textLayout.elements.TextFlow;
10 import flashx.textLayout.formats.BlockProgression;
11 import flashx.textLayout.formats.TextDecoration;
12 import flashx.textLayout.formats.TextLayoutFormat;
13
14 import twaver.Styles;
15 import twaver.network.ui.BasicAttachment;
16 import twaver.network.ui.ElementUI;
17
18 public class FTELabelAttachment extends BasicAttachment {
19
20 private var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
21
22 public function FTELabelAttachment(elementUI:ElementUI, showInAttachmentCanvas:Boolean=false) {
23 super(elementUI, showInAttachmentCanvas);
24
25 this.textLayoutFormat.locale = 'zh';
26 this.textLayoutFormat.blockProgression = BlockProgression.RL;
27 }
28
29 override public function updateProperties():void {
30 super.updateProperties();
31
32 this.textLayoutFormat.fontFamily = element.getStyle(Styles.LABEL_FONT);
33 this.textLayoutFormat.color = element.getStyle(Styles.LABEL_COLOR);
34 this.textLayoutFormat.fontSize = element.getStyle(Styles.LABEL_SIZE);
35 this.textLayoutFormat.fontStyle = element.getStyle(Styles.LABEL_ITALIC) ? FontPosture.ITALIC : FontPosture.NORMAL;
36 this.textLayoutFormat.fontWeight = element.getStyle(Styles.LABEL_BOLD) ? FontWeight.BOLD : FontWeight.NORMAL;
37 this.textLayoutFormat.textDecoration = element.getStyle(Styles.LABEL_UNDERLINE ? TextDecoration.UNDERLINE : TextDecoration.NONE);
38
39 var textFlow:TextFlow = new TextFlow();
40 textFlow.hostFormat = this.textLayoutFormat;
41 var p:ParagraphElement = new ParagraphElement();
42 textFlow.addChild(p);
43 var span:SpanElement = new SpanElement();
44 span.text = network.getLabel(element);
45 p.addChild(span);
46
47 var fteLabel:Sprite = new Sprite();
48 this.content = fteLabel;
49 var containerController:ContainerController = new ContainerController(fteLabel, this.textLayoutFormat.fontSize, 1000);
50 textFlow.flowComposer.addController(containerController);
51 textFlow.flowComposer.updateAllControllers();
52 }
53
54 override public function get position():String {
55 return element.getStyle(Styles.LABEL_POSITION);
56 }
57
58 override public function get xOffset():Number {
59 return element.getStyle(Styles.LABEL_XOFFSET);
60 }
61
62 override public function get yOffset():Number {
63 return element.getStyle(Styles.LABEL_YOFFSET);
64 }
65
66 override public function get padding():Number {
67 return element.getStyle(Styles.LABEL_PADDING);
68 }
69
70 override public function get paddingLeft():Number {
71 return element.getStyle(Styles.LABEL_PADDING_LEFT);
72 }
73
74 override public function get paddingRight():Number {
75 return element.getStyle(Styles.LABEL_PADDING_RIGHT);
76 }
77
78 override public function get paddingTop():Number {
79 return element.getStyle(Styles.LABEL_PADDING_TOP);
80 }
81
82 override public function get paddingBottom():Number {
83 return element.getStyle(Styles.LABEL_PADDING_BOTTOM);
84 }
85
86 override public function get cornerRadius():Number {
87 return element.getStyle(Styles.LABEL_CORNER_RADIUS);
88 }
89
90 override public function get pointerLength():Number {
91 return element.getStyle(Styles.LABEL_POINTER_LENGTH);
92 }
93
94 override public function get pointerWidth():Number {
95 return element.getStyle(Styles.LABEL_POINTER_WIDTH);
96 }
97
98 override public function get direction():String {
99 return element.getStyle(Styles.LABEL_DIRECTION);
100 }
101
102 override public function get fill():Boolean {
103 return element.getStyle(Styles.LABEL_FILL);
104 }
105
106 override public function get fillColor():Number {
107 return element.getStyle(Styles.LABEL_FILL_COLOR);
108 }
109
110 override public function get fillAlpha():Number {
111 return element.getStyle(Styles.LABEL_FILL_ALPHA);
112 }
113
114 override public function get gradient():String {
115 return element.getStyle(Styles.LABEL_GRADIENT);
116 }
117
118 override public function get gradientColor():Number {
119 return element.getStyle(Styles.LABEL_GRADIENT_COLOR);
120 }
121
122 override public function get gradientAlpha():Number {
123 return element.getStyle(Styles.LABEL_GRADIENT_ALPHA);
124 }
125
126 override public function get contentXScale():Number {
127 return element.getStyle(Styles.LABEL_CONTENT_XSCALE);
128 }
129
130 override public function get contentYScale():Number {
131 return element.getStyle(Styles.LABEL_CONTENT_YSCALE);
132 }
133
134 override public function get outlineWidth():Number {
135 return element.getStyle(Styles.LABEL_OUTLINE_WIDTH);
136 }
137
138 override public function get outlineColor():Number {
139 return element.getStyle(Styles.LABEL_OUTLINE_COLOR);
140 }
141
142 override public function get outlineAlpha():Number {
143 return element.getStyle(Styles.LABEL_OUTLINE_ALPHA);
144 }
145 }
146 }
再自定义Node和NodeUI,使用这个Attachment代替TWaver自带的LabelAttachment:
自定义Node:
1 package {
2 import twaver.Node;
3
4 public class FTELabelNode extends Node {
5 public function FTELabelNode(id:Object=null) {
6 super(id);
7 }
8
9 public override function get elementUIClass():Class {
10 return FTELabelNodeUI;
11 }
12 }
13 }
自定义NodeUI:
1 package {
2 import twaver.Node;
3 import twaver.network.Network;
4 import twaver.network.ui.NodeUI;
5
6 public class FTELabelNodeUI extends NodeUI {
7
8 private var _labelAttachment:FTELabelAttachment = null;
9
10 public function FTELabelNodeUI(network:Network, node:Node) {
11 super(network, node);
12 }
13
14 override protected function checkLabelAttachment():void{
15 var label:String = this.network.getLabel(element);
16 if(label != null && label != ""){
17 if(this._labelAttachment == null){
18 this._labelAttachment = new FTELabelAttachment(this, false);
19 this.addAttachment(this._labelAttachment);
20 }
21 }else{
22 if(this._labelAttachment != null){
23 this.removeAttachment(this._labelAttachment);
24 this._labelAttachment = null;
25 }
26 }
27 }
28 }
29 }
30
最后,写个例子看看效果:
1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
3 xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
4 layout="absolute" width="100%" height="100%"
5 creationComplete="init()" backgroundColor="#FFFFFF" >
6 <mx:Script>
7 <![CDATA[
8 import twaver.Consts;
9 import twaver.ElementBox;
10 import twaver.IElement;
11 import twaver.Node;
12 import twaver.Styles;
13
14 private var box:ElementBox = new ElementBox();
15
16 private function init():void {
17 network.labelFunction = function (element:IElement):String {
18 var name:String = element.name;
19 if(element.getClient('vertical')) {
20 var result:String = '';
21 for(var i:int=0,n:int=name.length; i<n; i++) {
22 result += name.charAt(i) + '\n';
23 }
24 result = result.substr(0, result.length-1);
25 return result;
26 } else {
27 return name;
28 }
29 };
30
31 var node1:Node = new Node();
32 node1.location = new Point(100, 100);
33 node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
34 node1.setClient('vertical', true);
35 node1.name = '竖向文字Vertical Text';
36 box.add(node1);
37
38 var node2:Node = new FTELabelNode();
39 node2.location = new Point(300, 100);
40 node2.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
41 node2.name = '竖向文字Vertical Text';
42 box.add(node2);
43
44 network.elementBox = box;
45 }
46
47 private function changeFontSize():void {
48 box.forEach(function (element:IElement):void {
49 element.setStyle(Styles.LABEL_SIZE, element.getStyle(Styles.LABEL_SIZE) + 2);
50 });
51 }
52 ]]>
53 </mx:Script>
54 <mx:VBox width="100%" height="100%">
55 <mx:HBox width="100%" height="20">
56 <mx:Button label="Change Font Size" click="changeFontSize()"/>
57 </mx:HBox>
58 <twaver:Network id="network" width="100%" height="100%" />
59 </mx:VBox>
60 </mx:Application>
恩,这就是我想要的效果 :
更多关于FTE和TLF的信息,请参考Adobe官方文档:
TextLayoutFormat
TextFlow
textlayout
本文完整代码见附件:FTELabelAttachment