Search code examples
actionscript-3flex4mouseeventuicomponents

Handle MouseEvent.CLICK, MOUSE_DOWN in subclasses


I'm building a panel of buttons, that are enclosed in Canvas container. For this purpose I created a MyButton class, which is a subclass of UIComponent. MyButton class has 2 other subclasses: MyRadioButton and MyMenuButton, which have another behavior on MouseEvent.MOUSE_DOWN. MyMenuButtoncreates and shows a menu, that I build from XML and it builds ok.

I add listeners in the superclass like this:

this.addEventListener(MouseEvent.CLICK, handleClick);
this.addEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
this.addEventListener(MouseEvent.MOUSE_UP, handleMouse);

It's done at the creation stage.

In my subclasses I override handleMouse handler.

override protected handleMouse(event:MouseEvent) : void
{
  // subclass specific handling
}

These button objects are added to canvas container as following:

in class MyButtonsContainer.as:

this.rowChildren.addChild(button);

These buttons draw perfectly and in place. The problem is the behavior: The event doesn't come to handleClick handler of superclass. And that's the question actually - why can it be? Thanks in advance

EDIT: It appears that MOUSE_DOWN & MOUSE_UP interfere with CLICK event. When I remove listeners to them I get to click handler.How to cause them live together?


Solution

  • I managed to catch CLICK event as timing difference between MOUSE_DOWN & MOUSE_UP.

    EDIT: A short/long explanation: For some reason my listeners for MOUSE_DOWN/MOUSE_UP events were interfering with MouseEvent.CLICK. I was suggested by somebody to give up on listening to MouseEvent.CLICK and instead start a timer in MouseEvent.MOUSE_DOWN and check again the timer in MouseEvent.MOUSE_UP. If the difference less than 0.1 (you can put there another threshold) then it was a click actually.

    Now some sample code:

    public class MyButton extends UIComponent
    {
       ...
       private var _clickTime : Number = 0.;
    
       public function void MyButton()
       {
           super();
           addEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
           addEventListener(MouseEvent.MOUSE_UP, handleMouse);
       }
    
       protected function checkForClick(event:MouseEvent) : Boolean
       {
          var down : Boolean = event.type == MouseEvent.MOUSE_DOWN;
    
          if (down)
             _clickTime = getTimer();
          else {
              var diff : Number  = getTimer() - _clickTime;
              if (diff/1000. < 1.) {
                  handleClick();
                  return true;
              }
          }
          return false;
       }
    
       protected function handleClick(event:MouseEvent) : void
       {
           // handle the click here
       }
    
       protected function handleMouse(event:MouseEvent) : void
       {
           checkForClick(event);
           ... 
           // take care of your button graphic state
       }
    

    DISCLAIMER: This code works for me and good for me and my application needs. If you disagree with this way or have a better way to suggest, please do it in comments. Since this answer answers my own question and this EDIT was added only because I was asked to do so, please don't downvote it if you don't agree with it.