DAN ZEN EXPO - CODE EXHIBIT -
KITTY TARTAN
package source
{
import com.danzen.effects.Tartan;
import com.danzen.effects.TartanShow;
import com.danzen.frameworks.Easy;
import com.danzen.frameworks.zenconfirm.ConfirmID;
import com.danzen.frameworks.zenconfirm.ConfirmPurchases;
import com.danzen.frameworks.zenconfirm.ConfirmReceive;
import com.danzen.interfaces.AIRPicDrop;
import com.danzen.interfaces.Picture;
import flash.display.Sprite;
import flash.events.*;
import flash.filters.DropShadowFilter;
import flash.utils.Timer;
public class KittyTartan extends Sprite
{
internal var picture:Picture;
internal var show:TartanShow;
public var sW:Number;
public var sH:Number;
private var kittyInterface:KittyInterface;
private var logo:Logo;
private var buttons:Buttons;
internal var startTart:Tartan;
internal var readyStatus:Boolean = false;
private const UPLOADS_PER_APP:Number = 4;
private var myConfirm:ConfirmReceive;
internal var myPurchases:ConfirmPurchases;
private var myConfirmID:ConfirmID;
private var picDrop:AIRPicDrop;
public function KittyTartan()
{
trace ("hi from KittyTartan");
sW = stage.stageWidth;
sH = stage.stageHeight;
startTart = new Tartan([15790320,2365452,5520432,8678484,14208192,11047044], [12,12,141,3,160,197], sW, sH);
addChild(startTart);
kittyInterface = new KittyInterface();
addChild(kittyInterface);
// always set up to receive another download confirmation (would give 4 more uploads)
myConfirm = new ConfirmReceive("kittytartan", "kittytartan.com");
myConfirm.addEventListener(ConfirmReceive.COMPLETE, confirm);
// ConfirmPurchases is a wrapper for shared objects and has a data property for specifics
// first parameter is global purchase scope to help prevent mischief
// second parameter is local purchase scope
myPurchases = new ConfirmPurchases("danzen", "kittytartan");
// ConfirmID is a wrapper for a shared object that holds an id
myConfirmID = new ConfirmID("kittytartan");
myPurchases.clear();
myConfirmID.clear();
// if we have an id then go to ready else we wait for myConfirm to confirm us and add an id
if (myConfirmID.id) {
ready();
} else {
kittyInterface.wait();
}
}
private function confirm(e:Event):void {
if (e.target.status == ConfirmReceive.BAD) {
kittyInterface.error();
return;
} else {
// check to see if we should add uploads
if (myPurchases.addID(e.target.data.pid)) {
if (!myPurchases.data.uploads) {myPurchases.data.uploads = 0;}
myPurchases.data.uploads += UPLOADS_PER_APP;
if (readyStatus) {
kittyInterface.uploadsAdded();
}
}
if (!myConfirmID.id) {
myConfirmID.id = myConfirmID.randomID();
myConfirmID.record("http://kittytartan.com/tartan/record.php?rand="+Math.random(), {tid:myConfirmID.id});
myConfirmID.addEventListener(Event.COMPLETE, idRecorded);
}
if (!readyStatus) {ready();}
}
}
private function idRecorded(e:Event):void {
trace ("id recorded " + myConfirmID.id);
}
private function ready():void {
kittyInterface.start();
picDrop = new AIRPicDrop(this, ["jpg", "jpeg", "gif", "png"]);
picDrop.addEventListener(AIRPicDrop.PIC_READY, getPicture);
readyStatus = true;
}
// called from first close button in KittyInterface
internal function startShow():void {
// to do
// need to make dropping picture do this
// also need to make sure it works with consecutive pictures - close show open it again
//getPicture("http://www.cs.brown.edu/orgs/artemis/2012/catsoftheworld/lime-cat.jpg");
}
private function getPicture(e:Event):void {
if (picture) {
removeChild(picture);
picture.removeEventListener(Picture.PIC_READY, getTartans);
}
// Picture extends a Sprite, loads an image into itself and gets a palatte (colors property)
// receives url:String, paletteSize:Number
picture = new Picture(picDrop.pic, 8);
picture.addEventListener(Picture.PIC_READY, getTartans);
}
private function getTartans(e:Event):void {
if (contains(startTart)) {
removeChild(startTart);
}
if (show) {
show.dispose();
removeChild(show);
}
show = new TartanShow(picture.colors, sW, sH)
addChild(show);
setPic(picture);
setChildIndex(kittyInterface, numChildren-1);
}
private function setPic(pic:Sprite):void {
// reduce pic size and center it to start
var scale:Number = 2;
if (pic.width > sW/2 || pic.height > sH/2) {
if (pic.width/sW > pic.height/sH) {
pic.height = sW/scale/pic.width*pic.height;
pic.width=sW/scale;
} else {
pic.width = sH/scale/pic.height*pic.width;
pic.height=sH/scale;
}
}
pic.x = (sW-pic.width)/2;
pic.y = (sH-pic.height)/2;
pic.filters = [new DropShadowFilter(4,45,0,.7,16,16,1)];
addChild(pic);
Easy.drag(pic,0,0,sW,sH,true,false);
kittyInterface.picReady();
}
}
}
package source
{
import com.adobe.images.JPGEncoder;
import com.danzen.effects.TartanShow;
import com.danzen.effects.TartanSpec;
import com.danzen.interfaces.RollFilter;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.net.navigateToURL;
import flash.printing.PrintJob;
import flash.printing.PrintJobOrientation;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.Timer;
public class KittyInterface extends MovieClip
{
private var kt:KittyTartan;
private var show:TartanShow;
private var logo:Logo;
private var buttons:Buttons;
private var help:Help;
private var form:Form;
private var alert:Alert;
private var sW:Number;
private var sH:Number;
private var firstClose:Boolean = true;
private var myFormat:TextFormat = new TextFormat();
public function KittyInterface() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
kt = KittyTartan(parent);
sW = kt.sW;
sH = kt.sH;
logo = new Logo();
logo.x = 30;
logo.y = sH - logo.height - 24;
logo.alpha = .7;
logo.buttonMode = true;
logo.addEventListener(MouseEvent.CLICK, clickLogo);
buttons = new Buttons();
buttons.x = logo.x + logo.width + 30;
buttons.y = sH - buttons.height - 24;
buttons.alpha = .7;
buttons.visible = false;
buttons.butPics.mouseEnabled = false;
buttons.butPics.mouseChildren = false;
rolls(buttons);
buttons.addEventListener(MouseEvent.CLICK, doButtons);
help = new Help();
help.x = (sW-help.width)/2;
help.y = (sH-help.height)/2;
help.filters = [new DropShadowFilter(4,45,0,.5)];
help.closeBut.visible = false;
rolls(help.closeBut);
help.closeBut.addEventListener(MouseEvent.CLICK, doHelpClose);
new RollFilter(help.danzen, new GlowFilter(0xffccff, .3, 14, 14));
help.danzen.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {navigateToURL(new URLRequest("http://danzen.com"), "danzen");});
myFormat.size = 20;
myFormat.font = "Verdana";
myFormat.color = 0x666666;
myFormat.blockIndent = 10;
form = new Form();
form.x = (sW-form.width)/2;
form.y = (sH-form.height)/2;
form.filters = [new DropShadowFilter(4,45,0,.5)];
rolls(form.closeBut);
rolls(form.submitBut);
var fields:Array = [form.nameText, form.cityText, form.countryText, form.descriptionText, form.thoughtsText];
for (var i:uint=0; i<fields.length; i++) {
fields[i].setStyle("textFormat", myFormat);
}
form.closeBut.addEventListener(MouseEvent.CLICK, doFormClose);
form.submitBut.addEventListener(MouseEvent.CLICK, doFormSubmit);
alert = new Alert();
alert.x = (sW-alert.width)/2;
alert.y = (sH-alert.height)/2;
alert.filters = [new DropShadowFilter(4,45,0,.5)];
rolls(alert.closeBut);
rolls(alert.questionBut);
alert.questionBut.visible = false;
alert.closeBut.addEventListener(MouseEvent.CLICK, doAlertClose);
alert.questionBut.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {navigateToURL(new URLRequest("http://kittytartan.com/tartan/kitty/"), "danzen");});
kt.stage.addEventListener(KeyboardEvent.KEY_DOWN, doKeyDown);
kt.stage.addEventListener(KeyboardEvent.KEY_UP, doKeyUp);
}
////// internal state functions //////
internal function start():void {
if (contains(alert)) {
alert.questionBut.visible = false;
alert.closeBut.visible = true;
alert.gotoAndStop(1);
removeChild(alert);
}
addChild(logo);
addChild(buttons);
addChild(help);
}
internal function wait():void {
alert.alertText.gotoAndStop(3);
alert.questionBut.visible = true;
alert.closeBut.visible = false;
addChild(alert);
}
internal function picReady():void {
if (contains(help)) {
removeChild(help);
help.closeBut.visible = true;
}
if (contains(form)) {
removeChild(form);
}
if (contains(alert)) {
removeChild(alert);
}
if (logo.buttonMode == false) {
logo.buttonMode = true;
logo.addEventListener(MouseEvent.CLICK, clickLogo);
}
if (buttons.butPics.pauseButPic.currentFrame == 2) {
buttons.butPics.pauseButPic.gotoAndStop(1);
}
}
internal function error():void {
if (kt.picture) {
kt.picture.visible = false;
buttons.visible = false;
logo.buttonMode = false;
logo.removeEventListener(MouseEvent.CLICK, clickLogo);
alert.closeBut.visible = true;
alert.closeBut.play();
alert.questionBut.play();
} else {
alert.closeBut.visible = false;
}
alert.alertText.gotoAndStop(4);
alert.questionBut.visible = true;
if (!contains(alert)) {addChild(alert);}
if (contains(help)) {removeChild(help);}
if (contains(form)) {removeChild(form);}
}
internal function noUploads():void {
alert.alertText.gotoAndStop(5);
alert.closeBut.gotoAndPlay(1);
alert.questionBut.gotoAndPlay(1);
alert.questionBut.visible = true;
alert.closeBut.visible = true;
if (!contains(alert)) {addChild(alert);}
}
internal function uploadsAdded():void {
if (kt.picture) {
kt.picture.visible = false;
buttons.visible = false;
logo.buttonMode = false;
logo.removeEventListener(MouseEvent.CLICK, clickLogo);
alert.closeBut.visible = true;
alert.closeBut.play();
alert.questionBut.play();
} else {
alert.closeBut.visible = false;
}
alert.alertText.gotoAndStop(6);
alert.closeBut.gotoAndPlay(1);
alert.questionBut.visible = false;
alert.closeBut.visible = true;
if (!contains(alert)) {addChild(alert);}
if (contains(help)) {removeChild(help);}
if (contains(form)) {removeChild(form);}
}
////// window close functions //////
private function doAlertClose(e:MouseEvent):void {
removeChild(alert);
if (kt.readyStatus) {
logo.buttonMode = true;
logo.addEventListener(MouseEvent.CLICK, clickLogo);
if (kt.picture) {kt.picture.visible = true;}
}
}
private function doHelpClose(e:MouseEvent):void {
if (!kt.picture) {return;}
/*
if (firstClose) {
firstClose = false;
kt.startShow();
}
*/
removeChild(help);
logo.buttonMode = true;
logo.addEventListener(MouseEvent.CLICK, clickLogo);
kt.picture.visible = true;
}
private function doFormClose(e:MouseEvent):void {
removeChild(form);
logo.buttonMode = true;
logo.addEventListener(MouseEvent.CLICK, clickLogo);
kt.picture.visible = true;
}
////// buttons and key events //////
private function doButtons(e:MouseEvent):void {
show = kt.show;
if (!show) return;
switch (e.target.name) {
case "leftBut":
toggleShow(); toggleShow();
show.prev();
break;
case "rightBut":
toggleShow(); toggleShow();
show.next();
break;
case "pauseBut":
toggleShow();
break;
case "printBut":
printPicture();
break;
case "postBut":
show.pause();
if (kt.myPurchases.data.uploads <= 0) {
noUploads();
} else {
form.closeBut.play();
form.submitBut.play();
form.uploadsText.text = String(kt.myPurchases.data.uploads);
addChild(form);
}
kt.picture.visible = false;
buttons.visible = false;
logo.buttonMode = false;
logo.removeEventListener(MouseEvent.CLICK, clickLogo);
break;
case "helpBut":
show.pause();
help.closeBut.visible = true;
help.closeBut.play();
addChild(help);
kt.picture.visible = false;
buttons.visible = false;
logo.buttonMode = false;
logo.removeEventListener(MouseEvent.CLICK, clickLogo);
}
}
private function doKeyDown(e:KeyboardEvent):void {
show = kt.show;
if (!show) return;
if (contains(form)) return;
switch (e.keyCode) {
case Keyboard.LEFT:
toggleShow();
toggleShow();
show.prev();
buttons.leftBut.gotoAndStop(3);
break;
case Keyboard.RIGHT:
toggleShow();
toggleShow();
show.next();
buttons.rightBut.gotoAndStop(3);
break;
case Keyboard.SPACE:
toggleShow();
buttons.pauseBut.gotoAndStop(3);
break;
case 76: // l
logo.visible = !logo.visible;
break;
}
}
private function doKeyUp(e:KeyboardEvent):void {
if (!show) return;
buttons.leftBut.gotoAndStop(1);
buttons.rightBut.gotoAndStop(1);
buttons.pauseBut.gotoAndStop(1);
}
////// Printing and Submitting //////
private function printPicture():void {
var bmd:BitmapData;
var bm:Bitmap;
var matrix:Matrix;
var sprite:Sprite;
var newW:Number;
var newH:Number;
var scale:Number;
var myPrintJob:PrintJob = new PrintJob();
show.pause();
myPrintJob.orientation = PrintJobOrientation.LANDSCAPE;
myPrintJob.start();
buttons.visible = false;
if (myPrintJob.printableArea.width/sW > myPrintJob.printableArea.height/sH) {
newH = sW/myPrintJob.printableArea.width*sH;
newW=myPrintJob.printableArea.width;
} else {
newW = sH/myPrintJob.printableArea.height*sW;
newH=myPrintJob.printableArea.height;
}
scale = myPrintJob.printableArea.width/sW;
bmd = new BitmapData(newW, newH);
matrix = new Matrix();
matrix.scale(scale, scale);
bmd.draw(kt,matrix);
sprite = new Sprite();
bm = new Bitmap(bmd);
sprite.addChild(bm);
addChild(sprite);
try {
myPrintJob.addPage(sprite);
}
catch (e:Error) {
}
sprite.removeChild(bm);
bm = null;
removeChild(sprite);
sprite = null;
buttons.visible = true;
myPrintJob.send();
myPrintJob = null;
}
private function doFormSubmit(e:MouseEvent):void {
if (form.nameText.text == "" || form.nameText.text == "Enter Name!") {
form.nameText.text = "Enter Name!";
return;
}
addChild(alert);
alert.closeBut.play();
alert.alertText.gotoAndStop(1);
removeChild(form);
var delayTimer:Timer = new Timer(500, 1);
delayTimer.start();
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {sendPicture();});
}
private function sendPicture():void {
show.pause();
var tid:String = String(new Date().time);
// create specs jpg and send to cloud
var tbd:BitmapData = new BitmapData(600,500,false,0xFFFFFF);
var tm:Matrix = new Matrix();
var colorNames:Array;
tm.scale(.7, .7);
tbd.draw(show.tartans, tm);
var spec:TartanSpec = new TartanSpec(show.currentTartan, new Bitmap(tbd));
addChild(spec);
var smd:BitmapData = new BitmapData(spec.width, spec.height);
smd.draw(spec);
removeChild(spec);
colorNames = spec.colorNames; // gets list of colors from spec for blog tags
spec = null;
var myEncoder:JPGEncoder = new JPGEncoder(80);
var stream:ByteArray = myEncoder.encode(smd);
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var jpgURLRequest:URLRequest;
var urlLoader:URLLoader;
var varsString:String = "id="+tid+"&type=kitty";
jpgURLRequest = new URLRequest("http://www.danzen.com/tartan/spec.php?"+varsString);
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = stream;
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, imageComplete);
urlLoader.load(jpgURLRequest);
// create tartan jpg, send to cloud and send e-mail
var bmd:BitmapData;
var matrix:Matrix;
var newW:Number;
var newH:Number;
var scale:Number;
newW = 770;
newH = sH*770/sW;
scale = 770/sW;
bmd = new BitmapData(newW, newH);
matrix = new Matrix();
matrix.scale(scale, scale);
buttons.visible = false;
alert.visible = false;
kt.picture.visible = true;
bmd.draw(kt,matrix);
kt.picture.visible = false;
alert.visible = true;
myEncoder = new JPGEncoder(80);
stream = myEncoder.encode(bmd);
header = new URLRequestHeader("Content-type", "application/octet-stream");
var vars:Array = ["name","city","country","description","thoughts"];
var obj:Object = {};
for (var i:uint = 0; i < vars.length; i++) {
obj[vars[i]] = form[vars[i]+"Text"].text;
}
varsString = "";
for (i = 0; i < vars.length; i++) {
varsString += vars[i] + "="+escape(obj[vars[i]])+"&"
}
varsString += "id="+tid+"&uid=12345&type=kitty&colors="+escape(colorNames.join(","));
jpgURLRequest = new URLRequest("http://www.danzen.com/tartan/image.php?"+varsString);
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = stream;
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, imageComplete);
urlLoader.load(jpgURLRequest);
function imageComplete(e:Event):void {
trace (e.target.data);
}
alert.alertText.gotoAndStop(2);
for (i = 0; i < vars.length; i++) {
form[vars[i]+"Text"].text = "";
}
kt.myPurchases.data.uploads --;
form.uploadsText.text = String(kt.myPurchases.data.uploads);
}
////// helpers //////
private function toggleShow():void {
if (show.running) {
show.pause();
buttons.butPics.pauseButPic.gotoAndStop(2);
} else {
show.resume();
buttons.butPics.pauseButPic.gotoAndStop(1);
}
}
private function rolls(c:Sprite):void {
c.addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent):void {MovieClip(e.target).gotoAndStop(2);});
c.addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent):void {MovieClip(e.target).gotoAndStop(1);});
c.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {MovieClip(e.target).gotoAndStop(3);});
c.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {MovieClip(e.target).gotoAndStop(2);});
}
private function clickLogo(e:MouseEvent):void {
buttons.visible = !buttons.visible;
}
}
}
package com.danzen.effects
{
import com.danzen.frameworks.Easy;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
public class Tartan extends Sprite
{
private var colors:Array;
private var widths:Array;
private var tW:Number;
private var tH:Number;
public function Tartan(theColors:Array, theWidths:Array, theWidth:Number, theHeight:Number)
{
colors = theColors;
widths = theWidths;
tW = theWidth;
tH = theHeight;
var strip:Easy;
var lastX:Number = 0;
var lastY:Number = 0;
var numColors:Number = colors.length;
for (var i:uint = 0; i < numColors*30; i++) {
strip = Easy.rectangle(2800, widths[i%numColors], colors[i%numColors]);
addChild(strip);
strip.y = lastY;
strip.alpha = .5;
lastY += widths[i%numColors];
strip = Easy.rectangle(2800, widths[numColors-i%numColors-1], colors[numColors-i%numColors-1]);
addChild(strip);
strip.y = lastY;
strip.alpha = .5;
lastY += widths[numColors-i%numColors-1];
}
for (i = 0; i < numColors*30; i++) {
strip = Easy.rectangle(widths[i%numColors], 1800, colors[i%numColors]);
addChild(strip);
strip.x = lastX;
strip.alpha = .5;
lastX += widths[i%numColors];
strip = Easy.rectangle(widths[numColors-i%numColors-1], 1800, colors[numColors-i%numColors-1]);
addChild(strip);
strip.x = lastX;
strip.alpha = .5;
lastX += widths[numColors-i%numColors-1];
}
var blindR:Easy = Easy.rectangle(lastX-tW, tH, 0x444444);
blindR.x = tW;
addChild(blindR);
var blindB:Easy = Easy.rectangle(lastX-tH, tW, 0x444444);
blindB.y = tH;
addChild(blindB);
var blindL:Easy = Easy.rectangle(lastX-tW, tH, 0x444444);
blindL.x = -blindL.width;
addChild(blindL);
var blindT:Easy = Easy.rectangle(lastX-tH, tW, 0x444444);
blindT.y = -blindT.height;
addChild(blindT);
trace (colors)
trace (widths);
}
}
}
package com.danzen.effects
{
import com.danzen.frameworks.Easy;
import flash.display.Sprite;
import flash.events.*;
import flash.utils.Timer;
public class TartanShow extends Sprite
{
private var timer:Timer;
private var keepPercent:Number = 70; // how often we overlay tartans in percent
private var colors:Array;
private var speed:Number;
private var numTartans:Number = 100;
private var tartanIndex:Number = 0;
// tartans hold all the tartan patterns that make up one tartan
public var tartans:Sprite;
// tartans always have same color order but varying widths and overlay of widths
public var tartanList:Array = []; // holds tartan widths including overlays
// [ [[widths]], [[widths],[widths]], [[widths],[widths],[widths]], [[widths]] ]
public var currentTartan:Array = [];
// [ [colors],[[widths],[widths]] ]
public var running:Boolean = true;
public const MIN_MIN_WIDTH:Number = 3; // smallest the small width gets
public const MAX_MIN_WIDTH:Number = 13; // largest the small width gets
public const MIN_MAX_WIDTH:Number = 50; // smallest the large width gets
public const MAX_MAX_WIDTH:Number = 200; // largest the large width gets
private var sW:Number;
private var sH:Number;
public function TartanShow(theColors:Array, theWidth:Number, theHeight:Number, theSpeed:uint=2)
{
colors = theColors;
sW = theWidth;
sH = theHeight;
speed = theSpeed;
makeTartanData();
timer = new Timer(speed*1000);
timer.addEventListener(TimerEvent.TIMER, timerGo);
timer.start();
// holder for tartans
tartans = new Sprite();
addChild(tartans);
goTartan(0);
}
private function makeTartanData():void {
// loop through numTartans make random data for tartan
// tartans can blend over top of one another and then clear
var numColors:Number = colors.length;
var curTart:Array = [];
var curWidths:Array;
var count:uint = 0;
tartanList = [];
for (var i:uint = 0; i < numTartans; i++) {
curWidths = [];
for (var j:uint = 0; j < numColors; j++) {
if (Easy.random(2) > 1) {
curWidths.push(Easy.randomRound(MIN_MIN_WIDTH,MAX_MIN_WIDTH));
} else {
curWidths.push(Easy.randomRound(MIN_MAX_WIDTH,MAX_MAX_WIDTH));
}
}
curTart.push(curWidths.slice());
count++;
tartanList.push(curTart.slice());
if (Easy.random(100) > keepPercent || count >= 4) {
curTart = [];
count = 0;
}
}
}
public function next():void {
tartanIndex++;
if (tartanIndex > numTartans - 1) {
tartanIndex--; // end rather than loop
return;
//tartanIndex = 0;
}
goTartan(tartanIndex);
}
public function prev():void {
tartanIndex--;
if (tartanIndex < 0) {
tartanIndex++; // end rather than loop
return;
//tartanIndex = numTartans - 1;
}
goTartan(tartanIndex);
}
private function goTartan(n:Number):void {
if (tartans) {
removeChild(tartans);
tartans = null; // no listeners in Tartan class
tartans = new Sprite();
addChild(tartans);
}
var widths:Array = tartanList[n];
currentTartan = [colors, widths];
for (var i:uint=0; i<widths.length; i++) {
tartans.addChild(new Tartan(colors, widths[i], sW, sH));
}
}
private function timerGo(e:TimerEvent):void {
next();
}
public function pause():void {
running = false;
timer.stop();
}
public function resume():void {
running = true;
timer.reset();
timer.start();
}
public function dispose():void {
timer.addEventListener(TimerEvent.TIMER, timerGo);
}
}
}
package com.danzen.effects
{
import com.danzen.frameworks.Easy;
import com.danzen.utilities.Colors;
import flash.display.Bitmap;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.geom.ColorTransform;
public class TartanSpec extends Sprite
{
public var colorNames:Array = [];
public function TartanSpec(tartanData:Array, tartan:Bitmap)
{
var colors:Array = tartanData[0];
var widths:Array = tartanData[1];
addChild(Easy.rectangle(600, 500, 0xffffff));
addChild(tartan);
tartan.alpha = .2;
var spec:Spec = new Spec();
addChild(spec);
var ct:ColorTransform = new ColorTransform();
var counter:Number = 0;
var row:MovieClip;
var j:uint;
var cn:String;
for (var i:uint = 0; i < colors.length / 2; i++) {
ct.color = colors[i];
row = spec["row"+counter];
row.s.inner.transform.colorTransform = ct;
row.s.inner.alpha = .8;
cn = Colors.getName(colors[i]);
colorNames.push(cn);
row.n.text = cn;
row.c.text = Colors.getHexFromNumber(colors[i]);
for (j=0; j<widths.length; j++) {
row["t"+j].text = String(widths[widths.length-1-j][i]);
}
counter++;
ct.color = colors[colors.length-1-i];
row = spec["row"+counter];
row.s.inner.transform.colorTransform = ct;
row.s.inner.alpha = .8;
cn = Colors.getName(colors[colors.length-1-i]);
colorNames.push(cn);
row.n.text = cn;
row.c.text = Colors.getHexFromNumber(colors[colors.length-1-i]);
for (j=0; j<widths.length; j++) {
row["t"+j].text = String(widths[widths.length-1-j][colors.length-1-i]);
}
counter++;
}
}
}
}
package com.danzen.frameworks.zenconfirm
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.LocalConnection;
// copyright 2012 Dan Zen - free to use
// Sets up a confirmation system when purchasing a desktop app through paypal for instance
// Works in leu of a unique paypal id - because paypal sandbox was not working at the time to test
// also avoids a username and password situation
// SYSTEM
// put a download link and a confirmation button swf file on the returning page from PAYPAL
// once the user downloads, installs and runs the AIR app the user is to press the confirm button
// the confirm button uses ConfirmSend with a LocalConnection to confirm and send an optional object of variables
// on the AIR side, the ConfirmReceive object receives the message and gives a COMPLETE event
// at which point the status, statusText and data properties are available
// from that point on store a shared object with the AIR app to keep track of registration
public class ConfirmSend extends Sprite
{
public var status:String;
public var statusText:String;
private var conn:LocalConnection;
public static const COMPLETE:String = "complete";
public static const GOOD:String = "good";
public static const BAD:String = "bad";
private var site:String;
private var connectName:String;
// theConnectName must be no spaces, unique for app, and the same for ConfirmSend and ConfirmReceive
// theSite is the AIR app ID for ConfirmSend i.e. app#com.danzen.kittytartan
// theSite is the site name where the confirm button is for ConfirmReceive i.e. tartankitty.com
public function ConfirmSend(theConnectName:String, theSite:String="*")
{
trace ("hi from ConfirmSend");
connectName = theConnectName;
site = theSite;
conn = new LocalConnection();
conn.addEventListener(StatusEvent.STATUS, onStatus);
conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionError);
}
public function send(obj:Object):void {
conn.send(site+":"+connectName, "confirmMe", obj);
}
private function connectionError(event:SecurityErrorEvent):void {
status = ConfirmSend.BAD;
statusText = "error with confirming domain";
dispatchEvent(new Event(ConfirmSend.COMPLETE));
}
private function onStatus(e:StatusEvent):void {
switch (e.level) {
case "status":
status = ConfirmSend.GOOD;
statusText = "success making connection - not necessarily accepted";
dispatchEvent(new Event(ConfirmSend.COMPLETE));
break;
case "error":
status = ConfirmSend.BAD;
statusText = "error with making connection";
dispatchEvent(new Event(ConfirmSend.COMPLETE));
break;
}
}
}
}
package com.danzen.frameworks.zenconfirm
{
import com.danzen.utilities.Falcon;
import flash.display.Sprite;
import flash.events.*;
import flash.net.LocalConnection;
// copyright 2012 Dan Zen - free to use
// Sets up a confirmation system when purchasing a desktop app through paypal for instance
// Works in leu of a unique paypal id - because paypal sandbox was not working at the time to test
// also avoids a username and password situation
// SYSTEM
// put a download link and a confirmation button swf file on the returning page from PAYPAL
// once the user downloads, installs and runs the AIR app the user is to press the confirm button
// the confirm button uses ConfirmSend with a LocalConnection to confirm and send an optional object of variables
// on the AIR side, the ConfirmReceive object receives the message and gives a COMPLETE event
// at which point the status, statusText and data properties are available
// from that point on store a shared object with the AIR app to keep track of registration
public class ConfirmReceive extends Sprite
{
public var data:Object;
public var status:String;
public var statusText:String;
private var conn:LocalConnection;
private var site:String;
private var connectName:String;
public static const COMPLETE:String = "complete";
public static const GOOD:String = "good";
public static const BAD:String = "bad";
// theConnectName must be no spaces, unique for app, and the same for ConfirmSend and ConfirmReceive
// theSite is the AIR app ID for ConfirmSend i.e. app#com.danzen.kittytartan
// theSite is the site name where the confirm button is for ConfirmReceive i.e. tartankitty.com
public function ConfirmReceive(theConnectName:String, theSite:String="*")
{
trace ("hi from ConfirmReceive");
site = theSite;
connectName = theConnectName;
conn = new LocalConnection();
conn.allowDomain(site);
conn.client = this;
try {
conn.connect(connectName);
} catch (error:ArgumentError) {
status = ConfirmReceive.BAD;
statusText = "error with connection name";
dispatchEvent(new Event(ConfirmReceive.COMPLETE));
}
conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionError);
}
private function connectionError(event:SecurityErrorEvent):void {
status = ConfirmReceive.BAD;
statusText = "error with confirming domain";
dispatchEvent(new Event(ConfirmReceive.COMPLETE));
conn.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionError);
}
public function confirmMe(obj:Object=null):void {
if (status != ConfirmReceive.BAD) {
status = ConfirmReceive.GOOD;
statusText = "Confirmation success";
data = obj;
dispatchEvent(new Event(ConfirmReceive.COMPLETE));
}
}
public function usePasscode(url:String, pass:String, type:String):void {
// usePasscode will check passcode with serverscript and if pass matches,
// it will create a pid and dispatch as if confirmed from purchase
var myFalcon:Falcon = new Falcon(url, Falcon.VARIABLES, {pass:pass, type:type});
myFalcon.addEventListener(Event.COMPLETE, doConfirm);
function doConfirm(e:Event):void {
if (e.target.data.error == 0) {
data = { pid:pass }; // records pid as pass to avoid using pass multiple times
dispatchEvent(new Event(ConfirmReceive.COMPLETE));
}
}
}
}
}
package com.danzen.frameworks.zenconfirm
{
// Purchases is a wrapper for shared objects to store purchase ids and goods associated with the purchase
// Global scope is so that one purchase id is unique for all products to stop parallel manipulation
// Local scope is where the goods can be tracked
import flash.display.Sprite;
import flash.events.Event;
import flash.net.SharedObject;
public class ConfirmPurchases extends Sprite
{
public var data:Object = {};
private var globalSO:SharedObject;
private var localSO:SharedObject;
public function ConfirmPurchases(theGlobalScope:String, theLocalScope:String)
{
trace ("hi from ConfirmPurchases");
globalSO = SharedObject.getLocal(theGlobalScope, "/");
if (!globalSO.data.ids) {
globalSO.data.ids = [];
}
localSO = SharedObject.getLocal(theLocalScope, "/");
data = localSO.data;
}
public function addID(id:Object):Boolean {
//check global shared object to see if id is already in pidList
// return false if it is and true if it is not - and add pid
trace ("id="+id);
if (globalSO.data.ids.indexOf(id) == -1) {
globalSO.data.ids.push(id);
return true;
} else {
return false;
}
}
public function clear():void {
for (var i:Object in globalSO.data) {
globalSO.data[i] = null;
}
globalSO.data.ids = [];
for (var j:Object in localSO.data) {
localSO.data[j] = null;
}
}
}
}
package com.danzen.frameworks.zenconfirm
{
// ConfirmID is a wrapper for a shared object to store and retrieve the App user id
import com.danzen.utilities.Falcon;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.SharedObject;
public class ConfirmID extends Sprite
{
private var localSO:SharedObject;
public var data:Object;
public var error:String;
public function ConfirmID(theLocalScope:String)
{
trace ("hi from ConfirmID");
localSO = SharedObject.getLocal(theLocalScope, "/");
}
public function get id():Object {
return localSO.data.id;
}
public function set id(theID:Object):void {
localSO.data.id = theID;
}
public function randomID(n:Number=10000000000):Number {
return Math.round(Math.random()*n);
}
public function record(url:String, obj:Object):void {
// if you want you can send some data to a server script - like recording the id
var myFalcon:Falcon = new Falcon(url, Falcon.VARIABLES, obj);
myFalcon.addEventListener(Event.COMPLETE, recorded);
}
private function recorded(e:Event):void {
// any variables coming back from the server script is stored in data as properties
error = e.target.error;
data = e.target.data;
dispatchEvent(new Event(Event.COMPLETE));
}
public function clear():void {
localSO.data.id = null;
}
}
}
package com.danzen.interfaces
{
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import flash.desktop.ClipboardTransferMode;
import flash.desktop.NativeApplication;
import flash.desktop.NativeDragManager;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.*;
import flash.filesystem.File;
import flash.net.URLRequest;
public class AIRPicDrop extends Sprite
{
private var myTargetClip:Sprite;
private var myLoader:Loader;
private var myExtensions:Array;
private var myFile:String;
private var myFileList:Array;
private var myFileNum:Number;
private var myTempFile:String;
private var myTempFileList:Array;
private var myTempFileNum:Number;
public var fileList:Array;
public var numFiles:Number;
public var pic:Sprite;
public static const PIC_READY:String = "picReady";
public function AIRPicDrop(theTargetClip:Sprite, thePicExtensions:Array=null)
{
trace ("hi from AIRPicDrop");
myTargetClip = theTargetClip;
myExtensions = (thePicExtensions) ? thePicExtensions : ["jpg", "jpeg", "gif", "png"];
pic = new Sprite(); // holds the current picture
myLoader = new Loader();
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, setPic);
// see if they have dropped a file on the application icon
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, doInvoke);
// check to see stuff dragged onto the ball
myTargetClip.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);
myTargetClip.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, dragDrop);
myTargetClip.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, dragExit);
}
private function doInvoke(e:InvokeEvent):void {
if (e.arguments.length > 0) {
var myArray:Array = [];
// turn the array of strings into File objects
for(var i:uint=0; i<e.arguments.length; i++) {
myArray.push(new File(e.arguments[i]));
}
if (getFiles(myArray)) {
loadMyFile();
}
}
}
private function dragEnter(e:NativeDragEvent):void {
// casting as Array(myData...) does not work because Array() is a global function
var myArray:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
if (getFiles(myArray)) {
// need to call this to accept the drop
NativeDragManager.acceptDragDrop(myTargetClip);
}
}
private function dragDrop(e:NativeDragEvent):void {
loadMyFile();
}
private function dragExit(e:NativeDragEvent):void {
trace ("drag exit");
}
// ------- methods to get the file list (AIR)
// prepares a temporary list of files from an array of filenames
// if the array has one file, the files in the directory are collected
// this temporary list will get applied when the file (or files) is dropped
private function getFiles(myArray:Array):Boolean {
myTempFileList = [];
var i:uint;
for(i=0; i<myArray.length; i++) {
var file:File = myArray[i];
if (file.isDirectory) {continue;}
if (myExtensions.indexOf(file.extension.toLowerCase()) != -1) {
myTempFileList.push(file);
}
}
if (myTempFileList.length > 0) {
myTempFile = myTempFileList[0].url
myTempFileNum = 0;
if (myTempFileList.length == 1) {
// get other files in directory
myTempFileList = getDirectoryFiles(myTempFileList[0]);
}
return true;
} else {
return false;
}
}
private function getDirectoryFiles(f:File):Array {
var directoryList:Array = f.parent.getDirectoryListing();
var addFiles:Array = [];
var count:Number = 0;
for (var i:uint=0; i<directoryList.length; i++) {
var file:File = directoryList[i];
if (file.isDirectory) {continue;}
if (myExtensions.indexOf(file.extension.toLowerCase()) != -1) {
if (f.url == file.url) {
myTempFileNum = count;
}
addFiles.push(file);
count++;
}
}
return addFiles;
}
// ------- loader method and prev next public methods
private function loadMyFile():void {
myFileList = myTempFileList;
myFile = myTempFile;
myFileNum = myTempFileNum;
myLoader.load(new URLRequest(myFile));
}
public function prev():void {
var newFile:Number = myFileNum - 1;
if (newFile < 0) {
newFile = myFileList.length-1;
}
myFile = myFileList[newFile].url;
myFileNum = newFile;
myLoader.load(new URLRequest(myFile));
}
public function next():void {
var newFile:Number = myFileNum + 1;
if (newFile > myFileList.length-1) {
newFile = 0;
}
myFile = myFileList[newFile].url;
myFileNum = newFile;
myLoader.load(new URLRequest(myFile));
}
// ------- loader event
private function setPic(e:Event):void {
pic.addChild(myLoader);
dispatchEvent(new Event(AIRPicDrop.PIC_READY));
}
}
}
package com.danzen.interfaces
{
import com.danzen.frameworks.Easy;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.*;
import flash.geom.Matrix;
import flash.utils.Timer;
import uk.co.soulwire.display.colour.ColourUtils;
// Picture extends a Sprite and loads an image into itself and gets a palatte (colors property)
// receives URL:String, paletteSize:Number
public class Picture extends Sprite
{
public var url:String;
public var colors:Array;
public var paletteSize:Number;
private var pic:Sprite;
public static const PIC_READY:String = "picReady";
public function Picture(thePicture:Object, thePaletteSize:Number=16)
{
trace("hi from Picture");
if (thePicture is String) {
url = String(thePicture);
pic = Easy.picture(url);
pic.addEventListener(Event.COMPLETE, done);
} else {
pic = Sprite(thePicture);
picReady();
}
paletteSize = thePaletteSize;
}
private function done(e:Event):void {
picReady();
}
private function picReady():void {
addChild(pic);
// url from web is okay without timer but it is synchronous for desktop
// so need to delay to let the listener be registered
// also, Bitmap draw needed a touch of a delay too.
var myTimer:Timer = new Timer(300,1);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, doDelay);
myTimer.start();
}
private function doDelay(e:TimerEvent):void {
var bitData:BitmapData = new BitmapData(100, 100);
var matrix:Matrix = new Matrix();
// make picture smaller to sample more quickly
matrix.scale(100/pic.width, 100/pic.height);
bitData.draw(pic,matrix);
colors = ColourUtils.colourPalette(bitData, paletteSize, .02);
pic.removeEventListener(Event.COMPLETE, done);
dispatchEvent(new Event(Picture.PIC_READY));
}
}
}