Bensmeets.com

Rich Internet, Interaction design and User Experience

Archive for January, 2005

Quicky, DevNet Resource Kit 10 is out

  • Filed under: RIA
Friday
Jan 28,2005

Just a quicky to remind everyone who hasn’t had their email notifier yet, that Devnet Resourcekit numero 10 is out.

At the first glimps of it, it seems there is less crap in it then usual. Focussing on the flash stuff as I always do, i can see some great RSS classes to use when implementing RSS in your projects. Nice way to learn AS2 programming too :)

Getting your uses out of OOP flashing

  • Filed under: RIA
Tuesday
Jan 25,2005

People who are just getting started with flash in general or AS2, might find this whole world full of OOP terms and flash OOP related information a bit overwhelming and make them decide not to use AS2 style in their projects.

This isn’t always necessary though. AS2 can be useful in very small projects too. Even in some situations where you might think ‘Isn’t this too small for AS2?’. Well it probably isn’t :) To show you some examples, I’ll show you some AS2 solutions for very simple menu’s in flash.

The only big issue when using an extremely simple menu in your app I could come up with, was how all menuitems knew about each other when they should be active or not. I’ll try to give you my example of two AS2 solutions for this problem. Along the way we’ll even find out how great ‘Static’ properties can be in real life examples :)

I’ll give you 2 solutions for building simple menu’s. One with using only 1 class where you can only have 1 menu in your application. And another one where you can have multiple menu’s all figuring out their own thing, using a seperate ‘Controller’ class.

So what seems to be the problem?
The problem i came across when trying to implement a quick and dirty menu for a simple flash project, is how to keep the active state across the menu? In the example below, each menuitem (square) has it’s own logic. When clicked, go down and thus be active. When clicked again, go up and thus be deactive. But what if i first activate item 1 and afterwards click item 2? Item 1 should then ‘know’ that item 2 is being clicked and therefor go to it’s deactive state.

Now let’s try to fix that with some OOP magic.

Menu logic using a single class with the help of ‘Static’
The most simple solution uses the ‘static’ principle for communicating between the different menu items. (See macromedia livedocs about static).

import mx.events.EventDispatcher;

class nl.fzfw.staticmenu.StaticMenu extends MovieClip {

	// ----------------------------------------
	// Static properties
	// ----------------------------------------
	private static var lstItems:Array;

	// ----------------------------------------
	// Constructor
	// ----------------------------------------
	public function StaticMenu()
	{
		if (lstItems == undefined)
			lstItems = new Array();

		lstItems.push(this);
		EventDispatcher.initialize(this);
	}

	// ----------------------------------------
	// Public functions
	// ----------------------------------------
	public function setActiveMenu(obj:StaticMenu) : Void
	{
		for(var item in lstItems)
		{
			if (lstItems[item] == obj)
				lstItems[item].activate()
			else
				lstItems[item].deactivate()
		}
	}

	// ----------------------------------------
	// Public functions
	// ----------------------------------------
	private function activate() : Void	{
		dispatchEvent({type:"onActivated",target:this});
	}

	private function deactivate() : Void	{
		dispatchEvent({type:"onDeactivated",target:this});
	}

	// ----------------------------------------
	// Declare functions that EventDispatcher adds
	// ----------------------------------------
	private var dispatchEvent:Function;
	public var addEventListener:Function;
	public var removeEventListener:Function;
}

Since the static variable is shared across all instances of StaticMenu, they can communicate to each other through the same variable. The MenuItem mc’s in the flash movie can handle what to do regarding to animation and stuff. What we wanted here was just to be able to talk to other menu items.

Solution with a menu controller class
But what if we needed multiple menu’s across our movie? They would start talking to each other wouldn’t they? Yes they would :) So in comes our controller class which we will create for each menu we want to use. The controller class is kind of a substitute for the previously used static variable. See the source files for more info. The code for using the controller will look something like this:

import nl.fzfw.simplemenu.*;

// Create the controller for the Main Menu
var mainMenu = new MenuController();
for (var i=0; i<5;i++) {
	var pointer = _root.attachMovie("MainMenuItem","MainMenuItem" + i, getNextHighestDepth());
	pointer._x = 50 + i * (pointer._width + 5);
	pointer._y = 10;
	pointer.Controller = mainMenu;
	mainMenu.addMenuItem(pointer);
}

// Create the controller for the Sub Menu
var subMenu = new MenuController();
for (var i=0; i<3;i++){
	var pointer = _root.attachMovie("SubMenuItem","SubMenuItem" + i, getNextHighestDepth());
	pointer._x = 50 + i * (pointer._width + 2);
	pointer._y = 60;
	pointer.Controller = subMenu;
	subMenu.addMenuItem(pointer);
}

Listening to the clicks
As Stone mentioned in the comments already, the question unanswered is how to use this theoretical setup in real life. We need to know when a certain menu is being clicked as to take action on it. Let’s say going to a certain frame, or loading a certain xml file.

For showing you how, i’ll use the setup with the ‘menu controller’ type of solution, and add a few things which will help us out.

Since the menuitems already are sending signals to the rest of the world when they are clicked (Events), the only thing we need to do is listen.

Step 1 is to extend the menuitem class with something to identify it with. We add a property to the MenuItem class called ‘_Name’

	...

	// ----------------------------------------
	// Private properties
	// ----------------------------------------
	public var _Name : String;

	...

Extend the event that is being dispatched by the menuitems by adding the Name property to it.

	...
	// ----------------------------------------
	// Public functions
	// ----------------------------------------
	public function activate() : Void	{
		dispatchEvent({type:"onActivated",target:this, data:Name});
	}
	...

Then when creating the menu in our fla, we fill that _Name property with something we can identify it with (unique).

	...

	// Set name parameter.
	pointer.Name = "Menu" + i;

	// Start listening to the menuitem for when it's activated
	pointer.addEventListener("onActivated", this);

	...

What we did here is first let the fla assign identifiers to the created MenuItem’s and let the MenuItems dispatch that same name when they go into their active state. In the fla we told our _root to listen to each of the MenuItems for their dispatched events. (When you get the point, you might want to move the dispatching to the menuController class and make your fla listen to that single class instead to each menuitem).

Now all we need to do is tell the fla what to do when it receives one of the fired events. e.g. trace the name of the menuitem which is firing by adding to following code to our fla:

	...

	this.onActivated = function(evtObj)
	{
		trace("Received a menu click with name: " + evtObj.data);
	}

	...

It’s as easy as that. Once you get your event dispatching up and running. All you need to do is add or remove listeners to that object as much as you want.

I updated the download to include the newer version. Older versions of examples of the menu controller solution have been overwritten by that.

You can spit through the source files to get the details. Man, trying to cover all the details is a complete day job. This should just give you an idea how easy AS2 can be in even the smallest projects. And although all of the mentioned things can also be accomplished in AS1, I dare to ask you…… why bother? ;)

» Download the entire source bunch.

I can see the spammer whining

Friday
Jan 14,2005

Well the spam busting measure me and Ronald took for flashzone, seems to have paid off just great.

Although the solution we had was quite simple, I had the pleasure of receiving 0 (!!) comment spam messages since installing it.

I can see the spammers trying though :) Since that day i had about 2464 unsuccesfull calls to mt-comment.cgi :)

“Duh, where did it go….. it was here before…. uhm…. now what should i do with all these pills…”

Stop spamming my logfiles you bastards! (That will be the next todo :) )