In OpenLayers, there is a common property that can be passed to handlers/controls, called keyMask. It is used in a bitwise comparison in the checkModifiers method of the OpenLayers.Handler class. The main issue I had was that it currently only works to allow a given control to be restricted to a specified key combination. It also does not allow you to have a single control that responds to different keys. Rather, any event keys added to the keyMask property of a control/handler must ALL be present in order for checkModifers to return true. However, here's the situation I wanted:
- Global control (context menu): triggers on right click, or left-click + alt, or left-click + ctrl (this allows users with a one-button mouse to still access the menu), and
 - All other controls: trigger on any left-click event that excludes the alt or ctrl keys.
 
checkModifiers: function (evt) {
 if(this.keyMask == null && this.keyIMask == null) {
   return true;
 }
 /* calculate the keyboard modifier mask for this event */
 var keyModifiers =
   (evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
   (evt.ctrlKey  ? OpenLayers.Handler.MOD_CTRL  : 0) |
   (evt.altKey   ? OpenLayers.Handler.MOD_ALT   : 0);
 /* if it differs from the handler object's key mask,
   bail out of the event handler */
 return ((this.keyMask == null || keyModifiers == this.keyMask)
  && (this.keyIMask == null || (keyModifiers & this.keyIMask) == 0));
}
With the Handler modified in this way, I can tell any control to not respond if any key in an event matches keyIMask.  In my global control, it internally checks if the event is either right-click, or if it's a left-click with either the ctrlKey or altKey present.  All of my other controls are set with the property "keyIMask = OpenLayers.Handler.MOD_CTRL | OpenLayers.Handler.MOD_ALT;", which prevents controls from being triggered when the menu is displayed, and still leaves room for MOD_SHIFT to be used either as a keyMask, or to internally modify the behaviour of control's events (e.g., the freehand toggle in the OpenLayers.Handler.Path class).
No comments:
Post a Comment