PageRenderTime 64ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/junkbyte/console/view/ConsolePanel.as

https://github.com/zeffrin/ZType
ActionScript | 325 lines | 261 code | 17 blank | 47 comment | 40 complexity | b177fc75d84e55f712adf1be29619243 MD5 | raw file
  1. /*
  2. *
  3. * Copyright (c) 2008-2010 Lu Aye Oo
  4. *
  5. * @author Lu Aye Oo
  6. *
  7. * http://code.google.com/p/flash-console/
  8. *
  9. *
  10. * This software is provided 'as-is', without any express or implied
  11. * warranty. In no event will the authors be held liable for any damages
  12. * arising from the use of this software.
  13. * Permission is granted to anyone to use this software for any purpose,
  14. * including commercial applications, and to alter it and redistribute it
  15. * freely, subject to the following restrictions:
  16. * 1. The origin of this software must not be misrepresented; you must not
  17. * claim that you wrote the original software. If you use this software
  18. * in a product, an acknowledgment in the product documentation would be
  19. * appreciated but is not required.
  20. * 2. Altered source versions must be plainly marked as such, and must not be
  21. * misrepresented as being the original software.
  22. * 3. This notice may not be removed or altered from any source distribution.
  23. *
  24. */
  25. package com.junkbyte.console.view {
  26. import com.junkbyte.console.ConsoleStyle;
  27. import com.junkbyte.console.ConsoleConfig;
  28. import flash.events.TextEvent;
  29. import com.junkbyte.console.Console;
  30. import flash.display.DisplayObject;
  31. import flash.display.Sprite;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. import flash.geom.Point;
  35. import flash.geom.Rectangle;
  36. import flash.text.TextField;
  37. import flash.text.TextFieldAutoSize;
  38. public class ConsolePanel extends Sprite {
  39. public static const DRAGGING:String = "DRAGGING";
  40. public static const SCALING:String = "SCALING";
  41. //[Event(name="TEXT_ROLL", type="flash.events.TextEvent")]
  42. private static const TEXT_ROLL:String = "TEXT_ROLL";
  43. private var _snaps:Array;
  44. private var _dragOffset:Point;
  45. private var _resizeTxt:TextField;
  46. //
  47. protected var console:Console;
  48. protected var bg:Sprite;
  49. protected var scaler:Sprite;
  50. protected var txtField:TextField;
  51. protected var minWidth:int = 18;
  52. protected var minHeight:int = 18;
  53. private var _movedFrom:Point;
  54. public var moveable:Boolean = true;
  55. public function ConsolePanel(m:Console) {
  56. console = m;
  57. bg = new Sprite();
  58. bg.name = "background";
  59. addChild(bg);
  60. }
  61. protected function get config() : ConsoleConfig {
  62. return console.config;
  63. }
  64. protected function get style() : ConsoleStyle {
  65. return console.config.style;
  66. }
  67. protected function init(w:Number,h:Number,resizable:Boolean = false, col:Number = -1, a:Number = -1, rounding:int = -1):void{
  68. bg.graphics.clear();
  69. bg.graphics.beginFill(col>=0?col:style.backgroundColor, a>=0?a:style.backgroundAlpha);
  70. if(rounding < 0) rounding = style.roundBorder;
  71. if(rounding <= 0) bg.graphics.drawRect(0, 0, 100, 100);
  72. else {
  73. bg.graphics.drawRoundRect(0, 0, rounding+10, rounding+10, rounding, rounding);
  74. bg.scale9Grid = new Rectangle(rounding*0.5, rounding*0.5, 10, 10);
  75. }
  76. scalable = resizable;
  77. width = w;
  78. height = h;
  79. }
  80. public function close():void {
  81. stopDragging();
  82. console.panels.tooltip();
  83. if(parent){
  84. parent.removeChild(this);
  85. }
  86. }
  87. //
  88. // SIZE
  89. //
  90. override public function set width(n:Number):void{
  91. if(n < minWidth) n = minWidth;
  92. if(scaler) scaler.x = n;
  93. bg.width = n;
  94. }
  95. override public function set height(n:Number):void{
  96. if(n < minHeight) n = minHeight;
  97. if(scaler) scaler.y = n;
  98. bg.height = n;
  99. }
  100. override public function get width():Number{
  101. return bg.width;
  102. }
  103. override public function get height():Number{
  104. return bg.height;
  105. }
  106. //
  107. // MOVING
  108. //
  109. public function registerSnaps(X:Array, Y:Array):void{
  110. _snaps = [X,Y];
  111. }
  112. protected function registerDragger(mc:DisplayObject, dereg:Boolean = false):void{
  113. if(dereg){
  114. mc.removeEventListener(MouseEvent.MOUSE_DOWN, onDraggerMouseDown);
  115. }else{
  116. mc.addEventListener(MouseEvent.MOUSE_DOWN, onDraggerMouseDown, false, 0, true);
  117. }
  118. }
  119. private function onDraggerMouseDown(e:MouseEvent):void{
  120. if(!stage || !moveable) return;
  121. //
  122. _resizeTxt = makeTF("positioningField", true);
  123. _resizeTxt.mouseEnabled = false;
  124. _resizeTxt.autoSize = TextFieldAutoSize.LEFT;
  125. addChild(_resizeTxt);
  126. updateDragText();
  127. //
  128. _movedFrom = new Point(x, y);
  129. _dragOffset = new Point(mouseX,mouseY); // using this way instead of startDrag, so that it can control snapping.
  130. _snaps = [[],[]];
  131. dispatchEvent(new Event(DRAGGING));
  132. stage.addEventListener(MouseEvent.MOUSE_UP, onDraggerMouseUp, false, 0, true);
  133. stage.addEventListener(MouseEvent.MOUSE_MOVE, onDraggerMouseMove, false, 0, true);
  134. }
  135. private function onDraggerMouseMove(e:MouseEvent = null):void{
  136. if(style.panelSnapping==0) return;
  137. // YEE HA, SNAPPING!
  138. var p:Point = returnSnappedFor(parent.mouseX-_dragOffset.x, parent.mouseY-_dragOffset.y);
  139. x = p.x;
  140. y = p.y;
  141. updateDragText();
  142. }
  143. private function updateDragText():void{
  144. _resizeTxt.text = "<low>"+x+","+y+"</low>";
  145. }
  146. private function onDraggerMouseUp(e:MouseEvent):void{
  147. stopDragging();
  148. }
  149. private function stopDragging():void{
  150. _snaps = null;
  151. if(stage){
  152. stage.removeEventListener(MouseEvent.MOUSE_UP, onDraggerMouseUp);
  153. stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDraggerMouseMove);
  154. }
  155. if(_resizeTxt && _resizeTxt.parent){
  156. _resizeTxt.parent.removeChild(_resizeTxt);
  157. }
  158. _resizeTxt = null;
  159. }
  160. public function moveBackSafePosition():void{
  161. if(_movedFrom != null){
  162. // This will only work if stage size is not altered OR stage.align is top left
  163. if(x+width<10 || (stage && stage.stageWidth<x+10) || y+height<10 || (stage && stage.stageHeight<y+20)) {
  164. x = _movedFrom.x;
  165. y = _movedFrom.y;
  166. }
  167. _movedFrom = null;
  168. }
  169. }
  170. //
  171. // SCALING
  172. //
  173. public function get scalable():Boolean{
  174. return scaler?true:false;
  175. }
  176. public function set scalable(b:Boolean):void{
  177. if(b && !scaler){
  178. scaler = new Sprite();
  179. scaler.name = "scaler";
  180. scaler.graphics.beginFill(0, 0);
  181. scaler.graphics.drawRect(-10, -18, 10, 18);
  182. scaler.graphics.endFill();
  183. scaler.graphics.beginFill(style.controlColor, style.backgroundAlpha);
  184. scaler.graphics.moveTo(0, 0);
  185. scaler.graphics.lineTo(-10, 0);
  186. scaler.graphics.lineTo(0, -10);
  187. scaler.graphics.endFill();
  188. scaler.buttonMode = true;
  189. scaler.doubleClickEnabled = true;
  190. scaler.addEventListener(MouseEvent.MOUSE_DOWN,onScalerMouseDown, false, 0, true);
  191. addChild(scaler);
  192. }else if(!b && scaler){
  193. if(contains(scaler)){
  194. removeChild(scaler);
  195. }
  196. scaler = null;
  197. }
  198. }
  199. private function onScalerMouseDown(e:Event):void{
  200. _resizeTxt = makeTF("resizingField", true);
  201. _resizeTxt.mouseEnabled = false;
  202. _resizeTxt.autoSize = TextFieldAutoSize.RIGHT;
  203. _resizeTxt.x = -4;
  204. _resizeTxt.y = -17;
  205. scaler.addChild(_resizeTxt);
  206. updateScaleText();
  207. _dragOffset = new Point(scaler.mouseX,scaler.mouseY); // using this way instead of startDrag, so that it can control snapping.
  208. _snaps = [[],[]];
  209. scaler.stage.addEventListener(MouseEvent.MOUSE_UP,onScalerMouseUp, false, 0, true);
  210. scaler.stage.addEventListener(MouseEvent.MOUSE_MOVE,updateScale, false, 0, true);
  211. dispatchEvent(new Event(SCALING));
  212. }
  213. private function updateScale(e:Event = null):void{
  214. var p:Point = returnSnappedFor(x+mouseX-_dragOffset.x, y+mouseY-_dragOffset.x);
  215. p.x-=x;
  216. p.y-=y;
  217. width = p.x<minWidth?minWidth:p.x;
  218. height = p.y<minHeight?minHeight:p.y;
  219. updateScaleText();
  220. }
  221. private function updateScaleText():void{
  222. _resizeTxt.text = "<low>"+width+","+height+"</low>";
  223. }
  224. public function stopScaling():void{
  225. onScalerMouseUp(null);
  226. }
  227. private function onScalerMouseUp(e:Event):void{
  228. scaler.stage.removeEventListener(MouseEvent.MOUSE_UP,onScalerMouseUp);
  229. scaler.stage.removeEventListener(MouseEvent.MOUSE_MOVE,updateScale);
  230. updateScale();
  231. _snaps = null;
  232. if(_resizeTxt && _resizeTxt.parent){
  233. _resizeTxt.parent.removeChild(_resizeTxt);
  234. }
  235. _resizeTxt = null;
  236. }
  237. //
  238. //
  239. public function makeTF(n:String, back:Boolean = false):TextField
  240. {
  241. var txt:TextField = new TextField();
  242. txt.name = n;
  243. txt.styleSheet = style.styleSheet;
  244. if(back){
  245. txt.background = true;
  246. txt.backgroundColor = style.backgroundColor;
  247. }
  248. return txt;
  249. }
  250. //
  251. //
  252. private function returnSnappedFor(X:Number,Y:Number):Point{
  253. return new Point(getSnapOf(X, true),getSnapOf(Y, false));
  254. }
  255. private function getSnapOf(v:Number, isX:Boolean):Number{
  256. var end:Number = v+width;
  257. var a:Array = _snaps[isX?0:1];
  258. var s:int = style.panelSnapping;
  259. for each(var ii:Number in a){
  260. if(Math.abs(ii-v)<s) return ii;
  261. if(Math.abs(ii-end)<s) return ii-width;
  262. }
  263. return v;
  264. }
  265. protected function registerTFRoller(field:TextField, overhandle:Function, linkHandler:Function = null):void{
  266. field.addEventListener(MouseEvent.MOUSE_MOVE, onTextFieldMouseMove, false, 0, true);
  267. field.addEventListener(MouseEvent.ROLL_OUT, onTextFieldMouseOut, false, 0, true);
  268. field.addEventListener(TEXT_ROLL, overhandle, false, 0, true);
  269. if(linkHandler != null) field.addEventListener(TextEvent.LINK, linkHandler, false, 0, true);
  270. }
  271. private static function onTextFieldMouseOut(e:MouseEvent):void{
  272. TextField(e.currentTarget).dispatchEvent(new TextEvent(TEXT_ROLL));
  273. }
  274. private static function onTextFieldMouseMove(e:MouseEvent):void{
  275. var field:TextField = e.currentTarget as TextField;
  276. var index:int;
  277. if(field.scrollH>0){
  278. // kinda a hack really :(
  279. var scrollH:Number = field.scrollH;
  280. var w:Number = field.width;
  281. field.width = w+scrollH;
  282. index = field.getCharIndexAtPoint(field.mouseX+scrollH, field.mouseY);
  283. field.width = w;
  284. field.scrollH = scrollH;
  285. }else{
  286. index = field.getCharIndexAtPoint(field.mouseX, field.mouseY);
  287. }
  288. var url:String = null;
  289. //var txt:String = null;
  290. if(index>0){
  291. // TextField.getXMLText(...) is not documented
  292. try{
  293. var X:XML = new XML(field.getXMLText(index,index+1));
  294. if(X.hasOwnProperty("textformat")){
  295. var txtformat:XML = X["textformat"][0] as XML;
  296. if(txtformat){
  297. url = txtformat.@url;
  298. //txt = txtformat.toString();
  299. }
  300. }
  301. }catch(err:Error){
  302. url = null;
  303. }
  304. }
  305. field.dispatchEvent(new TextEvent(TEXT_ROLL,false,false,url));
  306. }
  307. }
  308. }