OS X Mouse Wheel Support for Flex 2 Applications
Posted on July 6, 2007
Filed under ActionScript 3, Flex, Mac, Programming
In my current job I have been programming user interfaces for applications that display networks of data (as in nodes, links etc.) with the Adobe Flex framework, and the UI paradigm I have been utilizing is a kind of a Zoomable User Interface (ZUI). The idea there is to enable the user to view and manipulate objects on a two-dimensional plane, and navigate around that plane by zooming and panning.
Now, the easiest way (at least for me) to control the zooming is to use the mouse wheel. Mouse wheel support for Flex is implemented by registering an event listener of type MouseEvent.MOUSE_WHEEL with the DisplayObject that would dispatch the event. Sadly, mouse wheel support is not available in the Mac OS X version of Flash Player. This prompted me to create a custom solution, as my main computer is a MacBook and I would like to be able to test the mouse wheel navigation with my development machine.
Update: The javascript now works with more browsers than just Firefox 2 and Safari 2. I Tested it, in addition to those two, with Opera 9, Camino 1.5 and Omniweb 5.5, and it seems to work in all of them now.
Update #2: Changed the javascript code to also work with Safari 3 beta. When using it, small movements with the wheel do not invoke any action, so you’ll have to roll it a bit further to make the app respond.
Update #3: Added statement about licensing the code under the MIT License as per request of Philip Flip Kromer
Update #4 (feb 8, 08): If you’re looking for AS3 (not Flex) OS X mouse wheel support, check out PixelBreaker.com.
Update #5 (feb 12, 08): Fljot sent me a version of this that works also in non-Flex AS3 projects. He also fixed some issues in the code related to the automatic registration of listening objects. You can find him here.
The solution has been tested with Firefox 2 and Safari 2 Firefox 2, Safari 2, Opera 9, Camino 1.5 and Omniweb 5.5, and it is based on two main elements:
- JavaScript code that catches mouse events and sends their details through a function call to the Flash app using the ExternalInterface
- An ActionScript 3 singleton class ExternalMouseWheelSupport that registers an ExternalInterface callback for the function call and makes objects that are under the mouse cursor dispatch MouseEvents of type MouseEvent.MOUSE_WHEEL
JavaScript:
Just include the osxmousewheel.js file in your HTML and specify the ids/names of your flash object element and the div element that contains the flash object:
var mw_flashMovieId = "flashMovie"; // the id/name of your flash app's HTML DOM element
var mw_flashContainerId = "flashContainerDiv"; // the id/name of the flash element's surrounding div element
</script>
<script src="./osxmousewheel.js" type="text/javascript"></script>
ActionScript:
The singleton has to be created first, and that can be done by getting a reference to the instance property in at least one place:
private var _mwSupport:ExternalMouseWheelSupport = ExternalMouseWheelSupport.instance;
Then, all objects that you want to have the OS X mouse wheel support enabled for have to be registered with the ExternalMouseWheelSupport class. This can be done in two ways:
- Manually:
- Automatically:
This is the more foolproof way. First make sure that the registerAutomatically property is set to false (it is true by default):
Then just register the objects one by one:
or several at a time:
This is the easier, but more bug-prone way. Simply make sure that the registerAutomatically property is set to true (it is true by default, so you actually don’t even need to do this):
After that, all InteractiveObjects on the stage should dispatch mouse events, so you can normally attach event listeners to them and do whatever you want in them:
t.text = ("Mouse wheel delta: "+event.delta);
});
The code could probably use some debugging and optimization, but it seems to work well if you’re not doing anything too fancy. If you take it and make any fixes, please let me know! ;)
A working example.
The source code for the example.
The AsDoc-generated API Documentation for the support library
This code is distributed under the MIT License.
Comments
44 Responses to “OS X Mouse Wheel Support for Flex 2 Applications”
[...] OS X Mouse wheel support for Flex 2 applicationsIn my current job I have been programming user interfaces for applications that display networks of data (as in nodes, links etc.) with the Adobe Flex framework, and the UI paradigm I have been utilizing is a kind of a Zoomable User Interface (ZUI) …. [...]
thanks in advance.
I modified the javascript to work with other OS X browsers, too. See the post for more details. :)
It’s like:
The error console sais:
1120: Access of undefined property _mwSupport.
Why It doesen’t recognise it?
thx
http://www.figurart.hu/test.mxml
Well, you seem to be declaring the variable _mwSupport properly, so that shouldn’t be a problem. In the code you posted, I don’t really see anything wrong. I would just make sure that you actually have an object with the id redArea in there.
This is great stuff — thanks for figuring this out.
Would you please clarify the license attached to this code? In the US and many other countries, if no copyright is specified then all rights are reserved — so I can’t include your excellent work in other projects.
If you’d like to let anyone do whatever they want with the code, the MIT license is probably easiest:
http://www.opensource.org/licenses/mit-license.php
Cheers,
flip
I have no clue why. Do you have any hints for me??
Regards, Bernhard
Nice work,
Just a dumb question though (I’m not use to Flex, not sure to know what it is): does this mean that we can add the mouse wheel support (for scrollPanes or whatever) on flash websites (no Flex) ?
Tks for your answer
This code is ActionScript 3 and it relies on the use of some Flex classes, but it can be adapted for non-Flex AS3 – I just haven’t done it. If you do, please send me the code or the link to the code and I’ll post it here for others as well. If you use AS2, check out the following link:
http://blog.pixelbreaker.com/2006/11/08/flash/swfmacmousewheel/
Any thoughts?
http://hasseg.org/stuff/FlexOSXMouseWheel/example.html
I Tried to fix it for the new Opera version but couldn’t find a quick fix and I haven’t had time to go into it more deeply. It has something to do with JavaScript not being able to listen for mouse events inside the div that contains the Flash app, or more likely that Opera just uses some other method for doing it that I couldn’t figure out when I tried to fix it.
Bram:
It seems to work fine on WinXP SP2 when using Firefox. I Don’t have the proper access rights to update the ActiveX Flash player on my work computer (the only Windows box I have available), and it currently has Flash player 8 on it so I can’t test it :( Sorry..
FF & Opera 9.24 work just fine on Windows for me, Internet Explorer is an issue, as I can not see the example. The page is completely empty, as in total blank :).
I haven’t tried Flex 3 at all so I can’t say if this’ll work with it. For what it’s worth, I believe it should work and your problem is probably based somewhere else, but I can’t say for sure. I Apologize for not having more useful advice but I unfortunately haven’t had time to work on this stuff lately. :(
Bravo!
I could avoid the bug in IE by wrapping the JS code in the html page in a conditional tag :
var mw_flashMovieId = “flashMovie”; // the id/name of your flash app’s HTML DOM element
var mw_flashContainerId = “flashContainerDiv”; // the id/name of the flash element’s surrounding div element
here’s the code :
http://toolateatnight.be/macmousewheel/
It works on my projects, but not on the example pages provided on this site :)
//if (navigator.userAgent.indexOf(‘Mac’) != -1)
Now I can have wmode=opaque AND MouseWheel in IE, Firefox, and Safari on both Windows and Mac.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.managers::PopUpManagerImpl/addPopUp()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\managers\PopUpManagerImpl.as:229]
at mx.managers::PopUpManager$/addPopUp()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\managers\PopUpManager.as:167]
at mx.controls::Alert$/show()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\controls\Alert.as:505]
at org.hasseg.externalMouseWheel::ExternalMouseWheelSupport/initialize()[/Users/jonathan/Documents/Flex Builder 3/dflex/src/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as:64]
at org.hasseg.externalMouseWheel::ExternalMouseWheelSupport()[/Users/jonathan/Documents/Flex Builder 3/dflex/src/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as:43]
at org.hasseg.externalMouseWheel::ExternalMouseWheelSupport$/get instance()[/Users/jonathan/Documents/Flex Builder 3/dflex/src/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as:51]
at dflex()[/Users/jonathan/Documents/Flex Builder 3/dflex/src/com/dflex/controllers/application.as:18]
at _dflex_mx_managers_SystemManager/create()
at mx.managers::SystemManager/initializeTopLevelWindow()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\managers\SystemManager.as:2436]
at mx.managers::SystemManager/docFrameHandler()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\managers\SystemManager.as:2328]
Jonathan
try {
ExternalInterface.addCallback("dispatchExternalMouseWheelEvent", externalMouseWheelEventHandler);
ExternalInterface.call("mw_initialize");
}catch(e:Error){
Alert.show("Error initializing ExternalMouseWheelSupport: "+e.toString());
}
}
It’s clear that the ExternalInterface method calls are causing a problem there, so I think the way to start debugging is to check if any security features are blocking it.
Sources : http://toolateatnight.be/macmousewheel/mac_mousewheel_AS3.zip
I modified the class in a new one “ExternalMouseWheelSupportFlash.as” with the Flex-specific stuff stripped out.
I made it work with Flash AS3.
MacMouseWheel.setup(stage);
to:
MacMouseWheel.setup(Application.application.stage);
I put this line in my applicationComplete event handler, although it may work elsewhere.
[...] the mouse wheel work in Flash on OS X (it doesn’t by default) by using Ali Rantakari’s excellent ExternalMouseWheelSupport package. The The GAE SWF Project version 1.34 article by Aral Balkan, unless otherwise expressly [...]
I’ve just made a post about the new version (2) of this solution — check it out:
http://hasseg.org/blog/?p=138
[...] You can find the full explenation on this blog post. [...]
[...] I’ve finally updated the solution I’ve made earlier for enabling Mac OS X mouse wheel support in Flex applications to a second version. I didn’t want to continue adding stuff into the original post, so I decided [...]