/// <summary> /// Handles a key press and performs the appropriate action. /// </summary> /// <param name="key">The key.</param> /// <param name="unicodeKey">The Unicode key.</param> /// <param name="modifier">The modifier.</param> public bool HandleKeyPress( Key key, ModifierType modifier, uint unicodeKey) { // Normalize the key code and remove excessive modifiers. ModifierType filteredModifiers = modifier & (ModifierType.ShiftMask | ModifierType.Mod1Mask | ModifierType.ControlMask | ModifierType.MetaMask | ModifierType.SuperMask); int keyCode = GdkUtility.GetNormalizedKeyCode(key, filteredModifiers); // Check to see if we have an action for this. ModifierType isNormalOrShifted = filteredModifiers & ~ModifierType.ShiftMask; bool isCharacter = unicodeKey != 0 && isNormalOrShifted == ModifierType.None; bool isAction = keyBindings.ContainsKey(keyCode); if (isAction || isCharacter) { // Keep track of the original selection. TextRange previousSelection = displayContext.Caret.Selection; // Mark that we are starting a new action and fire events so // other listeners and handle it. InAction = true; // Perform the appropriate action. try { if (isAction) { keyBindings[keyCode].Perform(this); } else { TextActions.InsertText(this, (char)unicodeKey); } } finally { InAction = false; } // Check to see if the selection changed. if (previousSelection != displayContext.Caret.Selection) { displayContext.Renderer.UpdateSelection(displayContext, previousSelection); } // We did something, so return processed. return(true); } // No idea what to do, so don't do anything. return(false); }
/// <summary> /// Called when a key is pressed. /// </summary> /// <param name="eventKey">The event key.</param> /// <returns></returns> protected override bool OnKeyPressEvent(EventKey eventKey) { // If we don't have a line buffer, don't do anything. if (LineBuffer == null) { return(false); } // Decompose the key into its components. ModifierType modifier; Key key; GdkUtility.DecomposeKeys(eventKey, out key, out modifier); // Get the unicode character for this key. uint unicodeChar = Keyval.ToUnicode(eventKey.KeyValue); // Pass it on to the controller. return(controller.HandleKeyPress(key, modifier, unicodeChar)); }
/// <summary> /// Called when the <see cref="ActionManager"/> gets a key press and it passes /// it on to the current keybindings. /// </summary> /// <param name="e">The <see cref="Gtk.KeyPressEventArgs"/> instance /// containing the event data.</param> public void KeyPressed(KeyPressEventArgs e) { // Decompose the key into its components. ModifierType modifier; Key key; GdkUtility.DecomposeKeys(e.Event, out key, out modifier); // Get the normalized string accelerator which we use for lookups. bool isPartialAccelerator; string accelerator = GdkUtility.ToAcceleratorString( key, modifier, out isPartialAccelerator); if (isPartialAccelerator) { // If we are partial, just ignore it. return; } // Build a path with the current accelerator and the new one. var acceleratorPath = new HierarchicalPath(accelerator, currentAccelerator); // See if we have an accelerator for this path. if (!keybindings.Contains(acceleratorPath)) { // Reset the current accelerator key. currentAccelerator = HierarchicalPath.AbsoluteRoot; // We couldn't find it so return false. e.RetVal = false; return; } // Grab the accelerator for this key. If we don't have an item, then // this is going to be a continued chain. string actionName = keybindings.Get(acceleratorPath); if (actionName == null) { // We are only the first part of an action chain. currentAccelerator = acceleratorPath; e.RetVal = true; // TODO Fire an event to say incomplete accelerator. return; } // We have found a terminal action, so get the action involved. Action action = ActionManager.GetAction(actionName); if (action != null) { action.Activate(); e.RetVal = true; } // Add it to the errors. ActionManager.Messages.Add( new SeverityMessage( Severity.Error, string.Format( "Could not find action {0} to apply keybinding {1}.", actionName, acceleratorPath))); // We couldn't find the action so we did nothing. e.RetVal = false; }
/// <summary> /// Binds the actions from the various classes inside the assembly. /// </summary> /// <param name="assembly">The assembly.</param> public void BindActions(Assembly assembly) { // Make sure we have sane data. if (assembly == null) { throw new ArgumentNullException("assembly"); } // Go through the command factories in this assembly. foreach (Type type in assembly.GetTypes()) { // If we can't create it, we don't do anything. if (type.IsAbstract) { continue; } // If we are the proper type, create a new one and register it. if (typeof(ICommandFactory <OperationContext>).IsAssignableFrom(type)) { // Create a new instance. var commandFactory = (ICommandFactory <OperationContext>)Activator.CreateInstance(type); CommandFactory.Register(commandFactory); } } // Go through the types in the assembly. foreach (Type type in assembly.GetTypes()) { // Check to see if the type contains our attribute. bool isFixture = type.HasCustomAttribute <ActionFixtureAttribute>(); if (!isFixture) { continue; } // Go through all the methods inside the type and make sure they // have the action attribute. foreach (MethodInfo method in type.GetMethods()) { // Check to see if this method has the action attribute. bool isAction = method.HasCustomAttribute <ActionAttribute>(); if (!isAction) { continue; } // Create an action entry for this element. var action = (Action <EditorViewController>) Delegate.CreateDelegate(typeof(Action <EditorViewController>), method); var entry = new ActionEntry(method.Name, action); actions[method.Name] = entry; // Pull out the state objects and add them into the entry. object[] actionStates = method.GetCustomAttributes(typeof(ActionStateAttribute), false); foreach (ActionStateAttribute actionState in actionStates) { entry.StateTypes.Add(actionState.StateType); } // Pull out the key bindings and assign them. object[] bindings = method.GetCustomAttributes( typeof(KeyBindingAttribute), false); foreach (KeyBindingAttribute keyBinding in bindings) { // Get the keys and modifiers. int keyCode = GdkUtility.GetNormalizedKeyCode( keyBinding.Key, keyBinding.Modifier); // Add the key to the dictionary. keyBindings[keyCode] = entry; } } } }