Using Sprite.buttonMode and Sprite.mouseChildren

Today I found something I really did not understand very well. I had to debug a application because one button displayed the handCursor and another did not. Both use the same script and actually I didn’t find out why the behaviour of this buttons was like that but I fixed it through a workaround.

The first thing I understood today is, that it’s possible to receive all mouse events without using buttonMode! Simply add a listener to your objects and you can work with them.

But if you like to work with a button that contains additional sprites (which might be very useful) you definitely should take care about their behaviour. By default mouse events will be dispatched by the lowest sprite, exept you set mouseChildren to false…

Have a look at this little code example:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class ButtonModeTest extends Sprite
	{
		public function ButtonModeTest()
		{
			run();
		}
 
		private function run(): void
		{
			//-- Start listening
			addEventListener( MouseEvent.CLICK, onMouseEvent );
			addEventListener( MouseEvent.MOUSE_OVER, onMouseEvent );
			addEventListener( MouseEvent.MOUSE_OUT, onMouseEvent );
 
			//-- Button 1 on the main stage
			var button1: Sprite = createButton( 1 );
			addChild( button1 );
 
			//-- Button 2 within the container
			var button2: Sprite = createButton( 2 );
			var button2Container: Sprite = new Sprite();
			button2Container.addChild( button2 );
			button2Container.x = 150;
			button2Container.name = "button2Container";
			addChild( button2Container );
 
			// By default the mouse events will be dispatched by the buttons themself
			// (the lowest sprites)
 
			// Setting containers buttonMode to true doesn't force the container to
			// dispatch the mouse events ( so what the hell is button mode?)
			button2Container.buttonMode = true;
 
			// Setting containers useHandCursor to true only works when it's buttonMode
			// is also true. But the events will still be dispatched from the lowest
			// sprite (even its a button!?!)
			button2Container.useHandCursor = true;
 
			// Only setting mouseChildren to false forces the container to dispatch
			// the mouse events
			button2Container.mouseChildren = false;
		}
 
		private function createButton( index: uint ): Sprite
		{
			var button: Sprite = new Sprite();
			button.name = "button" + index; 
			button.graphics.beginFill( 0, 1 );
			button.graphics.drawRect( 0, 0, 100, 100 );
			button.graphics.endFill();
 
			return button;
		}
 
		private function onMouseEvent( event: Event ): void
		{
			trace( "Event (" + event.type + ") dispatched from : " + event.target.name );
		}
	}
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.