Context Menus Revisited

After encountering a security sandbox limitation in my previous example, I update the post with a scaled-down set of images that are accessed from the same domain. I’ll say more on that topic later. Then I got a comment from Brian Ferris saying that he was confused by my post as it was contradictory to the documentation. Brian quoted the documentation which has the following to say about context menus.

<snip>
In Flex, only top-level components in the application can have context menus. For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
</snip>

As it turns out that this is the exact same snippet of documentation that initially sent me down the wrong path. When I read this I thought to myself that I must still have to use the original Flash 7 means of tracking mouse movements for nested objects. As we now know, this isn’t the case at all, but rather Flex exposes a context menu property on every interactive object.

To use this property you simply create a ContextMenu object and assign it to the contextMenu property of the control in which you’re interested. The only caveat I’ve found so far is to be aware of when the various parts of your UI are created. For example, if you do indeed have a context menu on a DataGrid that’s in a VBox that’s further in a TabNavigator, when does that DataGrid get created?

If the DataGrid is on the first tab, it’ll get created with the rest of the main UI. However if the DataGrid is on the second tab, using the default creation policy, it won’t get created until that tab is made active. If you’re trying to assign a context menu to the DataGrid on the second tab at Application.creationComplete, then there’s nothing there yet to which you can assign. The solution is simply to watch for DataGrid.creationComplete before you assign the context menu (you can create it whenever you want).

At the end of this post is an example that is in direct contradiction to the documentation. In fact, I’ve even gone the extra mile to ensure that it contradicts the entire scenario.

The UI itself doesn’t really do anything, but it’s a far more bare-bones example of using context menus on nested controls. You’ll find a context menu on the DataGrid on the second tab. In fact, there’s two - one for if there’s no item selected, and one for when there is an item selected, and they are changed dynamically at runtime. There’s also a context menu on the Button that’s below the DataGrid on the second tab.

The attached source for this is far more straight-forward than the image slicing/extracting example in the previous post. That reminds me to tell you about the security sandbox problem.

You probably heard that Flickr (and others) moved their cross-domain policy files recently. This is no big deal once you know where they moved it to, and you can still access their API. This wasn’t the problem with my previous sample.

The problem with the previous sample has to do with my application trying to copy pixel-level data from images that were loaded from Flickr’s server farm. The security sandbox looks at bitmap operations such as BitmapData.draw() as entering the realm of cross-domain, and therefore limits access. Without being able to put additional policy files on Flickr’s server farm, I was out of luck.

To get around this problem, I had to change the application to load images from the same domain as the application itself. If you download the source from that post, you’ll still be getting the original example that target’s Flickr’s servers. I’ve opted to not upload the alternative source, but if you want it, just let me know. They are fundamentally the same save that the images aren’t as “interesting”.

8 Responses to “Context Menus Revisited”

  1. Greg Says:

    Hi Kevin,

    This may be I’m overlooking something entirely else, but do you know why the other ’system’ menu items (settings, show redraw regions, about…)still exist even after calling hideBuiltInItems?

  2. Kevin Hoyt Says:

    Greg,

    Within the web version of the Flash Player (what you’ll find in the browser), these menu’s cannot be removed. They are permanent items left intact to prevent potential spoofers or other hacking threats that might involve the Flash Player.

    To be clear, the “Show Redraw Regions” is specific only to the Debug version of the Flash Player (generally found when running an application from Flex Builder). The Flash Player distributed from Adobe doesn’t have this menu item.

    Hope this helps,
    Kevin

    PS - Look to Apollo to (potentially) offer context menu support with full customization.

  3. Mike Burns Says:

    I’m having this problem: I set up a context menu to work with a Tree object, but the EventListeners do not work. The context menu appears, but when I click an item, nothing happens. It works with other controls, just not the Tree. I read that some controls disallow MouseEvents on their children/items, so you have to create a custom item renderer or extend the item renderer class to allow MouseEvents on the items in the list. Do you know if this applies to the Tree control, or do you have any other information that might help me?

    Thanks,
    Mike

  4. Wayne Adams Says:

    What type of event listener are you adding? I noticed I get nothing when I add an event listener for mouse events, but if I add a listener (specifically to the ContextMenuItem) for a ContextMenuEvent.MENU_ITEM_SELECT, it works as expected. This is on a Tree control contained in an HBox. ICBW but I think the only event recognized on a ContextMenu is a ContextMenuEvent.MENU_SELECT, and the only event recognized on a ContextMenuItem is a ContextMenuEvent.MENU_ITEM_SELECT. HTH — Wayne

  5. Alex Says:

    Can you embed menu’s within menu’s. So when you choose a menuitem another submenu is displayed? I can’t find any examples anywhere?

    Thanks,
    Alex

  6. Ugo Says:

    Hi. I’m trying to setup a context menu for a Tree control where the context menu is different for right-clicking on a folder item or leaf item. However, it doesn’t do that. It just displays the set of menu items defined (lastly, in an If…else construct) for the leaf items.

    How can I resolve this? Thanks

  7. H Lu Says:

    Hi Kevin,

    Great job! I have a question: when the popup window appears,(eg ‘Nested Context Menus’ in your example), if you do right click anywhere in that window, it will show the full default context menu(Zoom in, Show All ….), how to hide it if possile? I tried, it seems I cannot do it.

    Thanks
    Lu

  8. Directory Says:

    Dear Kevin,

    Good job with the article!

Leave a Reply