PDA

View Full Version : directly prototyping the SimpleButton class


aguynamedben
08-15-2007, 04:57 PM
This has already been posted a while back (http://www.actionscript.org/forums/showthread.php3?t=113880) but there was no real great solution and I wanted to see if anybody had come up with anything since then.

In AS2, I was able to handle all onPress events to the Button class in my own way by using prototyping...


static function trackButtonClicks() {
Button.prototype.onPress = function() {
registerButtonClick(this);
}
mx.controls.Button.prototype.onPress = function() {
registerButtonClick(this);
}
trace("now tracking teh butt0nz!");
}


In AS3, apparently you cannot directly manipulate the prototype chain. I have tried messing around with event listeners and stuff, but the only solution is to make a custom class that inherits from the SimpleButton class, and then to use that custom class to handle the events.

This doesn't work for me though, because I need this button tracking code to be portable and usable among many different Flash applications, without having to scour the entire application changing all of the buttons inheritances to be of a certain class.

Any ideas?

Slowburn
08-15-2007, 08:32 PM
Here is asimple example that may help.
I used Sprite here instead of SimpleButton for simplicity

The only thing I don't get ( with my own code ;) ) is when you click the nested sprite the normalClick handler is invoked twice. not sure why.

Hope this helps.

you should be able to drop all this code into the first frame of a Flash Movie.

import flash.display.*;
import flash.events.*;


function createSpriteButton( name:String, size:int, color:uint ):Sprite
{
var spr:Sprite = new Sprite();
spr.name = name;
spr.graphics.beginFill( color, 1 );
spr.graphics.drawRect( 0, 0, size, size );
spr.graphics.endFill();
spr.buttonMode = true;
spr.useHandCursor = true;
spr.addEventListener( MouseEvent.CLICK, normalClick );

return( spr );
}

function normalClick( event:MouseEvent ):void
{
trace( "you clicked: " + event.target.name );
}
function trackClick( event:MouseEvent )
{
var btn:Sprite = event.target as Sprite;
trace( "tracking: " + btn.name );
}

// Create Buttons
for ( var i:int = 0; i < 4; i++ )
{
var mySprite:Sprite = createSpriteButton( "sprite_" + i, 50, 0xFF0000 );
mySprite.x = i * 55;
addChild( mySprite );
}

// Add complex nested button
var spr:Sprite = getChildAt( 3 ) as Sprite;
var nestedSpr:Sprite = createSpriteButton( "nestedSprite", 25, 0x0000FF );
nestedSpr.x = 25;
spr.addChild( nestedSpr );

/**
* This is what your looking for here
* this will add your tracking to all your buttons.
*/
// Add tracking capabilities
for ( var k:int = 0; k < this.numChildren; k++ )
{
// get each child
var child:DisplayObject = getChildAt( k );

// check type of child
if ( child is Sprite )
{
// add tracking event
( child as Sprite ).addEventListener( MouseEvent.CLICK, trackClick );
}
}

aguynamedben
08-28-2007, 12:55 PM
Slowburn,

Thanks a bunch! The new AS3 object architecture is very similar to the DOM, which is awesome. I just modified your code a little bit since I wanted to add the listener to existing buttons, rather than creating sprites like you did. Here is what I ended up with...


function trackClick( event:MouseEvent )
{
var btn:SimpleButton = event.target as SimpleButton;
trace( "tracking: " + btn.name );
}

for ( var k:int = 0; k < this.numChildren; k++ )
{
// get each child
var child:DisplayObject = getChildAt( k );

// check type of child
if ( child is SimpleButton )
{
// add tracking event
( child as SimpleButton ).addEventListener( MouseEvent.CLICK, trackClick );
}
}

aguynamedben
08-28-2007, 01:01 PM
I suppose I also want to loop through the children of each child to a degree, in case there is an object that has a child object that is a button. This will allow buttons not on the top level to be tracked.

aguynamedben
08-28-2007, 01:07 PM
Instead of putting the code in in the first frame, I want to make it as a class so that it is portable. Instead of referring to the children using the object "this", how do I refer to the children of the movie externally? I am looking through the Top Level, fl, and flash objects, and I don't see how the main object hierarchy is accessed without using "this" in the first frame.