Tuesday, June 14, 2011

Flex: Changing useRollOver style affects itemRollOver event

The other day I ran into a bug in our application that was a bit unintuitive to track down. Suddenly the context menus used on a Tree component in our application started to behave weird. Anytime the context menu was opened the menu items in it referred to the first item in the Tree rather than to the item below the mouse cursor. To give some context, this is how the context menu logic for the Tree component is setup:

We have a variable called 'lastRollOverIndex' that is updated whenever the user hovers an item in the Tree. This variable is updated with the Tree index of the last rolled over item using the itemRollOver event of the Tree control. Whenever the user then right clicks the Tree control the lastRollOverIndex is used to get the item currently under the mouse cursor and the statuses and captions of the context menu items are updated accordingly before the context menu is shown to the user.

And now, seemingly out of the blue, the above functionality failed to work. So I started going through the recent change sets in our repository to try to find out what could be the cause of this problem. Interestingly, the search showed that no changes had been made to any files containing the logic for the above, the only change between a working and a non-working version of the application was some updates to the stylesheet.

But, could that really be? Updating some styles to changes the visual appearance of the application would also cause the logic of the same to fail? Well, answer is yes.

So one of the changes in the stylesheets was setting useRollOver to false for all List components to turn of the highlighting of items while hovering the list. Since a Tree is an extension of a List the change also applies to Tree components. So far, so good. But now we come to the unexpected part. Turns out, setting the useRollOver style also prevents the itemRollOver event from being dispatched which in turn killed the logic for our context menus. At least to me, this was not what I expected, and from what I could find in the documentation it is also not mentioned there.

So in order to disable the highlighting but still allow the itemRollOver events to fire I chose to override the drawItem function of the Tree control:

protected override function drawItem(item:IListItemRenderer,
    selected:Boolean = false,
    highlighted:Boolean = false,
    caret:Boolean = false,
    transition:Boolean = false):void
{
    super.drawItem(item, selected, false, caret, transition);
}

No comments:

Post a Comment