Ejemplo n.º 1
0
  /**
   * We want to return the menu item associated with the key, but if there is no ambiguity (i.e.
   * there is only one menu item corresponding to the key) we want to return it even if it's not an
   * exact match; this allow the user to _not_ use the ALT key for example, making the use of
   * shortcuts slightly more user-friendly. An example is on the G1, '!' and '1' are on the same
   * key, and in Gmail, Menu+1 will trigger Menu+! (the actual shortcut).
   *
   * <p>On the other hand, if two (or more) shortcuts corresponds to the same key, we have to only
   * return the exact match.
   */
  MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) {
    // Get all items that can be associated directly or indirectly with the keyCode
    ArrayList<MenuItemImpl> items = mTempShortcutItemList;
    items.clear();
    findItemsWithShortcutForKey(items, keyCode, event);

    if (items.isEmpty()) {
      return null;
    }

    final int metaState = event.getMetaState();
    final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData();
    // Get the chars associated with the keyCode (i.e using any chording combo)
    event.getKeyData(possibleChars);

    // If we have only one element, we can safely returns it
    final int size = items.size();
    if (size == 1) {
      return items.get(0);
    }

    final boolean qwerty = isQwertyMode();
    // If we found more than one item associated with the key,
    // we have to return the exact match
    for (int i = 0; i < size; i++) {
      final MenuItemImpl item = items.get(i);
      final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut();
      if ((shortcutChar == possibleChars.meta[0] && (metaState & KeyEvent.META_ALT_ON) == 0)
          || (shortcutChar == possibleChars.meta[2] && (metaState & KeyEvent.META_ALT_ON) != 0)
          || (qwerty && shortcutChar == '\b' && keyCode == KeyEvent.KEYCODE_DEL)) {
        return item;
      }
    }
    return null;
  }
Ejemplo n.º 2
0
  /**
   * This function will return all the menu and sub-menu items that can be directly (the shortcut
   * directly corresponds) and indirectly (the ALT-enabled char corresponds to the shortcut)
   * associated with the keyCode.
   */
  void findItemsWithShortcutForKey(List<MenuItemImpl> items, int keyCode, KeyEvent event) {
    final boolean qwerty = isQwertyMode();
    final int metaState = event.getMetaState();
    final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData();
    // Get the chars associated with the keyCode (i.e using any chording combo)
    final boolean isKeyCodeMapped = event.getKeyData(possibleChars);
    // The delete key is not mapped to '\b' so we treat it specially
    if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) {
      return;
    }

    // Look for an item whose shortcut is this key.
    final int N = mItems.size();
    for (int i = 0; i < N; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.hasSubMenu()) {
        ((MenuBuilder) item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event);
      }
      final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut();
      if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0)
          && (shortcutChar != 0)
          && (shortcutChar == possibleChars.meta[0]
              || shortcutChar == possibleChars.meta[2]
              || (qwerty && shortcutChar == '\b' && keyCode == KeyEvent.KEYCODE_DEL))
          && item.isEnabled()) {
        items.add(item);
      }
    }
  }