| 1 | package com.longtailvideo.jwplayer.view.components { |
|---|
| 2 | import com.longtailvideo.jwplayer.utils.Draw; |
|---|
| 3 | |
|---|
| 4 | import flash.display.*; |
|---|
| 5 | import flash.events.*; |
|---|
| 6 | import flash.external.*; |
|---|
| 7 | import flash.geom.*; |
|---|
| 8 | import flash.text.*; |
|---|
| 9 | import flash.utils.*; |
|---|
| 10 | |
|---|
| 11 | public class DisplayIcon extends Sprite { |
|---|
| 12 | // Skin elements |
|---|
| 13 | private var _icon:DisplayObject; |
|---|
| 14 | private var _iconOver:DisplayObject; |
|---|
| 15 | private var _background:DisplayObject; |
|---|
| 16 | private var _backgroundOver:DisplayObject; |
|---|
| 17 | private var _capRight:DisplayObject; |
|---|
| 18 | private var _capRightOver:DisplayObject; |
|---|
| 19 | private var _capLeft:DisplayObject; |
|---|
| 20 | private var _capLeftOver:DisplayObject; |
|---|
| 21 | |
|---|
| 22 | private var _text:String; |
|---|
| 23 | private var _textFormat:TextFormat; |
|---|
| 24 | private var _textFormatOver:TextFormat; |
|---|
| 25 | private var _textField:TextField; |
|---|
| 26 | private var _textContainer:Sprite; |
|---|
| 27 | |
|---|
| 28 | private var _defaultBGWidth:Number; |
|---|
| 29 | |
|---|
| 30 | private var _container:Sprite; |
|---|
| 31 | private var _iconContainer:Sprite; |
|---|
| 32 | |
|---|
| 33 | private var _rotationTimer:Timer; |
|---|
| 34 | private var _rotationAngle:Number = 0; |
|---|
| 35 | |
|---|
| 36 | private var _noText:Boolean = false; |
|---|
| 37 | |
|---|
| 38 | public function DisplayIcon(elements:Object, textFormat:TextFormat, overFormat:TextFormat=null) { |
|---|
| 39 | _icon = elements.icon ? elements.icon : new Sprite(), |
|---|
| 40 | _iconOver = elements.iconOver; |
|---|
| 41 | |
|---|
| 42 | _background = elements.background ? elements.background : new Sprite(); |
|---|
| 43 | _backgroundOver = elements.backgroundOver; |
|---|
| 44 | |
|---|
| 45 | _capLeft = elements.capLeft ? elements.capLeft : new Sprite(); |
|---|
| 46 | _capLeftOver = elements.capLeftOver; |
|---|
| 47 | |
|---|
| 48 | _capRight = elements.capRight ? elements.capRight : new Sprite(); |
|---|
| 49 | _capRightOver = elements.capRightOver; |
|---|
| 50 | |
|---|
| 51 | _textFormat = textFormat; |
|---|
| 52 | _textFormatOver = overFormat ? overFormat : new TextFormat(textFormat.font, textFormat.size, textFormat.color, textFormat.bold); |
|---|
| 53 | |
|---|
| 54 | if (elements.icon && !(elements.capRight || elements.capLeft)) { |
|---|
| 55 | _noText = true; |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | _container = new Sprite(); |
|---|
| 59 | _container.mouseChildren = false; |
|---|
| 60 | _container.buttonMode = true; |
|---|
| 61 | this.mouseEnabled = false; |
|---|
| 62 | this.mouseChildren = true; |
|---|
| 63 | |
|---|
| 64 | buildIcon(); |
|---|
| 65 | |
|---|
| 66 | _container.addEventListener(MouseEvent.MOUSE_OVER, _overHandler); |
|---|
| 67 | _container.addEventListener(MouseEvent.MOUSE_OUT, _outHandler); |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | private function buildIcon():void { |
|---|
| 71 | _iconContainer = new Sprite(); |
|---|
| 72 | _textContainer = new Sprite(); |
|---|
| 73 | |
|---|
| 74 | _defaultBGWidth = _icon.width; |
|---|
| 75 | |
|---|
| 76 | _container.addChild(_capLeft); |
|---|
| 77 | if (_capLeftOver) _container.addChild(_capLeftOver); |
|---|
| 78 | |
|---|
| 79 | _container.addChild(_background); |
|---|
| 80 | if (_backgroundOver) _container.addChild(_backgroundOver); |
|---|
| 81 | |
|---|
| 82 | _container.addChild(_capRight); |
|---|
| 83 | if (_capRightOver) _container.addChild(_capRightOver); |
|---|
| 84 | |
|---|
| 85 | _iconContainer.addChild(_icon); |
|---|
| 86 | if (_iconOver) _iconContainer.addChild(_iconOver); |
|---|
| 87 | |
|---|
| 88 | _textField = new TextField(); |
|---|
| 89 | _textFormat.align = TextFormatAlign.LEFT; |
|---|
| 90 | _textField.selectable = false; |
|---|
| 91 | _textField.defaultTextFormat = _textFormat; |
|---|
| 92 | _container.addChild(_textField); |
|---|
| 93 | |
|---|
| 94 | _container.addChild(_iconContainer); |
|---|
| 95 | addChild(_container); |
|---|
| 96 | |
|---|
| 97 | _rotationTimer = new Timer(100); |
|---|
| 98 | _rotationTimer.addEventListener(TimerEvent.TIMER, rotationInterval); |
|---|
| 99 | |
|---|
| 100 | hover(false); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | private function redraw():void { |
|---|
| 104 | positionText(); |
|---|
| 105 | _background.x = _capLeft.width; |
|---|
| 106 | _textField.x = _background.x; |
|---|
| 107 | |
|---|
| 108 | _icon.x = _icon.width / -2; |
|---|
| 109 | _icon.y = _icon.height / -2; |
|---|
| 110 | align(_icon, _iconOver); |
|---|
| 111 | |
|---|
| 112 | _iconContainer.y = _background.height / 2; |
|---|
| 113 | |
|---|
| 114 | if (_noText) { |
|---|
| 115 | _iconContainer.x = _background.x + _background.width / 2; |
|---|
| 116 | } else { |
|---|
| 117 | _iconContainer.x = _textField.x + _textField.width + _icon.width / 2; |
|---|
| 118 | _background.width = Math.max(_defaultBGWidth, _textField.width + _iconContainer.width); |
|---|
| 119 | } |
|---|
| 120 | _capRight.x = _background.x + _background.width; |
|---|
| 121 | |
|---|
| 122 | align(_background, _backgroundOver); |
|---|
| 123 | align(_capRight, _capRightOver); |
|---|
| 124 | align(_capLeft, _capLeftOver); |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | private function align(disp1:DisplayObject, disp2:DisplayObject):void { |
|---|
| 128 | if (disp1 && disp2) { |
|---|
| 129 | disp2.x = disp1.x; |
|---|
| 130 | disp2.y = disp1.y; |
|---|
| 131 | disp2.width = disp1.width; |
|---|
| 132 | disp2.height = disp1.height; |
|---|
| 133 | } |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | public function set text(newText:String):void { |
|---|
| 137 | _text = newText; |
|---|
| 138 | if (!_text || _noText) { |
|---|
| 139 | _textField.visible = false; |
|---|
| 140 | _textField.width = _textField.height = 0; |
|---|
| 141 | redraw(); |
|---|
| 142 | return; |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | _textField.visible = true; |
|---|
| 146 | _textField.wordWrap = true; |
|---|
| 147 | _textField.width = 300; |
|---|
| 148 | _textField.text = _text.substr(0, 500).replace(":",":\n"); |
|---|
| 149 | |
|---|
| 150 | var elipses:Boolean = false; |
|---|
| 151 | if (_textField.numLines > 2) { |
|---|
| 152 | while(_textField.numLines > 2) { |
|---|
| 153 | elipses = true; |
|---|
| 154 | _textField.text = _textField.text.replace(/(.*).$/, "$1"); |
|---|
| 155 | } |
|---|
| 156 | if (elipses) { |
|---|
| 157 | _textField.text = _textField.text.substr(0, _textField.text.length-3); |
|---|
| 158 | _textField.text = _textField.text.substr(0, _textField.text.lastIndexOf(" ")) + "..."; |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | redraw(); |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | public function get text():String { |
|---|
| 166 | return _text; |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | private function positionText():void { |
|---|
| 170 | if (!_textField.text) return; |
|---|
| 171 | |
|---|
| 172 | var maxY:Number = -1; |
|---|
| 173 | var maxX:Number = -1; |
|---|
| 174 | var minY:Number = Number.MAX_VALUE; |
|---|
| 175 | for (var i:Number = 0; i < _textField.text.length; i++) { |
|---|
| 176 | var charDims:Rectangle = _textField.getCharBoundaries(i); |
|---|
| 177 | if (charDims.width * charDims.height > 0) { |
|---|
| 178 | maxX = Math.max(maxX, (charDims.x + charDims.width)); |
|---|
| 179 | maxY = Math.max(maxY, (charDims.y + charDims.height)); |
|---|
| 180 | minY = Math.min(minY, charDims.y); |
|---|
| 181 | } |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | if (maxX > 0 && maxY > 0) { |
|---|
| 185 | _textField.width = Math.round(maxX + 5); |
|---|
| 186 | _textField.height = Math.round(maxY + 5); |
|---|
| 187 | _textField.y = Math.round((_background.height - maxY) / 2 - minY); |
|---|
| 188 | } else { |
|---|
| 189 | _textField.height = _textField.textHeight; |
|---|
| 190 | } |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | private function _overHandler(evt:MouseEvent):void { |
|---|
| 194 | hover(true); |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | private function _outHandler(evt:MouseEvent):void { |
|---|
| 198 | hover(false); |
|---|
| 199 | } |
|---|
| 200 | |
|---|
| 201 | private function hover(state:Boolean):void { |
|---|
| 202 | if (_iconOver) { |
|---|
| 203 | _icon.visible = !state; |
|---|
| 204 | _iconOver.visible = state; |
|---|
| 205 | } |
|---|
| 206 | if (_backgroundOver) { |
|---|
| 207 | _background.visible = !state; |
|---|
| 208 | _backgroundOver.visible = state; |
|---|
| 209 | } |
|---|
| 210 | if (_capLeftOver) { |
|---|
| 211 | _capLeft.visible = !state; |
|---|
| 212 | _capLeftOver.visible = state; |
|---|
| 213 | } |
|---|
| 214 | if (_capRightOver) { |
|---|
| 215 | _capRight.visible = !state; |
|---|
| 216 | _capRightOver.visible = state; |
|---|
| 217 | } |
|---|
| 218 | _textField.textColor = Number(state ? _textFormatOver.color : _textFormat.color); |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | public function setRotation(angle:Number, interval:Number=100):void { |
|---|
| 222 | _rotationTimer.stop(); |
|---|
| 223 | _iconContainer.rotation = 0; |
|---|
| 224 | _rotationAngle = angle; |
|---|
| 225 | if (angle > 0) { |
|---|
| 226 | _rotationTimer.delay = interval; |
|---|
| 227 | _rotationTimer.start(); |
|---|
| 228 | } |
|---|
| 229 | redraw(); |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | private function rotationInterval(evt:TimerEvent):void { |
|---|
| 233 | _iconContainer.rotation = (_iconContainer.rotation + _rotationAngle) % 360; |
|---|
| 234 | } |
|---|
| 235 | |
|---|
| 236 | } |
|---|
| 237 | } |
|---|