/* Feel free to use, change, edit or laught hysterically at. Do at your own risk (epseically the laughing part) This is a very simple class that adds an output window to any DisplayObject. You can use this instead of trace() if you'd like to debug in the browser wihtout having to install the debut player and deal with FlashTracer or any of that nonsense. While I recommend removing all usage of this when your project is complete, you *COULD* simply set the instance of your DebugWindow enabled to false. This will hide it from view, unregister from all events and stop writing text to the output window. Removing it from the stage will also unregister the listener events by default -- USAGE TIPS -- SHIFT + SPACE - Toggle visibility of DebugWindow CTRL + UP - Scroll contents of DebugWindow up CTRL + DOWN - Scroll contents of DebugWindow down Double Click - Hide DebugWindow Click & Drag - Move DebugWindow There are plenty of other minor features I considered adding, but ultimately I wanted to keep it simple and lightweight. */ package com.baconandgames.utils{ import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFormat; import flash.ui.Keyboard; public class DebugWindow extends Sprite{ private static const BUFFER:int = 4; private var _tf:TextField; private var _fmt:TextFormat; private var _enabled:Boolean; private var _addedToStage:Boolean = false; /** * @param w Number Width of window * @param h Number Height of window * @optional textColor Number Color of text * @optional textSize int Size of text * @optional bkgdColor Number Background color of window * @optional borderColor Number Color of border * */ public function DebugWindow(w:Number,h:Number,textColor:Number=0x000000,textSize:int=10,bkgdColor:Number=0xffffff,borderColor:Number=0xff0000) { super(); this.graphics.lineStyle(1,borderColor); this.graphics.beginFill(bkgdColor); this.graphics.drawRect(0,0,w,h); this.graphics.endFill(); this.visible = false; this.doubleClickEnabled = true; this.enabled = true; _tf = new TextField(); _tf.multiline = true; _tf.wordWrap = true; _tf.mouseEnabled = false; _tf.x = DebugWindow.BUFFER; _tf.width = w - DebugWindow.BUFFER*2; _tf.height = h; addChild(_tf); _fmt = new TextFormat; _fmt.color = textColor; _fmt.size = textSize; _fmt.font = "Verdana"; _tf.setTextFormat(_fmt); registerListeners(); } /** * @param b Boolean * When set to true, listeners are enabled and text can be written to the output window. * When false, listeners are removed and text will NOT be written to the output window. **/ public function set enabled(b:Boolean):void{ _enabled = b; if(b){ this.visible = true; moveToTop(); registerListeners(); }else{ this.visible = false; unregisterListeners(); } } /** * @return Boolean returns true if enabled * */ public function get enabled():Boolean{ return _enabled; } /** * Boolean returns true if enabled * @param val String or number you would like to output, each call will put text on new line * * */ public function output(val):void{ if(this.enabled){ _tf.appendText("\n"+val); _tf.scrollV = _tf.numLines; _tf.setTextFormat(_fmt); } } /** * Works the same as output, but clears the output window before outputting content * @param val String or number you would like to output * * */ public function clearAndOutput(t):void{ clear(); output(t); } /** * Clears the output window * * */ public function clear():void{ output(""); } private function moveToTop():void{ if(this._addedToStage) this.parent.setChildIndex(this,this.parent.numChildren-1); } private function onAddedToStage(e:Event):void{ _addedToStage = true; registerListeners(); moveToTop(); } private function onRemovedFromStage(e:Event):void{ unregisterListeners(); } private function handleMouse(e:MouseEvent):void{ if(e.type == MouseEvent.MOUSE_DOWN){ this.startDrag(false); }else if(e.type == MouseEvent.MOUSE_UP){ this.stopDrag(); }else if(e.type == MouseEvent.DOUBLE_CLICK){ this.visible = false; } } private function onKey(e:KeyboardEvent):void{ if(e.shiftKey && e.keyCode == Keyboard.SPACE){ this.visible = !this.visible; moveToTop(); }else if(e.ctrlKey && e.keyCode == Keyboard.UP){ if(this.visible) _tf.scrollV -= 1; }else if(e.ctrlKey && e.keyCode == Keyboard.DOWN){ if(this.visible) _tf.scrollV += 1; } } private function registerListeners():void{ if(!this.hasEventListener(Event.ADDED_TO_STAGE)) addEventListener(Event.ADDED_TO_STAGE,onAddedToStage,false,0,true); if(!this.hasEventListener(Event.REMOVED_FROM_STAGE)) addEventListener(Event.REMOVED_FROM_STAGE,onRemovedFromStage,false,0,true); if(!this.hasEventListener(KeyboardEvent.KEY_DOWN) && this._addedToStage) this.stage.addEventListener(KeyboardEvent.KEY_DOWN,onKey,false,0,true); if(!this.hasEventListener(MouseEvent.MOUSE_UP)) addEventListener(MouseEvent.MOUSE_UP,handleMouse,false,0,true); if(!this.hasEventListener(MouseEvent.MOUSE_DOWN)) addEventListener(MouseEvent.MOUSE_DOWN,handleMouse,false,0,true); if(!this.hasEventListener(MouseEvent.DOUBLE_CLICK)) addEventListener(MouseEvent.DOUBLE_CLICK,handleMouse,false,0,true); } private function unregisterListeners():void{ if(this.hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE,onAddedToStage); if(this.hasEventListener(Event.REMOVED_FROM_STAGE)) removeEventListener(Event.REMOVED_FROM_STAGE,onRemovedFromStage); if(this.stage.hasEventListener(KeyboardEvent.KEY_DOWN)) this.stage.removeEventListener(KeyboardEvent.KEY_DOWN,onKey); if(this.hasEventListener(MouseEvent.MOUSE_UP)) removeEventListener(MouseEvent.MOUSE_UP,handleMouse); if(this.hasEventListener(MouseEvent.MOUSE_DOWN)) removeEventListener(MouseEvent.MOUSE_DOWN,handleMouse); if(this.hasEventListener(MouseEvent.DOUBLE_CLICK)) removeEventListener(MouseEvent.DOUBLE_CLICK,handleMouse); } } }