zoukankan      html  css  js  c++  java
  • 在TWaver Flex中实现垂直文字布局

    最近有客户提到如何让Network上网元的标签垂直显示,首先想到的就是每个字符之间插入一个回车。这个用Network#labelFunction就能达到目的:

    network.labelFunction = function (element:IElement):String {
    	var name:String = element.name;
    	if(element.getClient('vertical')) {
    		var result:String = '';
    		for(var i:int=0,n:int=name.length; i<n; i++) {
    			result += name.charAt(i) + '\n';
    		}
    		result = result.substr(0, result.length-1);
    		return result;
    	} else {
    		return name;
    	}
    };
    

      

    来段代码测试看看:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    				xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
    				layout="absolute" width="100%" height="100%"
    				creationComplete="init()" backgroundColor="#FFFFFF" >
    	<mx:Script>
    		<![CDATA[
    			import twaver.Consts;
    			import twaver.ElementBox;
    			import twaver.IElement;
    			import twaver.Node;
    			import twaver.Styles;
    
    			private var box:ElementBox = new ElementBox();
    
    			private function init():void {
    				network.labelFunction = function (element:IElement):String {
    					var name:String = element.name;
    					if(element.getClient('vertical')) {
    						var result:String = '';
    						for(var i:int=0,n:int=name.length; i<n; i++) {
    							result += name.charAt(i) + '\n';
    						}
    						result = result.substr(0, result.length-1);
    						return result;
    					} else {
    						return name;
    					}
    				};
    
    				var node1:Node = new Node();
    				node1.location = new Point(100, 100);
    				node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
    				node1.setClient('vertical', true);
    				node1.name = '竖向文字Vertical Text';
    				box.add(node1);
    
    				network.elementBox = box;
    			}
    		]]>
    	</mx:Script>
    	<twaver:Network id="network" width="100%" height="100%" />
    </mx:Application>
    

      

     运行效果如下:

         上面的方法很容易让文字垂直显示,但效果不是很理想,中英文混合时,英文也被一个字母一个字母地分开了。有没有更好的方案?答案是肯定的,借助于Flex的Flash Text Engine (FTE)和Text Layout Framework (TLF),可以很容易的让文字从上到下显示。

          先来看看一个小例子,设置TextLayoutFormat的blockProgression属性为BlockProgression.RL即可:

    package {
    	import flash.display.Sprite;
    
    	import flashx.textLayout.container.ContainerController;
    	import flashx.textLayout.conversion.TextConverter;
    	import flashx.textLayout.elements.TextFlow;
    	import flashx.textLayout.formats.BlockProgression;
    	import flashx.textLayout.formats.TextLayoutFormat;
    
    	public class StaticHelloWorld extends Sprite {
    		public function StaticHelloWorld() {
    			var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
    			textLayoutFormat.lineHeight = 30;
    			textLayoutFormat.locale = 'zh';
    			textLayoutFormat.blockProgression = BlockProgression.RL;
    
    			var text:String = "测试竖向文字,再看看English如何?";
    			var textFlow:TextFlow = TextConverter.importToFlow(text, TextConverter.PLAIN_TEXT_FORMAT);
    			textFlow.hostFormat = textLayoutFormat;
    			textFlow.flowComposer.addController(new ContainerController(this, 25, 200));
    			textFlow.flowComposer.updateAllControllers();
    		}
    	}
    }
    

      

     

    运行效果如下:

          的确这样效果就好多了,英文不会被一个字母一个字母地打断,然后我们自定义一个Attachment:

    package {
    	import flash.display.Sprite;
    	import flash.text.engine.FontPosture;
    	import flash.text.engine.FontWeight;
    
    	import flashx.textLayout.container.ContainerController;
    	import flashx.textLayout.elements.ParagraphElement;
    	import flashx.textLayout.elements.SpanElement;
    	import flashx.textLayout.elements.TextFlow;
    	import flashx.textLayout.formats.BlockProgression;
    	import flashx.textLayout.formats.TextDecoration;
    	import flashx.textLayout.formats.TextLayoutFormat;
    
    	import twaver.Styles;
    	import twaver.network.ui.BasicAttachment;
    	import twaver.network.ui.ElementUI;
    
    	public class FTELabelAttachment extends BasicAttachment {
    
    		private var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
    
    		public function FTELabelAttachment(elementUI:ElementUI, showInAttachmentCanvas:Boolean=false) {
    			super(elementUI, showInAttachmentCanvas);
    
    			this.textLayoutFormat.locale = 'zh';
    			this.textLayoutFormat.blockProgression = BlockProgression.RL;
    		}
    
    		override public function updateProperties():void {
    			super.updateProperties();
    
    			this.textLayoutFormat.fontFamily = element.getStyle(Styles.LABEL_FONT);
    			this.textLayoutFormat.color = element.getStyle(Styles.LABEL_COLOR);
    			this.textLayoutFormat.fontSize = element.getStyle(Styles.LABEL_SIZE);
    			this.textLayoutFormat.fontStyle = element.getStyle(Styles.LABEL_ITALIC) ? FontPosture.ITALIC : FontPosture.NORMAL;
    			this.textLayoutFormat.fontWeight = element.getStyle(Styles.LABEL_BOLD) ? FontWeight.BOLD : FontWeight.NORMAL;
    			this.textLayoutFormat.textDecoration = element.getStyle(Styles.LABEL_UNDERLINE ? TextDecoration.UNDERLINE : TextDecoration.NONE);
    
    			var textFlow:TextFlow = new TextFlow();
    			textFlow.hostFormat = this.textLayoutFormat;
    			var p:ParagraphElement = new ParagraphElement();
    			textFlow.addChild(p);
    			var span:SpanElement = new SpanElement();
    			span.text = network.getLabel(element);
    			p.addChild(span);
    
    			var fteLabel:Sprite = new Sprite();
    			this.content = fteLabel;
    			var containerController:ContainerController = new ContainerController(fteLabel, this.textLayoutFormat.fontSize, 1000);
    			textFlow.flowComposer.addController(containerController);
    			textFlow.flowComposer.updateAllControllers();
    		}
    
    		override public function get position():String {
    			return element.getStyle(Styles.LABEL_POSITION);
    		}
    
    		override public function get xOffset():Number {
    			return element.getStyle(Styles.LABEL_XOFFSET);
    		}
    
    		override public function get yOffset():Number {
    			return element.getStyle(Styles.LABEL_YOFFSET);
    		}
    
    		override public function get padding():Number {
    			return element.getStyle(Styles.LABEL_PADDING);
    		}
    
    		override public function get paddingLeft():Number {
    			return element.getStyle(Styles.LABEL_PADDING_LEFT);
    		}
    
    		override public function get paddingRight():Number {
    			return element.getStyle(Styles.LABEL_PADDING_RIGHT);
    		}
    
    		override public function get paddingTop():Number {
    			return element.getStyle(Styles.LABEL_PADDING_TOP);
    		}
    
    		override public function get paddingBottom():Number {
    			return element.getStyle(Styles.LABEL_PADDING_BOTTOM);
    		}
    
    		override public function get cornerRadius():Number {
    			return element.getStyle(Styles.LABEL_CORNER_RADIUS);
    		}
    
    		override public function get pointerLength():Number {
    			return element.getStyle(Styles.LABEL_POINTER_LENGTH);
    		}
    
    		override public function get pointerWidth():Number {
    			return element.getStyle(Styles.LABEL_POINTER_WIDTH);
    		}
    
    		override public function get direction():String {
    			return element.getStyle(Styles.LABEL_DIRECTION);
    		}
    
    		override public function get fill():Boolean {
    			return element.getStyle(Styles.LABEL_FILL);
    		}
    
    		override public function get fillColor():Number {
    			return element.getStyle(Styles.LABEL_FILL_COLOR);
    		}
    
    		override public function get fillAlpha():Number {
    			return element.getStyle(Styles.LABEL_FILL_ALPHA);
    		}
    
    		override public function get gradient():String {
    			return element.getStyle(Styles.LABEL_GRADIENT);
    		}
    
    		override public function get gradientColor():Number {
    			return element.getStyle(Styles.LABEL_GRADIENT_COLOR);
    		}
    
    		override public function get gradientAlpha():Number {
    			return element.getStyle(Styles.LABEL_GRADIENT_ALPHA);
    		}
    
    		override public function get contentXScale():Number {
    			return element.getStyle(Styles.LABEL_CONTENT_XSCALE);
    		}
    
    		override public function get contentYScale():Number {
    			return element.getStyle(Styles.LABEL_CONTENT_YSCALE);
    		}
    
    		override public function get outlineWidth():Number {
    			return element.getStyle(Styles.LABEL_OUTLINE_WIDTH);
    		}
    
    		override public function get outlineColor():Number {
    			return element.getStyle(Styles.LABEL_OUTLINE_COLOR);
    		}
    
    		override public function get outlineAlpha():Number {
    			return element.getStyle(Styles.LABEL_OUTLINE_ALPHA);
    		}
    	}
    }
    

      再自定义Node和NodeUI,使用这个Attachment代替TWaver自带的LabelAttachment:

    自定义Node:

    package {
    	import twaver.Node;
    
    	public class FTELabelNode extends Node {
    		public function FTELabelNode(id:Object=null) {
    			super(id);
    		}
    
    		public override function get elementUIClass():Class {
    			return FTELabelNodeUI;
    		}
    	}
    }
    

      自定义NodeUI:

    package {
    	import twaver.Node;
    	import twaver.network.Network;
    	import twaver.network.ui.NodeUI;
    
    	public class FTELabelNodeUI extends NodeUI {
    
    		private var _labelAttachment:FTELabelAttachment = null;
    
    		public function FTELabelNodeUI(network:Network, node:Node) {
    			super(network, node);
    		}
    
    		override protected function checkLabelAttachment():void{
    			var label:String = this.network.getLabel(element);
    			if(label != null && label != ""){
    				if(this._labelAttachment == null){
    					this._labelAttachment = new FTELabelAttachment(this, false);
    					this.addAttachment(this._labelAttachment);
    				}
    			}else{
    				if(this._labelAttachment != null){
    					this.removeAttachment(this._labelAttachment);
    					this._labelAttachment = null;
    				}
    			}
    		}
    	}
    }
    

      最后,写个例子看看效果:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    				xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
    				layout="absolute" width="100%" height="100%"
    				creationComplete="init()" backgroundColor="#FFFFFF" >
    	<mx:Script>
    		<![CDATA[
    			import twaver.Consts;
    			import twaver.ElementBox;
    			import twaver.IElement;
    			import twaver.Node;
    			import twaver.Styles;
    
    			private var box:ElementBox = new ElementBox();
    
    			private function init():void {
    				network.labelFunction = function (element:IElement):String {
    					var name:String = element.name;
    					if(element.getClient('vertical')) {
    						var result:String = '';
    						for(var i:int=0,n:int=name.length; i<n; i++) {
    							result += name.charAt(i) + '\n';
    						}
    						result = result.substr(0, result.length-1);
    						return result;
    					} else {
    						return name;
    					}
    				};
    
    				var node1:Node = new Node();
    				node1.location = new Point(100, 100);
    				node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
    				node1.setClient('vertical', true);
    				node1.name = '竖向文字Vertical Text';
    				box.add(node1);
    
    				var node2:Node = new FTELabelNode();
    				node2.location = new Point(300, 100);
    				node2.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
    				node2.name = '竖向文字Vertical Text';
    				box.add(node2);
    
    				network.elementBox = box;
    			}
    
    			private function changeFontSize():void {
    				box.forEach(function (element:IElement):void {
    					element.setStyle(Styles.LABEL_SIZE, element.getStyle(Styles.LABEL_SIZE) + 2);
    				});
    			}
    		]]>
    	</mx:Script>
    	<mx:VBox width="100%" height="100%">
    		<mx:HBox width="100%" height="20">
    			<mx:Button label="Change Font Size" click="changeFontSize()"/>
    		</mx:HBox>
    		<twaver:Network id="network" width="100%" height="100%" />
    	</mx:VBox>
    </mx:Application>
    

      

     恩,这就是我想要的效果:

    更多关于FTE和TLF的信息,请参考Adobe官方文档:

    TextLayoutFormat

    TextFlow

    Textlayout

    本文完整代码见附件:FTELabelAttachment

  • 相关阅读:
    纯win32实现PNG图片透明窗体
    win32用GDI+加载png图片作为背景图
    vc 制作图片资源dll
    wav文件格式分析详解
    VC++ WIN32 sdk实现按钮自绘详解.
    PNG文件结构分析 ---Png解析
    vc/mfc获取rgb图像数据后动态显示及保存图片的方法
    ffmpeg解码流程
    移植ffmpeg到VC环境心得
    Java
  • 原文地址:https://www.cnblogs.com/twaver/p/2493884.html
Copyright © 2011-2022 走看看