Peter Hall's Flash, Flex and AIR blog. News and insights into development with Flash, Flex and AIR.

This page is powered by Blogger. Isn't yours?
Sunday, August 22, 2004

EventDelegate

I thought I'd post my own implementation of event delegation; EventDelegate. Why? You might well ask.

Well, I think its a great concept, and it can really help to keep code clean and manageable, but there were two things that bugged me about the implementation, included in the Flash 7.2 update.

Firstly, the delegate is actually a function, and not an instance of the Delegate class. I like to keep a reference to the delegate; that allows me to remove the event at a later date. But, typing the delegate as Function doesn't feel nice. It doesn't tell me that the variable is holding a delegate, it tells me that it is holding some function, with no information about what I can do with it or what it is for, so I don't think its as readable as having an instance that you can declare a data type for.

Secondly, there are times that I would like to use the same delegate to handle multiple events, for example where an application provides more than one way of performing the same operation, or where you need a catch-all handler for debugging. This works fine with mx.utils.Delegate but, when it comes to cleaning up an object, I feel that an object, designed to deal with events, should be able to help out a bit and do some work for you. Specifically, if I decide that a certain delegate is going to handle an extra event, it would be nice if I didn't have to remember to find the place in the code where the listeners are removed and remove it manually. It's a minor point - and maybe I'm lazy - but it seems like unnecessary work to write code, for every event, to add and remove it, when I could just as easily have one line to remove them all. I want one method that will stop the delegate from handling any more events, so that I can safely delete it.

So I made a really simple instantiable class, EventDelegate. That means I can keep a reference to it, and type the variable as EventDelegate. It also meant I could give it a kill() method that deletes references to the listener target and function, and removes itself from listening to all the events to which it has been subscribed. This type of maintenance is difficult with the mx.utils.Delegate because the references to the listener target and function are held in the delegate function's activation object and are not accessible to be deleted; if this function is left in memory, then so is your listener target object.

As I was writing this entry, I noticed that Colin has just posted a discussion about it on his blog, which you might like to check out. Also Mike Chambers wrote an article about using Delegate and Sam Neff has some info too.

Monday, August 16, 2004

The future of XML in Flash?

I was recently reading up on a new ECMA specification, known as E4X (ecma-357), which is an extension to EcmaScript (the standard that ActionScript and JavaScript comply to). E4X is a language extension, that adds new functionality and syntax to EcmaScript, to handle XML in a very intuitive way. It would make clumsy statements like firstChild.nextSibling.attributes.id a thing of the past.

With E4X, XML becomes, not only a native object, syntactically native. Its a completely different way of dealing with XML and is both simple and powerful. Here is an example from the spec:

 // an XML object representing two employees
 
var e = <employees>
   <employee id="1"><name>Joe</name><age>20</age></employee>
   <employee id="2"><name>Sue</name><age>30</age></employee>
 </employees>;

You can easily access this data, with statements like this:

  // get the name of employee with id 2
  name = e..employee.(id==2).name;
 
// add a new employee
  var bob = e..employee[2] = "";
  bob.@id = "3";
  bob.name = "Bob";
  bob.age = "28";
  // or using an XMLList:
  e..employee[3] = <><name>Geoff</name><age>25</age>;
  e..employee[3].@id = 4;

Obviously I can't test if that is actually syntactically correct, without having a working implementation, but that's the gist of it :)

A lot of the document is concerned with how you should actually implement building the extension from scratch so, if you are not comfortable reading these technical documents (and who is?), the quickest way to get something out of it is to search for "for example", and you'll find most of the example code.

Macromedia haven't said anything about whether this could be in the next version of Flash (codenamed 8Ball), but it's very encouraging to see names of Macromedia employees listed as contributors to the spec, including Gary Grossman, who is the guy responsible for ActionScript.

Saturday, August 14, 2004

Shared Font resolution?

Shared fonts in Flash have always caused problems and been difficult to work with. If you want to be flexible, the technique is basically to create the shared symbol in one swf, then have another swf import it. Then you can either load this swf, or import a symbol from it, which contains textfields, that uses the fonts you want. Remembering to include a field for each font is one of the big gotchas, but I think most developers now know that you have to do it. There is even a commercial component, which does all this for you.

But, I've struggled for some time with the fact that sometimes, it just doesn't work. No reason. I hadn't forgotten anything. It just didn't work. Then, last week, I stumbled upon a reason which turned out to apply to all the non-functioning examples that I could find, and I was able to fix them. The reason was some completely innocent text fields, that happened to use the same font, but with the font embedded through the Properties Inspector, and not using the imported one. Even a single static text field can break all the fields that use the same font, if the font is set with ActionScript. I can't tell you how grateful I am for Flash MX 2004's ability to search and replace a font!

Here's an example, that isolates the issue. Try republishing the base.swf, after changing the static text field's font to Arial.

I have a suspicion that this is the sole reason why imported fonts sometimes don't work. If you have a case, that isn't (or is!) fixed by removing non-imported embedded fonts, let me know.

Thursday, August 12, 2004

Test for a full input field

I needed to make a text input box, which allowed as much text as it could fit, without horizontal scrolling, which was for a text input box in a custom component framework. Simple: or so you'd think...

The first thing I tried was to check for the textField.maxhscroll property becoming >0. In theory that should work, because the property is 0 while the field has too little text to scroll. But I found that it was limiting the text far too much; in fact, the property was becoming >0 when the the text field was approximately 75% full.

So I had to resort to measuring the width of the text. It's a bit more complicated because you have to take into account margins which are set in the textFormat. Here's the function I used:

  function fieldIsFull(field:TextField):Boolean{
     var tf:TextFormat = field.getTextFormat();
     // "4" is for the 2 pixel gutter around all fields
     return (field.textWidth >
         field._width-4-(tf.leftMargin||0)
         -(tf.rightMargin||0)-(tf.blockIndent||0));
  }

To make the field so that it didn't allow more text to be typed once it was full, I did this:

  private var __text:String = "";
  // listener for inputField's onChanged event
  function onChanged(){
     if(fieldIsFull(inputField)){
         // storing and setting background is to
         // workaround a player bug
         var bg:Boolean = inputField.background;
         inputField.text = __text;
         // field could have scrolled
         // so make sure it is moved back
         inputField.hscroll = 0;
         // remove bg if it wasn't there before
         if(!bg){

            inputField.background = false;
         }
     }else {
         __text = inputField.text;
     }
  }

Overall, I like this a lot better than limiting the number of characters with maxChars. Normally I'd only limit it to stop the field from scrolling accidentally anyway, so this is a lot nicer and does not depend on the font size.

Notice the workaround for the Player bug, where the background is turned on when hscroll is set. If I remember correctly, this used to pop up occasionally in the Flash MX 2004 components, prior to the 7.0.1 patch.

Friday, August 06, 2004

Flash Developer Vacancy

World Archipelago is looking for a Flash Developer. Here is the (paraphrased) job description:

World Archipelago is looking for a Flash Developer with at least 2 years commercial experience to work in our west London studio developing games, Flash sites and applications. We have a strong client list, in both the UK ans US, including The History Channel, Discovery Channel, AETN and Fox Kids, to name a few.

Initially this would be a 4 month contract, but with the likelihood of a fulltime position for the right candidate.

The ability to demonstrate the following is essential:

* Proven ability to produce original work
* Ability to manipulate and use graphics in Flash
* Familiarity with Illustrator and Photoshop
* Experience building a variety of Flash games
* Experience integrating Flash with external data sources
* An intermediate understanding of ActionScript

The following would be a distinct advantage:

* Evidence of creative use of ActionScript
* Some experience with ActionScript 2.0 and MX 2004 components
* Knowledge of PHP, dotNet or JavaScript
* Design or illustration skills
* Degree level education

Initially this would be a 4 month contract, but with the likelihood of a fulltime position for the right candidate.

Your application should include:

* Evidence that demonstrates the skills listed above
* Your availability
* Your salary expectations

Having worked here for over a year, I can promise that the atmosphere is lively and relaxed. However, you will need to be able to handle a bit of heat from time to time... Contact me if you are interested.