Customize the Flash Context Menu, AKA Right-Click Menu by KPro

This tutorial will teach you how to customize the Flash context menu (right-click menu). This technique is applicable to absolutely any Flash project, regardless of size, length, or complexity.

Everyone has seen the context menu that appears when you right-click on a Flash movie. By default, this context menu has a somewhat unprofessional appearance, and it has a couple of features that can severely disrupt the functionality of an ActionScript-driven Flash movie. The default suite of items that appear in the Flash context menu will vary depending on whether or not the Flash movie has multiple frames in its timeline.

For a movie with only one frame in its timeline, the default context menu options are: Zoom In, Zoom Out, Show All, Quality > (Low, Medium, High), Settings..., Print..., Show Redraw Regions (Flash Player 8 only), and About Macromedia Flash Player...

[showing the default Flash context menu for a movie with only one frame]

For a movie with multiple frames in its timeline, the default context menu options are: Zoom In, Zoom Out, Show All, Quality > (Low, Medium, High), Play (acts as a toggle to play or pause the movie), Loop, Rewind, Forward, Back, Settings..., Print..., Show Redraw Regions (Flash Player 8 only), and About Macromedia Flash Player...

[showing the default Flash context menu for a movie with multiple frames]

Obviously, some of these menu items can cause problems with the presentation of your Flash movie. In many instances, you don't want the user to be able to zoom in on your movie, because that will hide a significant portion of your content and make any bitmap content look pixelated and grainy. In an ActionScript-driven application, the user having the ability to pause, loop, rewind, or step forward in your movie will disrupt the flow of your script and produce erroneous results. How would you like for the user to pause and rewind your Flash-based portfolio site while it's in the middle of the initial preloader? That wouldn't be good. Heck, if it's a Flash game you've made, some of these menu items might allow a user to cheat!

To see an example of a customized Flash context menu, take a look at this screenshot from my portfolio site:

[showing the custom Flash context menu on KProDigital.com]

If the user were to click on the KPro Home Page option, it would open a new browser window and take them to my main home page. If the user clicked the KPro Tutorial Center option, it would launch a new browser window and take them to my tutorials site. Finally, if the user clicked the 2006 KPro Digital Media option, nothing would happen. That menu item is there for appearances only.

One common approach is to disable the context menu entirely, which will leave it with only the Settings... and About Macromedia Flash Player... menu items (if the user has Flash Player 8, it will also have the Show Redraw Regions menu item).

[showing the disable Flash context menu]

That approach gets the job done, but it still has the problem of presenting a somewhat unprofessional appearance. The better approach is to customize the Flash context menu so that the user sees menu items that are beneficial to you, the creator of the Flash movie. If you're an animator who produces Flash movies for popular showcase sites like Albino Blacksheep, then a customized context menu is an absolute must!

NOTE: One thing to emphasize here is that the Settings... and About Macromedia Flash Player... menu items cannot be removed from the context menu. Those will be there no matter what, and Macromedia designed it that way because those two options are important to the use and functionality of the Flash player plug-in.

Alright, let's begin. Please download the appropriate exercise file and open it in your Flash authoring tool.

contextmenu_ex_8.fla (Flash 8)

contextmenu_ex_mx04.fla (Flash MX 2004)

Before we start writing any ActionScript, let's just get familiar with the exercise file that we're working with. This one is very basic; it has one keyframe and two layers on its timeline. The top layer, labeled "a," is locked and dedicated to ActionScript. There is already a stop(); action on the first keyframe of this layer. It's not really necessary in a movie with only one frame, but I always put it there just for posterity's sake. Remember, having a locked layer above all other layers which is labeled "a" or "actions" and dedicated purely to ActionScript is a recommended best practice in Flash development.

The bottom layer, labeled "gradient," has a gradient fill on the stage, which serves no purpose other than to make the file a little more visually appealing than a plain white box. There are no items in the library.

showing the timeline and stage of the exercise file in the Flash authoring tool

Let's start this party with a bang. Publish this Flash movie by selecting File > Publish. Now locate the contextmenu_ex_8.html (or contextmenu_ex_mx04.html) HTML document that was just created, and open it in your web browser. Put your mouse cursor over the Flash movie and right-click. Since this movie has only one frame, you'll see the default context menu for a single-frame Flash movie.

showing the default Flash context menu for a movie with only one frame

That is totally unacceptable. If this was a Flash movie that you'd spent five weeks developing, and now it's featured on the home page of a popular content showcase site, then you don't want users to see junk like "Zoom In." You want them to see the name of your website, and for them to be taken to your website when they click on that menu item. You also want them to see a copyright notice, because in these days of viral content theft you just can't put enough branding on your work.

Customizing the Flash context menu is done entirely with ActionScript, so we're going to spend the rest of this tutorial in the Actions panel. Open up the Actions panel, click after the stop(); command, and hit enter a couple of times to give yourself some space.

Let's take a moment to discuss the two ActionScript 2.0 classes that we'll be using to customize the context menu: the ContextMenu class and the ContextMenuItem class. That's about as intuitive as ActionScript class names get. The ContextMenu class can be located in Flash Help under ActionScript Language Reference > ActionScript Classes > ContextMenu. The ContextMenuItem class can be located in Flash help under ActionScript Language Reference > ActionScript Classes > ContextMenuItem.

An object of the ContextMenu class can be attached to a MovieClip object, a Button object, a TextField object, or an entire movie timeline. The last option is what we're going to do in this tutorial, we'll be attaching this ContextMenu to the _root timeline. The ContextMenu class has several actions that it can execute, including one called hideBuiltInItems();, which we will be using in this tutorial. This class also has a property (well, it's actually an array, but it more or less acts like a property in this case) called customItems, which in turn has an action in that it can execute called push();. We will also be using those. For a complete reference of all properties and methods of the ContextMenu class, see the Flash help. Alright, let's begin.

The first thing we have to do is create a ContextMenu object. Let's use proper ActionScript 2.0 syntax and strict data typing, and give this object the name myMenu.

var myMenu:ContextMenu = new ContextMenu();

This code creates a new object of the ContextMenu class called myMenu, which is now alive and ready to receive actions. The second thing we have to do is get rid of the Zoom In, Zoom Out, Show All, Quality > (Low, Medium, High), Settings..., and Print... menu items. These menu items come together in the form of a property of the ContextMenu class called builtInItems. Remember the hideBuiltInItems(); action that I mentioned a minute ago? Yes, it's that easy. In your actions pane, hit enter and add this action:

myMenu.hideBuiltInItems();

Before we can see this custom context menu in action, we have to do one more thing. We have to attach it to the movie's _root timeline. Hit enter a couple more times to skip a line, and add the code _root.menu = myMenu;

To make sure we're all on the same page, your whole script should now look like this:

stop();

var myMenu:ContextMenu = new ContextMenu();
myMenu.hideBuiltInItems();

_root.menu = myMenu;

Publish the Flash movie again, and open the contextmenu_ex_8.html (or contextmenu_ex_mx04.html) HTML document in your web browser. Now when you right-click on the Flash movie, you get the bare minimum context menu, with all of the built-in items hidden.

[showing the Flash context menu with all of the built-in items hidden]

If you wanted to, you could really stop here. All of the nasty playback-altering mischief that can be caused by the default context menu is now disabled. Despite the fact that this gets the job done, it still doesn't present a very professional appearance. More than that, it's just plain lazy. Now we're going to jazz up this context menu with custom items that carry out actions which we will define.

Creating the custom context menu items themselves is going to require us to use the other class I mentioned, the ContextMenuItem class. To create the actions that these custom menu items will execute, we will have to write a function for each one.

To start off, before we create any custom menu items, let's write a function that does nothing. Yes, you read that correctly. Click at the end of the stop(); command at the top of the script and hit enter a couple of times to give yourself some space. Let's name this function deadClick.

function deadClick () {
}

Piece of cake. The purpose for this function that does nothing is that it will be the action we assign to any custom context menu item when we don't want that item to do anything when clicked.

Alright, now the ContextMenuItem class gets to play. Let's create our first custom menu item. Click at the end of the myMenu.hideBuiltInItems(); line, and hit enter a couple of times to make some space. Let's create an item that will display a copyright notice, with the name copyrightNotice.

var copyrightNotice:ContextMenuItem = new ContextMenuItem("© 2006 KPro Digital Media", deadClick);

That line of code is pretty long, but also pretty intuitive. You've noticed that there are two parameters in the parentheses after new ContextMenuItem. The first parameter is the caption for the context menu item, which is what will be shown in the menu in the Flash movie. The second parameter is the action that you want this movie to execute. In this case, since this item is just a copyright notice, we want it to do nothing, hence the deadClick function.

At this point, your whole script should look like this:

stop();

function deadClick () {
}

var myMenu:ContextMenu = new ContextMenu();
myMenu.hideBuiltInItems();

var copyrightNotice:ContextMenuItem = new ContextMenuItem("© 2006 KPro Digital Media", deadClick);

_root.menu = myMenu;

Now let's create a context menu item that does something when clicked. This one will be the name of a website, and when clicked it will take the user to that website. In this tutorial, I'll just use my own site name and URL for the example, but you can go ahead and use any site name and URL that you want. The first step is to write a function which houses the actions that we want this menu item to execute. Click after the closing curly brace of the deadClick function and hit enter a couple of times to make some space. Now let's write a function called gotoMySite.

function gotoMySite () {
getURL("http://www.kprotutorials.com", "_top");
}

Just in case you're not familiar with the getURL action, here's the skinny on it: the first parameter is the URL of the website that you want to link to, and the second parameter is the target window. You could use _self for the current window, or _top for a new window. With this done, we can create the context menu item itself. Click at the end of the var copyrightNotice line, and hit enter. Now let's create the new item, and give it the name mySiteLink:

var mySiteLink:ContextMenuItem = new ContextMenuItem("KPro Tutorial Center", gotoMySite);

Publish the Flash movie again, and open the contextmenu_ex_8.html (or contextmenu_ex_mx04.html) HTML document in your web browser. When you right-click on the Flash movie, you still get the bare minimum context menu. What's the deal, why isn't it showing the custom items we just created?

[showing the Flash context menu with all of the built-in items hidden]

There is another action required before the Flash movie will actually use the custom context menu items. Do you recall the customItems property and the push action that I mentioned earlier? That's the action that plugs your custom items into the Flash context menu. Click on the line above the _root.menu = myMenu; line, and hit enter to get some space. Now we're going to use the push action to plug in our custom items:

myMenu.customItems.push(mySiteLink, copyrightNotice);

This action plugs our custom menu items into the custom context menu that we created called myMenu, which we have already assigned as the _root timeline's context menu. In the parentheses, you see the names of the two custom context menu items that we created. It's important to note that the order in which you enter the names in this line of code will be the top-to-bottom order in which they appear in the Flash movie.

Just to make sure we're all on the same page, your completed script should now look like this:

stop();

function deadClick () {
}

function gotoMySite () {
getURL("http://www.kprotutorials.com", "_top");
}

var myMenu:ContextMenu = new ContextMenu();
myMenu.hideBuiltInItems();

var copyrightNotice:ContextMenuItem = new ContextMenuItem("© 2006 KPro Digital Media", deadClick);
var mySiteLink:ContextMenuItem = new ContextMenuItem("KPro Tutorial Center", gotoMySite);

myMenu.customItems.push(mySiteLink, copyrightNotice);

_root.menu = myMenu;

Alright, now publish the Flash movie again, and open the contextmenu_ex_8.html (or contextmenu_ex_mx04.html) HTML document in your web browser. Now when you right-click the Flash movie, our custom context menu is good to go.

[showing the custom context menu good to go]

This sure looks a lot better than the default context menu, doesn't it? Now your Flash movie has built-in branding and a link to your website. Now, there's one more little thing we can do with this to make it look even better. Do you see how the copyright symbol clashes a slight bit with the words directly above it? We should put a separator there. The way you do this is with a property of the ContextMenuItem class called separatorBefore, and what it does is put a separator line above the context menu item for which it is declared. Let's use this property for the copyrightNotice menu item.

Click at the end of the new ContextMenuItem line where we created the copyrightNotice item, and hit enter. Now add the following code:

copyrightNotice.separatorBefore = true;

OK, now publish the Flash movie again, and open the contextmenu_ex_8.html (or contextmenu_ex_mx04.html) HTML document in your web browser. Now when you right-click the Flash movie, our custom context menu is good to go and there is a separator line above the copyright notice. Mission complete.

[showing the custom context menu completed]

Let me conclude with a final note about code placement. The code we've written in this tutorial only needs to be in your Flash movie once, on the first keyframe of the _root timeline. That's it. I hope you've enjoyed this tutorial and find it useful in your future work.

May 24, 2006