Friday, November 07, 2008

Text Selection Discovery

I was wracking my brain on and off for about a week trying to get a field to select all the text in it when it achieves focus. This happens automatically when you tab to it, but when you click in it, it sets the caret wherever you're clicked.

Initially I was convinced that FocusEvent.FOCUS_IN should do the trick. In fact, I'm still convinced it is, but it doesn't work.

var tmp:TextField = new TextField();
tmp.addEventListener(FocusEvent.FOCUS_IN,focusText);
tmp.htmlText = "test text";
tmp.autoSize = "left";
tmp.selectable = true;
tmp.type = "input";
tmp.border = true;
tmp.x = 50;
tmp.y = 50;
addChild(tmp);
function focusText(_fevt:FocusEvent):void{
trace(_fevt.target.text);
var tf:TextField = TextField(_fevt.target);
tf.setSelection(0,tf.length);
}

This doesn't work. Such a shame.

Anyway, Todd Fraser over here at Organic gave me one of those, "wait, MouseEvent.CLICK didn't work?" with one eyebrow raised. And although I had to admit I hadn't even bothered with MouseEvent.CLICK because I assumed FocusEvent.FOCUS_IN should work. Don't discount what you might consider "ol' timey" ways of doing things.

var tmp:TextField = new TextField();
tmp.addEventListener(MouseEvent.CLICK,focusText);
tmp.htmlText = "test text";
tmp.autoSize = "left";
tmp.selectable = true;
tmp.type = "input";
tmp.border = true;
tmp.x = 50;
tmp.y = 50;
addChild(tmp);
function focusText(_fevt:MouseEvent):void{
trace(_fevt.target.text);
var tf:TextField = TextField(_fevt.target);
tf.setSelection(0,tf.length);
}

Shoot, dawg.

Labels: , ,

Saturday, November 01, 2008

Flash on the Beach Miami!

I've just been confirmed as a speaker at Flash on the Beach Miami!

This is a great honour and I look forward to hitting South Beach in April! I can't wait for this one.

Labels: , ,

Thursday, October 30, 2008

Awards. The Good. The Bad. The Ugly

This came up on Facebook because a friend commented on it and wondered if maybe he was too harsh in his response.

As a former boutique shop owner (if two guys in their respective homes running a virtual shop counts) I ran into this situation many, MANY times. I’ve been to so many award shows when work I’ve done has won and I have to sit as the agency that hired us to build their concept into a living, breathing, creative and exciting site accepts the award.

In one case, we (Nemesis Group) were up against two other agencies for Canadian Agency of the Year. One of those agencies used us AND the other shop up for the award as contractors. When neither contractor shop won, the hiring shop got up, waved the award in the air and said, “thanks.”

Call it sour grapes if you want, but a shout out to the other two shops in your category who elevated your work would have been nice. Even shaking our hands after you accepted the award would have sufficed. I digress.

Anyway, this is two sides of the coin;

First in defence of hiring agencies.

And in defence of the shops who build the work.

Finally, the comments that sparked the whole conversation.

Labels:

Monday, September 22, 2008

Fee Education Wins an Award

I generally don't notice when something I worked on wins awards. It's not that I don't care, but if I didn't enter them I wouldn't know they were submitted. I digress.

Turns out Fee & Processes Explained, a site I worked on last year for Organic, won a WebAward for Best Financial Services Website.

Yay me. Yay Organic.

Labels: ,

Thursday, September 11, 2008

MainImporter Class

This is the second custom class used in the Bullet Class, MainImporter.

During the same project that prompted TextFormatter it dawned on me I had no real useful Load this class. There are a lot of nice phat loaders around, BulkLoader is a great example. However, it's kind of overkill for what I wanted.

So I put together MainImporter. It handles Bitmaps, SWFs and XML nicely and I've used it extensively for pretty much every project since.

package com.utils{
import com.events.LoaderEvent;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class MainImporter extends EventDispatcher{
public static const ITEMLOADED:String = "item loaded";
private var itemURL:String;
public var loader:Loader;
public var loaderXML:URLLoader;
private var fileEnder:String;
public var loadedCurrent:Number;
public var loadedTotal:Number;
public function MainImporter(_url:String){
itemURL = _url;
var tmpArray:Array = itemURL.split(".");
fileEnder = tmpArray[tmpArray.length-1];
loadItem();
}
private function loadItem():void{
var urlRequest: URLRequest = new URLRequest(itemURL);
if(fileEnder == "xml"){
loaderXML = new URLLoader();
loaderXML.addEventListener(IOErrorEvent.IO_ERROR,loadError);
loaderXML.addEventListener(ProgressEvent.PROGRESS,progressListener);
loaderXML.addEventListener(Event.COMPLETE,completeLoad);
loaderXML.addEventListener(Event.INIT,initListener);
loaderXML.load(urlRequest);
}else{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadError);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progressListener);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeLoad);
loader.contentLoaderInfo.addEventListener(Event.INIT,initListener);
loader.load(urlRequest);
}
}
private function initListener(evt:Event):void{
//trace("init");
}
private function progressListener(evt:ProgressEvent):void{
loadedCurrent = Math.floor(evt.bytesLoaded/1024);
loadedTotal = Math.floor(evt.bytesTotal/1024);
dispatchEvent(new LoaderEvent(LoaderEvent.UPDATELOADER,loadedCurrent,loadedTotal,true));
}
private function loadError(evt:IOErrorEvent):void{
trace("IOErrorEvent : " + evt);
}
private function completeLoad(evt:Event):void{
dispatchEvent(new Event(MainImporter.ITEMLOADED));
}
}
}


This is a work in progress, so do what you want with it.
MainImporter.as

Labels: , , ,

TextFormatter Class

I just posted on BulletBuilder. I realized there are two other classes I set up a while ago for another project that I use regularly that could use some explanation.

First is TextFormatter. We'd started a project and needed a quick way to implement some basic textfields across the project that could react to some supplied variables; font, color, size, leading

To circumvent some massive discussion about Stylesheets or whatever, I set up TextFormatter and it's done the job pretty adequately and I've used it since for anything non-complex in a textfield.

To use TextFormatter, just import the class and create a textfield then instantiate TextFormatter. Of course, also import the TextField class. You'll want to set the width of the textfield as well.
var tf:TextField = new TextField;
tf.width = 300;
new TextFormatter(tf,0x000000,12,"Flash ain't so bad","Arial");
addChild(tf);

Now in TextFormatter all the pseudo-heavy lifting can begin.
package com.utils {
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.AntiAliasType;
public class TextFormatter {
public function TextFormatter(src:TextField,fcolor:uint,fsize:Number,str:String,ffont:String="FranklinGothicEF-Demi", leading:Number=0)
{
src.autoSize = TextFieldAutoSize.LEFT;
src.background = false;
src.border = false;
src.embedFonts = true;
src.selectable = false;
src.antiAliasType = AntiAliasType.ADVANCED;
var format:TextFormat = new TextFormat;
format.font = ffont;
format.color = fcolor;
format.size = fsize;
format.leading = leading;
src.defaultTextFormat = format;
src.htmlText = str;
}
}
}


TextFormatter.as

Labels: , , ,

Bullet Class

A little while ago, I was working a little project that had several lists of bullets. I couldn't find any suitable solutions that gave the designer what he craved; a list of bullets with well-wrapped text.

Sample xml;
<SAMPLE_TEXT>• Bullet item one.
• Bullet item two. Long enough to wrap because I've typed a little bit too much and it definitely is too long to fit in one line.
• Bullet item three. There's nothing like seeing text wrapping to make you realize that bullets are the bane of your existence. Nothing, I say.
• Bullet item four.</SAMPLE_TEXT>


Here's what you get when you just set up a normal textfield and do what you normally do.

var tf:TextField = new TextField;
tf.width = 300;
tf.multiline = true;
tf.wordWrap = true;
tf.text = SAMPLE_TEXT;
addChild(tf);




As you can see, the text wraps under the bullet because flash only sees it as a block of text.

I realized that the best solution, for me anyway, was to separate the bullet and the line, make two textfields and line them up. This way the copy aligns as it should and doesn't wrap under the bullet. So I set up a little class to take care of it for me.

The XML had to change to accomodate TextFormatter, but only a little;
<SAMPLE_TEXT bulletString="•" ffont="Arial" fsize="18" fcolor="0x000000">• Bullet item one.
• Bullet item two. Long enough to wrap because I've typed a little bit too much and it definitely is too long to fit in one line.
• Bullet item three. There's nothing like seeing text wrapping to make you realize that bullets are the bane of your existence. Nothing, I say.
• Bullet item four.</SAMPLE_TEXT>

package com.display
{
import flash.display.Sprite;
import com.utils.TextFormatter;
import flash.text.TextField;
public class BulletBuilder extends Sprite
{
private var content:Sprite;
private var bulletCharacter:String;
private var bulletArr:Array;
private var contentArray:Array;
private var bullet:TextField;
private var copy:TextField;
private var bulletHeight:Number = 0;
private var fieldWidth:Number;
/*====================
provide the constructor with;
the xml node
what character to look for
the width of the end field
sample;
var bulletBuilder:BulletBuilder = new BulletBuilder(sampleNode,"•",415);
addChild(bulletBuilder);
=====================*/
public function BulletBuilder(_copy:XML,_bulletCharacter:String,_fieldWidth:Number)
{
content = new Sprite;
bulletCharacter = _bulletCharacter;
fieldWidth = _fieldWidth;
bulletArr = _copy.toString().split(bulletCharacter+" ");
setBulletFields(_copy);
}
/*=====================
setBulletFields separates the copy
into an array based on the provided bullet character.
it then uses two textfields; one for the bullet character, one for the copy.
places the copy at the same y position as the bullet
and moving it to the right of the bullet
it then adds the two fields to the sprite and updates the y position for the next bullet
finally, the function adds the content sprite
========================*/
private function setBulletFields(_copy:XML):void{
contentArray = []
for(var i:int = 1;i<bulletArr.length;i++){
contentArray[i] = new Sprite;
bullet = new TextField;
copy = new TextField;
copy.width = fieldWidth;
copy.multiline = true;
copy.wordWrap = true;
new TextFormatter(bullet,_copy.@fcolor,_copy.@fsize,bulletCharacter,_copy.@ffont);
new TextFormatter(copy,_copy.@fcolor,_copy.@fsize,bulletArr[i],_copy.@ffont);
copy.x = bullet.width;
contentArray[i].addChild(bullet);
contentArray[i].addChild(copy);
contentArray[i].y = bulletHeight;
bulletHeight +=contentArray[i].height;
content.addChild(contentArray[i]);
}
addChild(content);
}
}
}



Here's sample with the package(s)

Labels: , , ,

Friday, August 15, 2008

FlashForward San Fransisco

FlashForward is on next week and I'm about as excited as a fat kid looking at a bowl of smarties.

Not only do I finally get to see the Organic offices in SF, but Libs managed to wrangle a couple of days off and will be joining me for her first trip there ever.

I look forward to seeing all my friends, tipping a glass and toasting to everyone's health.

Labels: , ,

Wednesday, July 16, 2008

Last Weekend

Libs and I had planned on going to Huff Estates winery for our first weekend alone since Declan was born. However, with Declan getting sick with hand, foot and mouth disease, we felt it inappropriate to drop him at the grandparents and waving so long.

Turns out after we cancelled our reservation, he started to feel better and by the weekend, he was fully recovered. We brought him to Libs' parents anyway so we could still get a little break.

They gave us the opportunity to head into Peterborough and watch a movie. Went to Hancock. As we were walking around downtown Peterborough, we happened to see this car sitting in a parking lot.



I recommend waiting a second while you look at it. No? Imfamous. Not only is it stupid to have Infamous on your windshield, it's just that little bit extra stupid to misspell it.

Oh and we went to the drive-in in the evening and saw Wall•e and The Incredible Hulk. Took care of all our summer blockbusters at one go.

Labels: , , ,