I just installed the Syntax Highlighter Javascript Library, which makes it easy to display easily-readable source code on websites. As my first test, here is a class I wrote in Actionscript 3 a couple of years ago, when I was deep in a dozen different projects, all built using Notepad++ and the MXMLC command-line compiler. The upshot of that was, no way to “trace” output from the .swf file. So I wrote my own, more or less. Here is the source code:
package { import flash.display.DisplayObjectContainer; import flash.display.Stage; import flash.display.Sprite; import flash.events.TimerEvent; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.Timer; public class InfoPanel extends Sprite { private var dragBar:Sprite; private var closeButton:Sprite; private var clearButton:Sprite; private var resizeButton:Sprite; private var outputWindow:TextField; private var timer:Timer; private var base:DisplayObjectContainer; private var isDragging:Boolean = false; private var isResizing:Boolean = false; private var dragMouseOffX:Number = 0; private var dragMouseOffY:Number = 0; private var resizeMouseOffX:Number = 0; private var resizeMouseOffY:Number = 0; private var w:Number = 0; private var h:Number = 0; private var bgc:Number; private var fgc:Number; private var outputFormat:TextFormat = new TextFormat("Courier New",11,0x33ff33,false,false,false,null,null,"left"); public function InfoPanel($base:DisplayObjectContainer,$w:Number = 150,$h:Number = 100,$bgc:Number=0x000000,$fgc:Number=0x66ff66):void { base = $base; w = $w; h = $h; bgc = $bgc; fgc = $fgc; outputFormat.color = fgc; graphics.lineStyle(0,0x666666,1); graphics.beginFill(bgc,1); graphics.drawRect(0,0,w,h); graphics.endFill(); dragBar = new Sprite(); dragBar.graphics.beginFill(0x666666,1); dragBar.graphics.drawRect(0,0,w,10); dragBar.graphics.endFill(); dragBar.buttonMode = true; dragBar.useHandCursor = true; dragBar.addEventListener(MouseEvent.MOUSE_DOWN,onDragMouseDown); dragBar.addEventListener(MouseEvent.MOUSE_UP,onDragMouseUp); dragBar.x = 0; dragBar.y = 0; addChild(dragBar); clearButton = new Sprite(); clearButton.graphics.lineStyle(0,0xcccccc,1) clearButton.graphics.beginFill(0x666666,1); clearButton.graphics.drawCircle(0,0,3); clearButton.graphics.endFill(); clearButton.x = w-15; clearButton.y = 5; clearButton.buttonMode = true; clearButton.useHandCursor = true; clearButton.addEventListener(MouseEvent.CLICK,onClearButtonClicked); addChild(clearButton); closeButton = new Sprite(); closeButton.graphics.beginFill(0xcccccc,1); closeButton.graphics.drawCircle(0,0,3); closeButton.graphics.endFill(); closeButton.x = w-5; closeButton.y = 5; closeButton.buttonMode = true; closeButton.useHandCursor = true; closeButton.addEventListener(MouseEvent.CLICK,onCloseButtonClicked); addChild(closeButton); resizeButton = new Sprite(); resizeButton.graphics.beginFill(0xcccccc,1); resizeButton.graphics.drawRect(0,0,6,6); resizeButton.graphics.endFill(); resizeButton.x = w-6; resizeButton.y = h-6; resizeButton.buttonMode = true; resizeButton.useHandCursor = true; resizeButton.addEventListener(MouseEvent.MOUSE_DOWN,onResizeMouseDown); resizeButton.addEventListener(MouseEvent.MOUSE_UP,onResizeMouseUp); addChild(resizeButton); outputWindow = new TextField(); outputWindow.width = w-10; outputWindow.height = h-20; outputWindow.x = 5; outputWindow.y = 15; outputWindow.selectable = true; outputWindow.wordWrap = true; outputWindow.multiline = true; outputWindow.text = "STATS"; outputWindow.setTextFormat(outputFormat); outputWindow.defaultTextFormat = outputFormat; addChild(outputWindow); timer = new Timer(25); timer.addEventListener(TimerEvent.TIMER,onTimer); } private function onTimer(e:TimerEvent):void { if(isDragging==true) dragMe(); if(isResizing==true) resizeMe(); e.updateAfterEvent(); } private function onDragMouseDown(e:MouseEvent):void { e.stopPropagation(); dragMouseOffX = e.target.mouseX; dragMouseOffY = e.target.mouseY; startMe(); isDragging = true; } private function onDragMouseUp(e:MouseEvent):void { isDragging = false; stopMe(); base.addChild(this); } private function onResizeMouseDown(e:MouseEvent):void { e.stopPropagation(); resizeMouseOffX = e.target.mouseX; resizeMouseOffY = e.target.mouseY; startMe(); isResizing = true; } private function onResizeMouseUp(e:MouseEvent):void { isResizing = false; stopMe(); } private function onCloseButtonClicked(e:MouseEvent):void { e.stopPropagation(); hideMe(); } private function onClearButtonClicked(e:MouseEvent):void { outputWindow.text = ""; } private function startMe():void { timer.start(); } private function stopMe():void { timer.stop(); } public function showMe():void { base.addChild(this); } public function hideMe():void { base.removeChild(this); } private function dragMe():void { x = stage.mouseX - dragMouseOffX; y = stage.mouseY - dragMouseOffY; } private function resizeMe():void { w = mouseX + 6 - resizeMouseOffX; h = mouseY + 6 - resizeMouseOffY; graphics.clear(); graphics.lineStyle(0,0x666666,1); graphics.beginFill(bgc,1); graphics.drawRect(0,0,w,h); graphics.endFill(); dragBar.graphics.clear(); dragBar.graphics.beginFill(0x666666,1); dragBar.graphics.drawRect(0,0,w,10); dragBar.graphics.endFill(); outputWindow.width = w - 10; outputWindow.height = h - 20; resizeButton.x = w - 6; resizeButton.y = h - 6 clearButton.x = w - 15; closeButton.x = w - 5; } public function update($s:*,$r:Boolean = false):void { if($r==true) { outputWindow.text = $s.toString(); } else { outputWindow.appendText("\n"+$s.toString()); } outputWindow.scrollV = outputWindow.maxScrollV; base.addChild(this); } } }
And it is called like this:
var info:InfoPanel = new InfoPanel(this); info.update("hello world");
After being created the InfoPanel can be positioned just like any other DisplayObject. It accepts up to five arguments, in this order:
parent:DisplayObjectContainer, width:Number, height:Number, backgroundColor:Number,textColor:Number
Of them, only the parent argument is required; the rest will revert to default values if left empty. The parent item must be a DisplayObjectContainer, such as the Stage, or a MovieClip or Sprite.
Once created, the InfoPanel can be moved, resized, cleared and closed with the mouse.
To update the content, use the following method call:
info.update("a string");
This will append a line break, then the string. To clear the info panel when updating it, use the method call as follows:
info.update("a string",true);
Be careful; once the content of the InfoPanel starts measuring in the many thousands of characters, updating it may start to bog down the Flash player, slowing down whatever else you are running.