Пример #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).
   *
   * 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;
  }
Пример #2
0
  public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) {
    final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title);
    final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item);
    item.setSubMenu(subMenu);

    return subMenu;
  }
Пример #3
0
 private void addItem(final Integer index, final MenuItemImpl item) {
   if (index != null) {
     getUiReference().getItems().add(index.intValue(), item.getUiReference());
   } else {
     getUiReference().getItems().add(item.getUiReference());
   }
 }
Пример #4
0
  public boolean performItemAction(MenuItem item, int flags) {
    MenuItemImpl itemImpl = (MenuItemImpl) item;

    if (itemImpl == null || !itemImpl.isEnabled()) {
      return false;
    }

    boolean invoked = itemImpl.invoke();

    //        if (itemImpl.hasCollapsibleActionView()) {
    //            invoked |= itemImpl.expandActionView();
    //            if (invoked) close(true);
    //        } else if (item.hasSubMenu()) {
    //            close(false);
    //
    //            final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
    //            final ActionProvider provider = item.getActionProvider();
    //            if (provider != null && provider.hasSubMenu()) {
    //                provider.onPrepareSubMenu(subMenu);
    //            }
    //            invoked |= dispatchSubMenuSelected(subMenu);
    //            if (!invoked) close(true);
    //        } else
    {
      if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) {
        close(true);
      }
    }

    return invoked;
  }
Пример #5
0
  public void setGroupEnabled(int group, boolean enabled) {
    final int N = mItems.size();

    for (int i = 0; i < N; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.getGroupId() == group) {
        item.setEnabled(enabled);
      }
    }
  }
Пример #6
0
  private static int findInsertIndex(ArrayList<MenuItemImpl> items, int ordering) {
    for (int i = items.size() - 1; i >= 0; i--) {
      MenuItemImpl item = items.get(i);
      if (item.getOrdering() <= ordering) {
        return i + 1;
      }
    }

    return 0;
  }
Пример #7
0
  public void setGroupCheckable(int group, boolean checkable, boolean exclusive) {
    final int N = mItems.size();

    for (int i = 0; i < N; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.getGroupId() == group) {
        item.setExclusiveCheckable(exclusive);
        item.setCheckable(checkable);
      }
    }
  }
Пример #8
0
  public int findItemIndex(int id) {
    final int size = size();

    for (int i = 0; i < size; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.getItemId() == id) {
        return i;
      }
    }

    return -1;
  }
Пример #9
0
  public boolean hasVisibleItems() {
    final int size = size();

    for (int i = 0; i < size; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.isVisible()) {
        return true;
      }
    }

    return false;
  }
Пример #10
0
 public void localeChanged() {
   this.setText(Strings.get("fileMenu"));
   newi.setText(Strings.get("fileNewItem"));
   open.setText(Strings.get("fileOpenItem"));
   openRecent.localeChanged();
   close.setText(Strings.get("fileCloseItem"));
   save.setText(Strings.get("fileSaveItem"));
   saveAs.setText(Strings.get("fileSaveAsItem"));
   exportImage.setText(Strings.get("fileExportImageItem"));
   print.setText(Strings.get("filePrintItem"));
   prefs.setText(Strings.get("filePreferencesItem"));
   quit.setText(Strings.get("fileQuitItem"));
 }
Пример #11
0
  void setExclusiveItemChecked(MenuItem item) {
    final int group = item.getGroupId();

    final int N = mItems.size();
    for (int i = 0; i < N; i++) {
      MenuItemImpl curItem = mItems.get(i);
      if (curItem.getGroupId() == group) {
        if (!curItem.isExclusiveCheckable()) continue;
        if (!curItem.isCheckable()) continue;

        // Check the item meant to be checked, uncheck the others (that are in the group)
        curItem.setCheckedInt(curItem == item);
      }
    }
  }
Пример #12
0
  public void setGroupVisible(int group, boolean visible) {
    final int N = mItems.size();

    // We handle the notification of items being changed ourselves, so we use setVisibleInt rather
    // than setVisible and at the end notify of items being changed

    boolean changedAtLeastOneItem = false;
    for (int i = 0; i < N; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.getGroupId() == group) {
        if (item.setVisibleInt(visible)) changedAtLeastOneItem = true;
      }
    }

    if (changedAtLeastOneItem) onItemsChanged(true);
  }
Пример #13
0
  /** Adds an item to the menu. The other add methods funnel to this. */
  private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) {
    final int ordering = getOrdering(categoryOrder);

    final MenuItemImpl item =
        new MenuItemImpl(this, group, id, categoryOrder, ordering, title, mDefaultShowAsAction);

    if (mCurrentMenuInfo != null) {
      // Pass along the current menu info
      item.setMenuInfo(mCurrentMenuInfo);
    }

    mItems.add(findInsertIndex(mItems, ordering), item);
    onItemsChanged(true);

    return item;
  }
Пример #14
0
  public MenuItem findItem(int id) {
    final int size = size();
    for (int i = 0; i < size; i++) {
      MenuItemImpl item = mItems.get(i);
      if (item.getItemId() == id) {
        return item;
      } else if (item.hasSubMenu()) {
        MenuItem possibleItem = item.getSubMenu().findItem(id);

        if (possibleItem != null) {
          return possibleItem;
        }
      }
    }

    return null;
  }
Пример #15
0
 @Override
 public String getActionViewStatesKey() {
   final int itemId = mItem != null ? mItem.getItemId() : 0;
   if (itemId == 0) {
     return null;
   }
   return super.getActionViewStatesKey() + ":" + itemId;
 }
Пример #16
0
  public int findGroupIndex(int group, int start) {
    final int size = size();

    if (start < 0) {
      start = 0;
    }

    for (int i = start; i < size; i++) {
      final MenuItemImpl item = mItems.get(i);

      if (item.getGroupId() == group) {
        return i;
      }
    }

    return -1;
  }
Пример #17
0
  ArrayList<MenuItemImpl> getVisibleItems() {
    if (!mIsVisibleItemsStale) return mVisibleItems;

    // Refresh the visible items
    mVisibleItems.clear();

    final int itemsSize = mItems.size();
    MenuItemImpl item;
    for (int i = 0; i < itemsSize; i++) {
      item = mItems.get(i);
      if (item.isVisible()) mVisibleItems.add(item);
    }

    mIsVisibleItemsStale = false;
    mIsActionItemsStale = true;

    return mVisibleItems;
  }
Пример #18
0
  public MenuFile(LogisimMenuBar menubar) {
    this.menubar = menubar;
    openRecent = new OpenRecent(menubar);

    int menuMask = getToolkit().getMenuShortcutKeyMask();

    newi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, menuMask));
    merge.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, menuMask));
    open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, menuMask));
    close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, menuMask | InputEvent.SHIFT_MASK));
    save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, menuMask));
    saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, menuMask | InputEvent.SHIFT_MASK));
    print.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, menuMask));
    quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, menuMask));

    add(newi);
    add(merge);
    add(open);
    add(openRecent);
    addSeparator();
    add(close);
    add(save);
    add(saveAs);
    addSeparator();
    add(exportImage);
    add(print);
    if (!MacCompatibility.isPreferencesAutomaticallyPresent()) {
      addSeparator();
      add(prefs);
    }
    if (!MacCompatibility.isQuitAutomaticallyPresent()) {
      addSeparator();
      add(quit);
    }

    Project proj = menubar.getProject();
    newi.addActionListener(this);
    open.addActionListener(this);
    if (proj == null) {
      merge.setEnabled(false);
      close.setEnabled(false);
      save.setEnabled(false);
      saveAs.setEnabled(false);
    } else {
      merge.addActionListener(this);
      close.addActionListener(this);
      save.addActionListener(this);
      saveAs.addActionListener(this);
    }
    menubar.registerItem(LogisimMenuBar.EXPORT_IMAGE, exportImage);
    menubar.registerItem(LogisimMenuBar.PRINT, print);
    prefs.addActionListener(this);
    quit.addActionListener(this);
  }
Пример #19
0
  /**
   * This method determines which menu items get to be 'action items' that will appear in an action
   * bar and which items should be 'overflow items' in a secondary menu. The rules are as follows:
   *
   * <p>Items are considered for inclusion in the order specified within the menu. There is a limit
   * of mMaxActionItems as a total count, optionally including the overflow menu button itself. This
   * is a soft limit; if an item shares a group ID with an item previously included as an action
   * item, the new item will stay with its group and become an action item itself even if it breaks
   * the max item count limit. This is done to limit the conceptual complexity of the items
   * presented within an action bar. Only a few unrelated concepts should be presented to the user
   * in this space, and groups are treated as a single concept.
   *
   * <p>There is also a hard limit of consumed measurable space: mActionWidthLimit. This limit may
   * be broken by a single item that exceeds the remaining space, but no further items may be added.
   * If an item that is part of a group cannot fit within the remaining measured width, the entire
   * group will be demoted to overflow. This is done to ensure room for navigation and other
   * affordances in the action bar as well as reduce general UI clutter.
   *
   * <p>The space freed by demoting a full group cannot be consumed by future menu items. Once items
   * begin to overflow, all future items become overflow items as well. This is to avoid inadvertent
   * reordering that may break the app's intended design.
   */
  public void flagActionItems() {
    // Important side effect: if getVisibleItems is stale it may refresh,
    // which can affect action items staleness.
    final ArrayList<MenuItemImpl> visibleItems = getVisibleItems();

    if (!mIsActionItemsStale) {
      return;
    }

    // Presenters flag action items as needed.
    boolean flagged = false;
    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        flagged |= presenter.flagActionItems();
      }
    }

    if (flagged) {
      mActionItems.clear();
      mNonActionItems.clear();
      final int itemsSize = visibleItems.size();
      for (int i = 0; i < itemsSize; i++) {
        MenuItemImpl item = visibleItems.get(i);
        if (item.isActionButton()) {
          mActionItems.add(item);
        } else {
          mNonActionItems.add(item);
        }
      }
    } else {
      // Nobody flagged anything, everything is a non-action item.
      // (This happens during a first pass with no action-item presenters.)
      mActionItems.clear();
      mNonActionItems.clear();
      mNonActionItems.addAll(getVisibleItems());
    }
    mIsActionItemsStale = false;
  }
Пример #20
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);
      }
    }
  }
Пример #21
0
 @Override
 public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) {
   final MenuItem item =
       new MenuItemImpl(mContext)
           .setGroupId(groupId)
           .setItemId(itemId)
           .setOrder(order)
           .setTitle(title);
   final SubMenu subMenu = new SubMenuImpl(mContext, item);
   ((MenuItemImpl) item).setSubMenu(subMenu);
   if (order != 0) {
     mMenuItems.add(order, item);
   } else {
     mMenuItems.add(item);
   }
   return subMenu;
 }
Пример #22
0
 @Override
 public void setMnemonic(final char mnemonic) {
   menuItemDelegate.setMnemonic(mnemonic);
 }
Пример #23
0
 @Override
 public void setText(final String text) {
   menuItemDelegate.setText(text);
 }
Пример #24
0
 public SubMenu setIcon(Drawable icon) {
   mItem.setIcon(icon);
   return this;
 }
Пример #25
0
 @Override
 public Menu getUiReference() {
   return (Menu) menuItemDelegate.getUiReference();
 }
Пример #26
0
 public SubMenu setIcon(int iconRes) {
   mItem.setIcon(iconRes);
   return this;
 }