зеркало из https://github.com/mozilla/gecko-dev.git
Bug 785994: Submenu for custom menu. [r=mfinkle]
--HG-- extra : rebase_source : 473a746b802fdc9ff10c4bdc7a95e4a13700f23a
This commit is contained in:
Родитель
87922539e0
Коммит
de35e11712
|
@ -716,7 +716,11 @@ abstract public class BrowserApp extends GeckoApp
|
|||
|
||||
@Override
|
||||
public void closeOptionsMenu() {
|
||||
if (!mBrowserToolbar.closeOptionsMenu())
|
||||
boolean closed = mBrowserToolbar.closeOptionsMenu();
|
||||
|
||||
if (closed)
|
||||
onOptionsMenuClosed(mMenu);
|
||||
else
|
||||
super.closeOptionsMenu();
|
||||
}
|
||||
|
||||
|
|
|
@ -304,6 +304,12 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
|||
if (mHasSoftMenuButton) {
|
||||
mMenuPopup = new MenuPopup(mActivity);
|
||||
mMenuPopup.setPanelView(panel);
|
||||
|
||||
mMenuPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
public void onDismiss() {
|
||||
mActivity.onOptionsMenuClosed(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -696,7 +702,7 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
|||
}
|
||||
|
||||
// MenuPopup holds the MenuPanel in Honeycomb/ICS devices with no hardware key
|
||||
public class MenuPopup extends PopupWindow {
|
||||
public static class MenuPopup extends PopupWindow {
|
||||
private RelativeLayout mPanel;
|
||||
|
||||
public MenuPopup(Context context) {
|
||||
|
|
|
@ -142,6 +142,7 @@ abstract public class GeckoApp
|
|||
public SurfaceView cameraView;
|
||||
public static GeckoApp mAppContext;
|
||||
public boolean mDOMFullScreen = false;
|
||||
protected MenuPresenter mMenuPresenter;
|
||||
protected MenuPanel mMenuPanel;
|
||||
protected Menu mMenu;
|
||||
private static GeckoThread sGeckoThread;
|
||||
|
@ -466,10 +467,14 @@ abstract public class GeckoApp
|
|||
return super.getMenuInflater();
|
||||
}
|
||||
|
||||
public View getMenuPanel() {
|
||||
public MenuPanel getMenuPanel() {
|
||||
return mMenuPanel;
|
||||
}
|
||||
|
||||
public MenuPresenter getMenuPresenter() {
|
||||
return mMenuPresenter;
|
||||
}
|
||||
|
||||
// MenuPanel holds the scrollable Menu
|
||||
public static class MenuPanel extends LinearLayout {
|
||||
public MenuPanel(Context context, AttributeSet attrs) {
|
||||
|
@ -497,11 +502,41 @@ abstract public class GeckoApp
|
|||
}
|
||||
}
|
||||
|
||||
// MenuPresenter takes care of proper animation and inflation.
|
||||
public class MenuPresenter {
|
||||
GeckoApp mActivity;
|
||||
|
||||
public MenuPresenter(GeckoApp activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
public void show(GeckoMenu menu) {
|
||||
mActivity.closeOptionsMenu();
|
||||
|
||||
MenuPanel panel = mActivity.getMenuPanel();
|
||||
panel.removeAllViews();
|
||||
panel.addView(menu);
|
||||
|
||||
mActivity.openOptionsMenu();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
mActivity.closeOptionsMenu();
|
||||
}
|
||||
|
||||
public void onOptionsMenuClosed() {
|
||||
MenuPanel panel = mActivity.getMenuPanel();
|
||||
panel.removeAllViews();
|
||||
panel.addView((GeckoMenu) mMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreatePanelView(int featureId) {
|
||||
if (Build.VERSION.SDK_INT >= 11 && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (mMenuPanel == null) {
|
||||
mMenuPanel = new MenuPanel(mAppContext, null);
|
||||
mMenuPresenter = new MenuPresenter(this);
|
||||
} else {
|
||||
// Prepare the panel everytime before showing the menu.
|
||||
onPreparePanel(featureId, mMenuPanel, mMenu);
|
||||
|
@ -573,6 +608,12 @@ abstract public class GeckoApp
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOptionsMenuClosed(Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
mMenuPresenter.onOptionsMenuClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class GeckoMenu extends ListView
|
|||
public int getActionItemsCount();
|
||||
}
|
||||
|
||||
private static final int NO_ID = 0;
|
||||
protected static final int NO_ID = 0;
|
||||
|
||||
// List of all menu items.
|
||||
private List<GeckoMenuItem> mItems;
|
||||
|
@ -60,7 +60,6 @@ public class GeckoMenu extends ListView
|
|||
|
||||
public GeckoMenu(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mContext = context;
|
||||
|
||||
setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||
|
@ -145,22 +144,38 @@ public class GeckoMenu extends ListView
|
|||
|
||||
@Override
|
||||
public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) {
|
||||
return null;
|
||||
MenuItem menuItem = add(groupId, itemId, order, title);
|
||||
GeckoSubMenu subMenu = new GeckoSubMenu(mContext, null);
|
||||
subMenu.setMenuItem(menuItem);
|
||||
((GeckoMenuItem) menuItem).setSubMenu(subMenu);
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
|
||||
return null;
|
||||
MenuItem menuItem = add(groupId, itemId, order, titleRes);
|
||||
GeckoSubMenu subMenu = new GeckoSubMenu(mContext, null);
|
||||
subMenu.setMenuItem(menuItem);
|
||||
((GeckoMenuItem) menuItem).setSubMenu(subMenu);
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu addSubMenu(CharSequence title) {
|
||||
return null;
|
||||
MenuItem menuItem = add(title);
|
||||
GeckoSubMenu subMenu = new GeckoSubMenu(mContext, null);
|
||||
subMenu.setMenuItem(menuItem);
|
||||
((GeckoMenuItem) menuItem).setSubMenu(subMenu);
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu addSubMenu(int titleRes) {
|
||||
return null;
|
||||
MenuItem menuItem = add(titleRes);
|
||||
GeckoSubMenu subMenu = new GeckoSubMenu(mContext, null);
|
||||
subMenu.setMenuItem(menuItem);
|
||||
((GeckoMenuItem) menuItem).setSubMenu(subMenu);
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -174,8 +189,14 @@ public class GeckoMenu extends ListView
|
|||
@Override
|
||||
public MenuItem findItem(int id) {
|
||||
for (GeckoMenuItem menuItem : mItems) {
|
||||
if (menuItem.getItemId() == id)
|
||||
if (menuItem.getItemId() == id) {
|
||||
return menuItem;
|
||||
} else if (menuItem.hasSubMenu()) {
|
||||
SubMenu subMenu = menuItem.getSubMenu();
|
||||
MenuItem item = subMenu.findItem(id);
|
||||
if (item != null)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -298,10 +319,18 @@ public class GeckoMenu extends ListView
|
|||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
Activity activity = (Activity) mContext;
|
||||
boolean result = activity.onOptionsItemSelected(item);
|
||||
activity.closeOptionsMenu();
|
||||
return result;
|
||||
GeckoApp activity = (GeckoApp) mContext;
|
||||
|
||||
if (!item.hasSubMenu()) {
|
||||
boolean result = activity.onOptionsItemSelected(item);
|
||||
activity.closeOptionsMenu();
|
||||
return result;
|
||||
} else {
|
||||
// Dismiss this menu.
|
||||
GeckoApp.MenuPresenter presenter = activity.getMenuPresenter();
|
||||
presenter.show((GeckoSubMenu) item.getSubMenu());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setActionItemBarPresenter(ActionItemBarPresenter presenter) {
|
||||
|
|
|
@ -16,17 +16,21 @@ import android.view.InflateException;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GeckoMenuInflater extends MenuInflater {
|
||||
private static final String LOGTAG = "GeckoMenuInflater";
|
||||
|
||||
private static final String TAG_MENU = "menu";
|
||||
private static final String TAG_ITEM = "item";
|
||||
private static final int NO_ID = 0;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private boolean isSubMenu;
|
||||
|
||||
// Private class to hold the parsed menu item.
|
||||
private class ParsedItem {
|
||||
public int id;
|
||||
|
@ -43,13 +47,13 @@ public class GeckoMenuInflater extends MenuInflater {
|
|||
public GeckoMenuInflater(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
|
||||
isSubMenu = false;
|
||||
}
|
||||
|
||||
public void inflate(int menuRes, Menu menu) {
|
||||
|
||||
// This is a very minimal parser for the custom menu.
|
||||
// This assumes that there is only one menu tag in the resource file.
|
||||
// This does not support sub-menus.
|
||||
// This does not check for a well-formed XML.
|
||||
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
|
@ -57,6 +61,8 @@ public class GeckoMenuInflater extends MenuInflater {
|
|||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
ParsedItem item = null;
|
||||
SubMenu subMenu = null;
|
||||
MenuItem menuItem = null;
|
||||
|
||||
String tag;
|
||||
int eventType = parser.getEventType();
|
||||
|
@ -70,14 +76,35 @@ public class GeckoMenuInflater extends MenuInflater {
|
|||
// Parse the menu item.
|
||||
item = new ParsedItem();
|
||||
parseItem(item, attrs);
|
||||
}
|
||||
} else if (tag.equals(TAG_MENU)) {
|
||||
if (item != null) {
|
||||
// Start parsing the sub menu.
|
||||
isSubMenu = true;
|
||||
subMenu = menu.addSubMenu(NO_ID, item.id, item.order, item.title);
|
||||
menuItem = subMenu.getItem();
|
||||
|
||||
// Set the menu item in main menu.
|
||||
setValues(item, menuItem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XmlPullParser.END_TAG:
|
||||
if (parser.getName().equals(TAG_ITEM)) {
|
||||
// Add the item.
|
||||
MenuItem menuItem = menu.add(NO_ID, item.id, item.order, item.title);
|
||||
setValues(item, menuItem);
|
||||
if (isSubMenu && subMenu == null) {
|
||||
isSubMenu = false;
|
||||
} else {
|
||||
// Add the item.
|
||||
if (subMenu == null)
|
||||
menuItem = menu.add(NO_ID, item.id, item.order, item.title);
|
||||
else
|
||||
menuItem = subMenu.add(NO_ID, item.id, item.order, item.title);
|
||||
|
||||
setValues(item, menuItem);
|
||||
}
|
||||
} else if (tag.equals(TAG_MENU)) {
|
||||
// End of sub menu.
|
||||
subMenu = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener {
|
|||
private boolean mEnabled;
|
||||
private Drawable mIcon;
|
||||
private int mIconRes;
|
||||
private GeckoSubMenu mSubMenu;
|
||||
private MenuItem.OnMenuItemClickListener mMenuItemClickListener;
|
||||
private OnVisibilityChangedListener mVisibilityChangedListener;
|
||||
private OnShowAsActionChangedListener mShowAsActionChangedListener;
|
||||
|
@ -141,7 +142,7 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener {
|
|||
|
||||
@Override
|
||||
public SubMenu getSubMenu() {
|
||||
return null;
|
||||
return mSubMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +157,7 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener {
|
|||
|
||||
@Override
|
||||
public boolean hasSubMenu() {
|
||||
return false;
|
||||
return (mSubMenu != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -308,6 +309,11 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener {
|
|||
return this;
|
||||
}
|
||||
|
||||
public MenuItem setSubMenu(GeckoSubMenu subMenu) {
|
||||
mSubMenu = subMenu;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItem setTitle(CharSequence title) {
|
||||
mTitle = title;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeckoSubMenu extends GeckoMenu
|
||||
implements SubMenu {
|
||||
private static final String LOGTAG = "GeckoSubMenu";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
// MenuItem associated with this submenu.
|
||||
private MenuItem mMenuItem;
|
||||
|
||||
public GeckoSubMenu(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearHeader() {
|
||||
}
|
||||
|
||||
public SubMenu setMenuItem(MenuItem item) {
|
||||
mMenuItem = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItem getItem() {
|
||||
return mMenuItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setHeaderIcon(Drawable icon) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setHeaderIcon(int iconRes) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setHeaderTitle(CharSequence title) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setHeaderTitle(int titleRes) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setHeaderView(View view) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setIcon(Drawable icon) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubMenu setIcon(int iconRes) {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -81,6 +81,7 @@ FENNEC_JAVA_FILES = \
|
|||
GeckoMenuInflater.java \
|
||||
GeckoMenuItem.java \
|
||||
GeckoMessageReceiver.java \
|
||||
GeckoSubMenu.java \
|
||||
GeckoPreferences.java \
|
||||
GeckoProfile.java \
|
||||
GeckoThread.java \
|
||||
|
|
|
@ -124,6 +124,7 @@ size. -->
|
|||
<!ENTITY save_as_pdf "Save as PDF">
|
||||
<!ENTITY find_in_page "Find in Page">
|
||||
<!ENTITY desktop_mode "Request Desktop Site">
|
||||
<!ENTITY tools "Tools">
|
||||
|
||||
<!-- Localization note (find_text, find_prev, find_next, find_close) : These strings are used
|
||||
as alternate text for accessibility. They are not visible in the UI. -->
|
||||
|
|
|
@ -28,10 +28,6 @@
|
|||
gecko:icon="@drawable/ic_menu_reading_list_add"
|
||||
gecko:title="@string/reading_list" />
|
||||
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:icon="@drawable/ic_menu_find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
@ -41,14 +37,26 @@
|
|||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
<item gecko:title="@string/tools">
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
<menu>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item gecko:id="@+id/char_encoding"
|
||||
gecko:visible="false"
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
gecko:icon="@drawable/ic_menu_reading_list_add"
|
||||
gecko:title="@string/reading_list" />
|
||||
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:icon="@drawable/ic_menu_find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
@ -42,14 +38,26 @@
|
|||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
<item gecko:title="@string/tools">
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
<menu>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item gecko:id="@+id/char_encoding"
|
||||
gecko:visible="false"
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
gecko:icon="@drawable/ic_menu_reading_list_add"
|
||||
gecko:title="@string/reading_list" />
|
||||
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:icon="@drawable/ic_menu_find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
@ -42,14 +38,26 @@
|
|||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
<item gecko:title="@string/tools">
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
<menu>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
<item gecko:id="@+id/save_as_pdf"
|
||||
gecko:icon="@drawable/ic_menu_save_as_pdf"
|
||||
gecko:title="@string/save_as_pdf" />
|
||||
|
||||
<item gecko:id="@+id/addons"
|
||||
gecko:title="@string/addons"/>
|
||||
|
||||
<item gecko:id="@+id/downloads"
|
||||
gecko:title="@string/downloads"/>
|
||||
|
||||
<item gecko:id="@+id/apps"
|
||||
gecko:title="@string/apps"/>
|
||||
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item gecko:id="@+id/char_encoding"
|
||||
gecko:visible="false"
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
<string name="save_as_pdf">&save_as_pdf;</string>
|
||||
<string name="find_in_page">&find_in_page;</string>
|
||||
<string name="desktop_mode">&desktop_mode;</string>
|
||||
<string name="tools">&tools;</string>
|
||||
|
||||
<string name="find_text">&find_text;</string>
|
||||
<string name="find_prev">&find_prev;</string>
|
||||
|
|
Загрузка…
Ссылка в новой задаче