/* This is the FlAniS -- Flash version of the AnimationS applet. This code is Copyright(C) 2008 by Tom Whittaker. You may use this for any lawful purpose, and we are not responsible for what you do with it. It was developed as an outcome of the VISIT Project and uses many classes from the VISITview collaborative training / distance learning tool. */ // this is compiled with the mxmlc using the flanis.mxml template... // package { import mx.controls.Button; import mx.controls.CheckBox; import mx.controls.ComboBox; import mx.controls.Label; import mx.controls.HSlider; import mx.controls.RadioButton; import mx.controls.RadioButtonGroup; import mx.controls.ProgressBar; import mx.controls.Alert; import mx.controls.TextArea; import mx.core.*; import mx.containers.HBox; import mx.containers.VBox; import mx.containers.Canvas; import mx.containers.Panel; import mx.core.UIComponent; import mx.events.SliderEvent; import mx.events.ListEvent; import mx.utils.StringUtil; import flash.display.Loader; import flash.display.Bitmap; import flash.display.Sprite; import flash.display.BitmapData; import flash.display.Graphics; import flash.events.Event; import flash.events.MouseEvent; import flash.events.KeyboardEvent; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.geom.Point; import flash.geom.Rectangle; import flash.geom.Matrix; import flash.geom.ColorTransform; import flash.printing.PrintJob; import flash.printing.PrintJobOptions; import flash.utils.Timer; import flash.events.TimerEvent; import flash.system.System; import flash.net.*; import flash.text.*; import mx.managers.PopUpManager; public class FlAniS { private var version:String; private var isDebug:Boolean; private var debugTextArea:TextArea; private var debugText:String; private var background:int; private var foreground:int; private var usingIP:Boolean; private var onlyShowFirstImage:Boolean; private var quietReload:Boolean; private var quietLoadem:Boolean; private var noControls:Boolean; private var useProgressBar:Boolean; private var isLoading:Boolean; private var countFrames:int; private var doExcludeCaching:Boolean; private var excludeCaching:String; private var useCaching:Boolean; private var useAntiCaching:Boolean; private var antiCacheIndex:int; private var baseStatic:Boolean; private var imageBase:String; private var s:Array; private var its:int; private var printButt:Button; private var zoom:Button; private var zoomLabelTrue:String; private var zoomLabelFalse:String; private var keepZoom:Boolean; private var activeZoom:Boolean; private var zoomScale:Number; private var zoomXFactor:Number; private var zoomYFactor:Number; private var zoomXBase:Number; private var zoomYBase:Number; private var isZooming:Boolean; private var enableZooming:Boolean; private var frameLabelWidth:int; private var frameLabelField:Label; private var hasFrameLabel:Boolean; private var frameLabels:Array; private var doLayoutControls:Boolean; private var useBottomControls:Boolean; private var looprock:Button; private var looprockLabelTrue:String; private var looprockLabelFalse:String; private var isLoopRock:Boolean; private var loopDirection:int; private var isRocking:Boolean; private var autoOnOff:Button; private var autoOnOffLabelTrue:String; private var autoOnOffLabelFalse:String; private var refreshRate:int; private var refreshTimer:Timer; private var autoState:Boolean; private var refresh:Button; private var isAutoRefresh:Boolean; private var showAllOnOff:Boolean; private var onOffWidth:int; private var onOffHeight:int; private var onOffSpacing:int; private var onOffState:Array; private var onOffBM:Bitmap; private var onOffRect:Rectangle; private var onOffBMD:BitmapData; private var onOffUI:UIComponent; private var onOffSprite:Sprite; private var onOffBackground:uint; private var isOnOff:Boolean; private var incFrame:int; private var stepBack:Button; private var stepForward:Button; private var isStepping:Boolean; private var stepFirst:Button; private var stepLast:Button; private var setFrameScrollbar:HSlider; private var setFrameText:String; private var isSetFrameScrollbar:Boolean; private var setFaderScrollbar:HSlider; private var faderToggle:Button; private var setFaderText:String; private var isFader:Boolean; private var faderFrame:int; private var faderImages:Array; private var isShowingFrames:Boolean; private var faderLabel:String; private var startFrame:int; private var basename:String; private var baseNumber:int; private var numFrames:int; private var currentFrame:int; private var deadFrames:int; private var firstFrame:int; private var lastFrame:int; private var enh:Array; private var enhNames:Array; private var enhanceChoice:ComboBox; private var madeEnhBitmaps:Boolean; private var enhBitmaps:Array; private var enhOverlay:int; private var location:Array; private var lat:Number; private var lon:Number; private var isLoc:Boolean; private var doingLoc:Boolean; private var locLabel:Label; private var locLabelDigits:int; private var locLabelFirst:String; private var locLabelSecond:String; private var xMouse:int; private var yMouse:int; private var locOffset:int; private var locButt:Button; private var locLabelOff:String; private var locLabelOn:String; private var locLabels:Array; private var vb:VBox; private var vbc:VBox; private var hb:HBox; private var controlBox:HBox; private var overlayControlBox:HBox; private var overlayControlContainer:VBox; private var speed:HSlider; private var dwell:int; private var addDwell:int; private var pauseOnLast:int; private var pausePercent:int; private var startstop:Button; private var startstopLabelTrue:String; private var startstopLabelFalse:String; private var bm:Bitmap; private var grandma:Application; private var mom:Canvas; private var sp:Sprite; private var timer:Timer; private var isLooping:Boolean; private var wasLooping:Boolean; private var isOverlay:Boolean; private var overlay:Array; private var overlayLinks:Array; private var overlayOrder:Array; private var overlayHidden:Array; private var overlayStatic:Array; private var overlayZoom:Array; private var overlayTransparentAmount:Array; private var ct:ColorTransform; private var transparency:int; private var numOverlayLabels:int; private var doneOverlayMask:Array; private var overlayMask:Array; private var probeValues:Array; private var probe:CheckBox; private var isProbe:Boolean; private var probeEnabled:Boolean; private var fnList:Array; private var biList:Array; private var olList:Array; private var hiresFnList:Array; private var fnDwell:Array; private var useDwell:Boolean; private var minDwell:int; private var drawingPaper:UIComponent; private var probePaper:UIComponent; private var pbar:ProgressBar; private var totalFrames:int; private var initialLoad:Boolean; private var imgList:Array; private var hiresImgList:Array; private var singleImage:Array; private var imgSmoothList:Array; private var imgUIBack:UIComponent; private var imgLoaderList:Array; private var hiresImgLoaderList:Array; private var imgLoaderInfoList:Array; private var hiresImgLoaderInfoList:Array; private var imgZoomableList:Array; private var preserve:Array; private var preRect:Rectangle; private var prePoint:Point; private var xImage:int; private var yImage:int; private var xLineEnd:int; private var yLineEnd:int; private var xScreen:int; private var yScreen:int; private var xMove:int; private var yMove:int; private var bmBack:Bitmap; private var bmBackground:BitmapData; private var bmBackCreated:Boolean private var bmBackLoaded:Array private var bmWidth:int; private var bmHeight:int; private var userWindowSize:Boolean; private var imgWidth:int; private var imgHeight:int; private var backSprite:Sprite; private var upperLeft:Point; private var imgRect:Rectangle; private var bmRect:Rectangle; private var isDragging:Boolean; private var isDrawingLine:Boolean; private var paramNames:Array; private var paramValues:Array; private var pLabels:Array // Application point of entry public static function main():void { var ec:FlAniS = new FlAniS(); ec.letterroll(); } /** letterroll() * * Why did we call it this? * */ public function letterroll():void { grandma = Application(Application.application); grandma.layout="absolute"; grandma.frameRate = 1; grandma.addEventListener(KeyboardEvent.KEY_DOWN, kclick); mom = new Canvas(); mom.height = grandma.height; mom.width = grandma.width; mom.setStyle("backgroundColor", grandma.getStyle("backgroundColor")); mom.setFocus(); grandma.addChild(mom); initialLoad = true; currentFrame = 0; bmBackCreated = false; zoomXFactor = 1.0; zoomYFactor = 1.0; isZooming = false; enableZooming = false; isDragging = false; isDrawingLine = false; isOverlay = false; incFrame = 1; isFader = false; preRect = new Rectangle(); prePoint = new Point(); madeEnhBitmaps = false; locOffset = 20; upperLeft = new Point(0,0); ct = new ColorTransform(1.0,1.0,1.0,1.0); version = "FlAniS version .98 beta"; trace(version); debugText = version+"\n"; // all set up must be serialized, since there is no // other way to do it...hmmmm.... var configLoader:URLLoader = new URLLoader(); configLoader.dataFormat = URLLoaderDataFormat.TEXT; configLoader.addEventListener(Event.COMPLETE, configLoaded); // see if name supplied in Flashvars var cfname:String = grandma.parameters.configFilename; if (cfname == null) cfname = "flanis.cfg"; trace ("config filename = "+cfname); debugText = debugText +"\nConfig filename = "+cfname; if (cfname.indexOf("?") > 0) { var bar:RegExp = /\|/g; cfname = cfname.replace(bar,"&"); debugText = debugText + "\nPHP config = "+cfname; } isLoading = false; var request:URLRequest = new URLRequest(cfname); // turn off caching ? request.requestHeaders.push(new URLRequestHeader("Cache-Control","no-store,max-age=0,no-cache,must-revalidate")); request.requestHeaders.push(new URLRequestHeader("Expires","Mon, 26 Jul 1997 05:00:00 GMT")); request.requestHeaders.push(new URLRequestHeader("Pragma","no-cache")); configLoader.load(request); } /** configLoaded(Event) * * after getting the "configFile", parse it and create lists for * getParameter() calls... * */ private function configLoaded(event:Event) : void { var cfl:URLLoader = URLLoader(event.target); var lines:Array = cfl.data.split("\n"); paramNames = new Array(); paramValues = new Array(); var eqinx:int = 0; // first, parse the basic requests for (var i:int=0; i "+ probeValues[p][pa][0]+" : "+probeValues[p][pa][1]); } } } } // now pick up params with no associated widget.... s = getParameter("rate"); dwell = 300; if (s != null) { dwell = 10000/parseInt(s[0]); if (dwell < 5 || dwell > 30000) { dwell = 300; debug("******** Invalid value for 'rate' parameter...."); } } s = getParameter("rocking"); if (s != null) { if (startsWith(s[0],"t") || startsWith(s[0],"T")) isRocking=true; } else { isRocking = false; } s = getParameter("loop"); s = getParameter("pause"); pauseOnLast = 0; if (s != null) { pauseOnLast = parseInt(s[0]); if (pauseOnLast < 0 || pauseOnLast > 20000) { pauseOnLast = 0; debug("******** Bad value for 'pause' parameter = "+pauseOnLast); } } s = getParameter("pause_percent"); pausePercent = 0; if (s != null) { pausePercent = parseInt(s[0]); if (pausePercent < 0 || pausePercent > 20000) { pausePercent = 0; debug("******** Bad value for 'pause' parameter = "+pausePercent); } } s = getParameter("transparency"); transparency = 0x00000000; if (s != null) { transparency = parseHex(s[0]); } s = getParameter("image_preserve"); if (s != null) { if (s.length % 4 != 0) { debug("******** image_preserve -- incorrect number of parameters!"); preserve = null; } else { preserve = new Array(s.length); for (i = 0; i 2) { if (ls[2].length > 0) locLabel.setStyle("fontSize", parseInt(ls[2]) ); if (ls.length > 3) { locLabelFirst = ls[3]; locLabelSecond = ls[4]; if (ls.length > 5) locLabelDigits = parseInt(ls[5]); } } } else { locLabel.opaqueBackground = background; locLabel.setStyle("color", foreground); } locLabel.x = 0; locLabel.y = 0; locLabel.visible = true; trace("location = "+location); } } userWindowSize = false; zoomXBase = 1.0; zoomYBase = 1.0; s = getParameter("image_window_size"); if (s != null) { bmWidth = parseInt(s[0]); bmHeight = parseInt(s[1]); bmRect = new Rectangle(0,0,bmWidth, bmHeight); userWindowSize = true; } // not implemented...yet.... s = getParameter("initial_zoom_state"); s = getParameter("fade"); s = getParameter("blank_screen"); s = getParameter("overlay_locations"); s = getParameter("image_size"); // control layout must be done after the image info is available... doLayoutControls = true; // timer for animation timer = new Timer(dwell); timer.addEventListener(TimerEvent.TIMER, showFrames, false, 0, true); s = getParameter("background_image"); onOffBackground = mom.getStyle("backgroundColor"); if (s != null) { onOffBackground = 0x00000000; var biSprite:Sprite = new Sprite(); var biBitmap:Bitmap = new Bitmap(new BitmapData(mom.width, mom.height)); biSprite.addChild(biBitmap); var biComp:UIComponent =new UIComponent(); biComp.addChild(biSprite); biComp.x = 0; biComp.y = 0; biComp.width = mom.width; biComp.height= mom.height; mom.addChild(biComp); var biName:String = s[0]; if (useAntiCaching) { antiCacheIndex = Math.random()*1677216.0; biName = biName+"?"+antiCacheIndex; } var biLoader:Loader = new Loader(); biLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { biBitmap.bitmapData = e.target.content.bitmapData; } ); biLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void { debug("******** Error loading background_image "+biName); } ); try { if (imageBase != null) { biName = imageBase+biName; } biLoader.load( new URLRequest(biName)); } catch (ibe:Error) { Alert.show("Unable to load background_image "+biName); } } // Now create the VBox to hold the UI components...and addChild it vb = new VBox(); vb.move(0,3); vb.width=mom.width; vb.setStyle("horizontalAlign","center"); vb.setStyle("verticalGap",2); mom.addChild(vb); enh = null; s = getParameter("no_enh"); if (s != null) { getImageFilenames(); } else { var enhLoader :URLLoader = new URLLoader(); enhLoader.dataFormat = URLLoaderDataFormat.TEXT; enhLoader.addEventListener(Event.COMPLETE, doneGettingEnhTab); enhLoader.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void { getImageFilenames(); } ); var enhName:String = "enh.tab"; s = getParameter("enhance_filename"); if (s != null) enhName = s[0]; try { if (useAntiCaching) { antiCacheIndex = Math.random()*1677216.0; enhName = "enh.tab?"+antiCacheIndex; } if (imageBase != null) enhName = imageBase+enhName; var request:URLRequest = new URLRequest(enhName); // turn off caching ? request.requestHeaders.push(new URLRequestHeader("Cache-Control","no-store,max-age=0,no-cache,must-revalidate")); request.requestHeaders.push(new URLRequestHeader("Expires","Mon, 26 Jul 1997 05:00:00 GMT")); request.requestHeaders.push(new URLRequestHeader("Pragma","no-cache")); enhLoader.load( request); } catch (ioe:Error) { Alert.show("Unable to load enhancement file: "+enhName+" Error: "+ioe); } } } /** getImageFilenames() * * come here to get the filenames (initially and/or on "refresh") * * if file_of_filenames, initiate read of that * * otherwise, just continue on.... * */ private function getImageFilenames():void { var s:Array = getParameter("file_of_filenames"); if (s != null) { fnList = new Array(); var fnLoader:URLLoader = new URLLoader(); fnLoader.dataFormat = URLLoaderDataFormat.TEXT; fnLoader.addEventListener(Event.COMPLETE, doneGettingFilenames); fnLoader.addEventListener(IOErrorEvent.IO_ERROR, errorLoadingFilenames); var fofName:String = s[0]; try { if (useAntiCaching && fofName.indexOf("?") == -1) { antiCacheIndex = Math.random()*1677216.0; fofName = StringUtil.trim(s[0])+"?"+antiCacheIndex; } if (imageBase != null) fofName = imageBase+fofName; var request:URLRequest = new URLRequest(fofName); // turn off caching ? request.requestHeaders.push(new URLRequestHeader("Cache-Control","no-store,max-age=0,no-cache,must-revalidate")); request.requestHeaders.push(new URLRequestHeader("Expires","Mon, 26 Jul 1997 05:00:00 GMT")); request.requestHeaders.push(new URLRequestHeader("Pragma","no-cache")); fnLoader.load( request); } catch (ioe:Error) { Alert.show("Unable to load configuration file: "+s[0]+" Error: "+ioe); } } else { doneGettingFilenames(null); } } /** doneGettingFilenames(Event) * * handler for file_of_filenames * * if called from elsewhere, just continue on to getImages() * */ private function doneGettingFilenames(event:Event) : void { if (event != null) { frameLabels = getParameter("frame_label"); if (frameLabels == null) frameLabels = new Array(); var fnl:URLLoader = URLLoader(event.target); var lines:Array = fnl.data.split("\n"); var firstTime:Boolean = true; // first push for background ([0]) fnList.push(new Array()); for (var i:int=0; i 0) { autoOnOff.label = autoOnOffLabelTrue; autoState = false; refreshTimer.stop(); } else { autoOnOff.label = autoOnOffLabelFalse; autoState = true; } if (tips != null) autoOnOff.toolTip = tips[cn]; autoOnOff.addEventListener(MouseEvent.CLICK, bclick); controlBox.addChild(autoOnOff); gotControls = true; } else if (s[cn] == "refresh") { refresh = new Button(); pLabels = getParameter("refresh_label"); if (pLabels == null) { refresh.label = "Refresh"; } else { refresh.label = pLabels[0]; if (pLabels.length == 2) { refresh.width = parseInt(pLabels[1]); } } refresh.addEventListener(MouseEvent.CLICK, bclick); if (tips != null) refresh.toolTip = tips[cn]; controlBox.addChild(refresh); gotControls = true; } else if (s[cn] == "location") { locButt = new Button(); locLabels = getParameter("location_labels"); if (locLabels == null) { locLabelOff = "Show Location"; locLabelOn = "Hide Location"; locButt.width = 100; } else { locLabelOff = locLabels[0]; locLabelOn = locLabels[1]; if (locLabels.length == 3) { locButt.width = parseInt(locLabels[2]); } } locButt.label = locLabelOff; isLoc = false; locButt.addEventListener(MouseEvent.CLICK, bclick); if (tips != null) locButt.toolTip = tips[cn]; locLabel.visible = false; controlBox.addChild(locButt); gotControls = true; } else if (s[cn] == "probe") { probe = new CheckBox(); pLabels = getParameter("probe_label"); if (pLabels == null) { probe.label = "Probe"; } else { probe.label = pLabels[0]; if (pLabels.length == 2) { probe.width = parseInt(pLabels[1]); } } probe.addEventListener(MouseEvent.CLICK, bclick); if (tips != null) probe.toolTip = tips[cn]; controlBox.addChild(probe); isProbe = true; probeEnabled = false; gotControls = true; } else if (s[cn] == "print" || s[cn] == "show") { printButt = new Button(); printButt.label = "Print"; var pbl:Array = getParameter("print_label"); if (pbl == null) pbl = getParameter("show_label"); if (pbl != null) printButt.label = pbl[0]; printButt.addEventListener(MouseEvent.CLICK, bclick); if (tips != null) printButt.toolTip = tips[cn]; if (isLooping) { printButt.enabled = false; } else { printButt.enabled = true; } controlBox.addChild(printButt); gotControls = true; } else if (s[cn] == "step") { stepBack = new Button(); stepBack.label="<"; stepBack.width=20; stepBack.addEventListener(MouseEvent.CLICK, bclick); stepForward = new Button(); stepForward.label=">"; stepForward.width=20; stepForward.addEventListener(MouseEvent.CLICK, bclick); isStepping = true; if (tips != null) stepBack.toolTip = tips[cn]; if (tips != null) stepForward.toolTip = tips[cn]; controlBox.addChild(stepBack); controlBox.addChild(stepForward); gotControls = true; } else if (s[cn] == "firstlast") { stepFirst = new Button(); stepFirst.label = "<|"; stepFirst.width = 30; stepFirst.addEventListener(MouseEvent.CLICK, bclick); stepLast = new Button(); stepLast.label = "|>"; stepLast.width = 30; stepLast.addEventListener(MouseEvent.CLICK, bclick); if (tips != null) stepFirst.toolTip = tips[cn]; if (tips != null) stepLast.toolTip = tips[cn]; controlBox.addChild(stepFirst); controlBox.addChild(stepLast); gotControls = true; } else if (s[cn] == "setframe") { setFrameScrollbar = new HSlider(); var sft:Array = getParameter("setframe_label"); setFrameText = "Set Frame *"; if (sft != null) setFrameText = StringUtil.trim(sft[0]); setFrameScrollbar.setStyle("labelOffset",0); //setFrameScrollbar.height=40; setFrameScrollbar.showDataTip = false; setFrameScrollbar.maximum = numFrames - 1; setFrameScrollbar.minimum = startFrame; setFrameScrollbar.liveDragging = true; setFrameScrollbar.addEventListener(SliderEvent.CHANGE,changeFrame); if (tips != null) setFrameScrollbar.toolTip = tips[cn]; //setFrameScrollbar.labels = [" ",setFrameText," "]; changeFrame(null); controlBox.addChild(setFrameScrollbar); gotControls = true; } else if (s[cn].indexOf("toggle") == 0) { var toggles:Array = getParameter("toggle_size"); if (s[cn].toLowerCase().indexOf("/showall") != -1) { showAllOnOff = true; } else { showAllOnOff = false; } onOffWidth = 10; onOffHeight = 10; onOffSpacing = 3; if (toggles != null) { onOffWidth = parseInt(toggles[0]); onOffHeight = parseInt(toggles[1]); if (toggles.length > 2) onOffSpacing = parseInt(toggles[2]); } onOffBMD = new BitmapData(numFrames*(onOffSpacing+onOffWidth), onOffHeight+3, true, onOffBackground); onOffBM = new Bitmap(onOffBMD); onOffSprite = new Sprite(); onOffSprite.addChild(onOffBM); onOffRect = new Rectangle(0,0,onOffWidth, onOffHeight); onOffUI = new UIComponent(); onOffUI.addChild(onOffSprite); onOffUI.height = onOffHeight+3; onOffUI.width = (onOffSpacing+onOffWidth)*numFrames; onOffState =new Array(); for (var nof:int = 0; nof