/// <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> /// 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; } } } }