1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/menu/GeckoMenuInflater.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,155 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.menu; 1.9 + 1.10 +import org.mozilla.gecko.R; 1.11 + 1.12 +import org.xmlpull.v1.XmlPullParser; 1.13 +import org.xmlpull.v1.XmlPullParserException; 1.14 + 1.15 +import android.content.Context; 1.16 +import android.content.res.TypedArray; 1.17 +import android.content.res.XmlResourceParser; 1.18 +import android.os.Build; 1.19 +import android.util.AttributeSet; 1.20 +import android.util.Xml; 1.21 +import android.view.InflateException; 1.22 +import android.view.Menu; 1.23 +import android.view.MenuInflater; 1.24 +import android.view.MenuItem; 1.25 +import android.view.SubMenu; 1.26 + 1.27 +import java.io.IOException; 1.28 + 1.29 +public class GeckoMenuInflater extends MenuInflater { 1.30 + private static final String LOGTAG = "GeckoMenuInflater"; 1.31 + 1.32 + private static final String TAG_MENU = "menu"; 1.33 + private static final String TAG_ITEM = "item"; 1.34 + private static final int NO_ID = 0; 1.35 + 1.36 + private Context mContext; 1.37 + 1.38 + // Private class to hold the parsed menu item. 1.39 + private class ParsedItem { 1.40 + public int id; 1.41 + public int order; 1.42 + public CharSequence title; 1.43 + public int iconRes; 1.44 + public boolean checkable; 1.45 + public boolean checked; 1.46 + public boolean visible; 1.47 + public boolean enabled; 1.48 + public int showAsAction; 1.49 + public boolean hasSubMenu; 1.50 + } 1.51 + 1.52 + public GeckoMenuInflater(Context context) { 1.53 + super(context); 1.54 + mContext = context; 1.55 + } 1.56 + 1.57 + @Override 1.58 + public void inflate(int menuRes, Menu menu) { 1.59 + 1.60 + // This does not check for a well-formed XML. 1.61 + 1.62 + XmlResourceParser parser = null; 1.63 + try { 1.64 + parser = mContext.getResources().getXml(menuRes); 1.65 + AttributeSet attrs = Xml.asAttributeSet(parser); 1.66 + 1.67 + parseMenu(parser, attrs, menu); 1.68 + 1.69 + } catch (XmlPullParserException e) { 1.70 + throw new InflateException("Error inflating menu XML", e); 1.71 + } catch (IOException e) { 1.72 + throw new InflateException("Error inflating menu XML", e); 1.73 + } finally { 1.74 + if (parser != null) 1.75 + parser.close(); 1.76 + } 1.77 + } 1.78 + 1.79 + private void parseMenu(XmlResourceParser parser, AttributeSet attrs, Menu menu) 1.80 + throws XmlPullParserException, IOException { 1.81 + ParsedItem item = null; 1.82 + 1.83 + String tag; 1.84 + int eventType = parser.getEventType(); 1.85 + 1.86 + do { 1.87 + tag = parser.getName(); 1.88 + 1.89 + switch (eventType) { 1.90 + case XmlPullParser.START_TAG: 1.91 + if (tag.equals(TAG_ITEM)) { 1.92 + // Parse the menu item. 1.93 + item = new ParsedItem(); 1.94 + parseItem(item, attrs); 1.95 + } else if (tag.equals(TAG_MENU)) { 1.96 + if (item != null) { 1.97 + // Add the submenu item. 1.98 + SubMenu subMenu = menu.addSubMenu(NO_ID, item.id, item.order, item.title); 1.99 + item.hasSubMenu = true; 1.100 + 1.101 + // Set the menu item in main menu. 1.102 + MenuItem menuItem = subMenu.getItem(); 1.103 + setValues(item, menuItem); 1.104 + 1.105 + // Start parsing the sub menu. 1.106 + parseMenu(parser, attrs, subMenu); 1.107 + } 1.108 + } 1.109 + break; 1.110 + 1.111 + case XmlPullParser.END_TAG: 1.112 + if (parser.getName().equals(TAG_ITEM)) { 1.113 + if (!item.hasSubMenu) { 1.114 + // Add the item. 1.115 + MenuItem menuItem = menu.add(NO_ID, item.id, item.order, item.title); 1.116 + setValues(item, menuItem); 1.117 + } 1.118 + } else if (tag.equals(TAG_MENU)) { 1.119 + return; 1.120 + } 1.121 + break; 1.122 + } 1.123 + 1.124 + eventType = parser.next(); 1.125 + 1.126 + } while (eventType != XmlPullParser.END_DOCUMENT); 1.127 + } 1.128 + 1.129 + public void parseItem(ParsedItem item, AttributeSet attrs) { 1.130 + TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.MenuItem); 1.131 + 1.132 + item.id = a.getResourceId(R.styleable.MenuItem_android_id, NO_ID); 1.133 + item.order = a.getInt(R.styleable.MenuItem_android_orderInCategory, 0); 1.134 + item.title = a.getText(R.styleable.MenuItem_android_title); 1.135 + item.iconRes = a.getResourceId(R.styleable.MenuItem_android_icon, 0); 1.136 + item.checkable = a.getBoolean(R.styleable.MenuItem_android_checkable, false); 1.137 + item.checked = a.getBoolean(R.styleable.MenuItem_android_checked, false); 1.138 + item.visible = a.getBoolean(R.styleable.MenuItem_android_visible, true); 1.139 + item.enabled = a.getBoolean(R.styleable.MenuItem_android_enabled, true); 1.140 + item.hasSubMenu = false; 1.141 + 1.142 + if (Build.VERSION.SDK_INT >= 11) 1.143 + item.showAsAction = a.getInt(R.styleable.MenuItem_android_showAsAction, 0); 1.144 + 1.145 + a.recycle(); 1.146 + } 1.147 + 1.148 + public void setValues(ParsedItem item, MenuItem menuItem) { 1.149 + menuItem.setChecked(item.checked) 1.150 + .setVisible(item.visible) 1.151 + .setEnabled(item.enabled) 1.152 + .setCheckable(item.checkable) 1.153 + .setIcon(item.iconRes); 1.154 + 1.155 + if (Build.VERSION.SDK_INT >= 11) 1.156 + menuItem.setShowAsAction(item.showAsAction); 1.157 + } 1.158 +}