summaryrefslogtreecommitdiffstats
path: root/actionbarsherlock/src/com/actionbarsherlock/view
diff options
context:
space:
mode:
Diffstat (limited to 'actionbarsherlock/src/com/actionbarsherlock/view')
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java224
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java170
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java39
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/Menu.java447
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java472
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java598
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java110
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/view/Window.java65
8 files changed, 2125 insertions, 0 deletions
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java b/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java
new file mode 100644
index 000000000..81b4cd4d2
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.view.View;
+
+
+/**
+ * Represents a contextual mode of the user interface. Action modes can be used for
+ * modal interactions with content and replace parts of the normal UI until finished.
+ * Examples of good action modes include selection modes, search, content editing, etc.
+ */
+public abstract class ActionMode {
+ private Object mTag;
+
+ /**
+ * Set a tag object associated with this ActionMode.
+ *
+ * <p>Like the tag available to views, this allows applications to associate arbitrary
+ * data with an ActionMode for later reference.
+ *
+ * @param tag Tag to associate with this ActionMode
+ *
+ * @see #getTag()
+ */
+ public void setTag(Object tag) {
+ mTag = tag;
+ }
+
+ /**
+ * Retrieve the tag object associated with this ActionMode.
+ *
+ * <p>Like the tag available to views, this allows applications to associate arbitrary
+ * data with an ActionMode for later reference.
+ *
+ * @return Tag associated with this ActionMode
+ *
+ * @see #setTag(Object)
+ */
+ public Object getTag() {
+ return mTag;
+ }
+
+ /**
+ * Set the title of the action mode. This method will have no visible effect if
+ * a custom view has been set.
+ *
+ * @param title Title string to set
+ *
+ * @see #setTitle(int)
+ * @see #setCustomView(View)
+ */
+ public abstract void setTitle(CharSequence title);
+
+ /**
+ * Set the title of the action mode. This method will have no visible effect if
+ * a custom view has been set.
+ *
+ * @param resId Resource ID of a string to set as the title
+ *
+ * @see #setTitle(CharSequence)
+ * @see #setCustomView(View)
+ */
+ public abstract void setTitle(int resId);
+
+ /**
+ * Set the subtitle of the action mode. This method will have no visible effect if
+ * a custom view has been set.
+ *
+ * @param subtitle Subtitle string to set
+ *
+ * @see #setSubtitle(int)
+ * @see #setCustomView(View)
+ */
+ public abstract void setSubtitle(CharSequence subtitle);
+
+ /**
+ * Set the subtitle of the action mode. This method will have no visible effect if
+ * a custom view has been set.
+ *
+ * @param resId Resource ID of a string to set as the subtitle
+ *
+ * @see #setSubtitle(CharSequence)
+ * @see #setCustomView(View)
+ */
+ public abstract void setSubtitle(int resId);
+
+ /**
+ * Set a custom view for this action mode. The custom view will take the place of
+ * the title and subtitle. Useful for things like search boxes.
+ *
+ * @param view Custom view to use in place of the title/subtitle.
+ *
+ * @see #setTitle(CharSequence)
+ * @see #setSubtitle(CharSequence)
+ */
+ public abstract void setCustomView(View view);
+
+ /**
+ * Invalidate the action mode and refresh menu content. The mode's
+ * {@link ActionMode.Callback} will have its
+ * {@link Callback#onPrepareActionMode(ActionMode, Menu)} method called.
+ * If it returns true the menu will be scanned for updated content and any relevant changes
+ * will be reflected to the user.
+ */
+ public abstract void invalidate();
+
+ /**
+ * Finish and close this action mode. The action mode's {@link ActionMode.Callback} will
+ * have its {@link Callback#onDestroyActionMode(ActionMode)} method called.
+ */
+ public abstract void finish();
+
+ /**
+ * Returns the menu of actions that this action mode presents.
+ * @return The action mode's menu.
+ */
+ public abstract Menu getMenu();
+
+ /**
+ * Returns the current title of this action mode.
+ * @return Title text
+ */
+ public abstract CharSequence getTitle();
+
+ /**
+ * Returns the current subtitle of this action mode.
+ * @return Subtitle text
+ */
+ public abstract CharSequence getSubtitle();
+
+ /**
+ * Returns the current custom view for this action mode.
+ * @return The current custom view
+ */
+ public abstract View getCustomView();
+
+ /**
+ * Returns a {@link MenuInflater} with the ActionMode's context.
+ */
+ public abstract MenuInflater getMenuInflater();
+
+ /**
+ * Returns whether the UI presenting this action mode can take focus or not.
+ * This is used by internal components within the framework that would otherwise
+ * present an action mode UI that requires focus, such as an EditText as a custom view.
+ *
+ * @return true if the UI used to show this action mode can take focus
+ * @hide Internal use only
+ */
+ public boolean isUiFocusable() {
+ return true;
+ }
+
+ /**
+ * Callback interface for action modes. Supplied to
+ * {@link View#startActionMode(Callback)}, a Callback
+ * configures and handles events raised by a user's interaction with an action mode.
+ *
+ * <p>An action mode's lifecycle is as follows:
+ * <ul>
+ * <li>{@link Callback#onCreateActionMode(ActionMode, Menu)} once on initial
+ * creation</li>
+ * <li>{@link Callback#onPrepareActionMode(ActionMode, Menu)} after creation
+ * and any time the {@link ActionMode} is invalidated</li>
+ * <li>{@link Callback#onActionItemClicked(ActionMode, MenuItem)} any time a
+ * contextual action button is clicked</li>
+ * <li>{@link Callback#onDestroyActionMode(ActionMode)} when the action mode
+ * is closed</li>
+ * </ul>
+ */
+ public interface Callback {
+ /**
+ * Called when action mode is first created. The menu supplied will be used to
+ * generate action buttons for the action mode.
+ *
+ * @param mode ActionMode being created
+ * @param menu Menu used to populate action buttons
+ * @return true if the action mode should be created, false if entering this
+ * mode should be aborted.
+ */
+ public boolean onCreateActionMode(ActionMode mode, Menu menu);
+
+ /**
+ * Called to refresh an action mode's action menu whenever it is invalidated.
+ *
+ * @param mode ActionMode being prepared
+ * @param menu Menu used to populate action buttons
+ * @return true if the menu or action mode was updated, false otherwise.
+ */
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu);
+
+ /**
+ * Called to report a user click on an action button.
+ *
+ * @param mode The current ActionMode
+ * @param item The item that was clicked
+ * @return true if this callback handled the event, false if the standard MenuItem
+ * invocation should continue.
+ */
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item);
+
+ /**
+ * Called when an action mode is about to be exited and destroyed.
+ *
+ * @param mode The current ActionMode being destroyed
+ */
+ public void onDestroyActionMode(ActionMode mode);
+ }
+} \ No newline at end of file
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java b/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java
new file mode 100644
index 000000000..ae7cb1fe0
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.content.Context;
+import android.view.View;
+
+/**
+ * This class is a mediator for accomplishing a given task, for example sharing a file.
+ * It is responsible for creating a view that performs an action that accomplishes the task.
+ * This class also implements other functions such a performing a default action.
+ * <p>
+ * An ActionProvider can be optionally specified for a {@link MenuItem} and in such a
+ * case it will be responsible for creating the action view that appears in the
+ * {@link android.app.ActionBar} as a substitute for the menu item when the item is
+ * displayed as an action item. Also the provider is responsible for performing a
+ * default action if a menu item placed on the overflow menu of the ActionBar is
+ * selected and none of the menu item callbacks has handled the selection. For this
+ * case the provider can also optionally provide a sub-menu for accomplishing the
+ * task at hand.
+ * </p>
+ * <p>
+ * There are two ways for using an action provider for creating and handling of action views:
+ * <ul>
+ * <li>
+ * Setting the action provider on a {@link MenuItem} directly by calling
+ * {@link MenuItem#setActionProvider(ActionProvider)}.
+ * </li>
+ * <li>
+ * Declaring the action provider in the menu XML resource. For example:
+ * <pre>
+ * <code>
+ * &lt;item android:id="@+id/my_menu_item"
+ * android:title="Title"
+ * android:icon="@drawable/my_menu_item_icon"
+ * android:showAsAction="ifRoom"
+ * android:actionProviderClass="foo.bar.SomeActionProvider" /&gt;
+ * </code>
+ * </pre>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @see MenuItem#setActionProvider(ActionProvider)
+ * @see MenuItem#getActionProvider()
+ */
+public abstract class ActionProvider {
+ private SubUiVisibilityListener mSubUiVisibilityListener;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context Context for accessing resources.
+ */
+ public ActionProvider(Context context) {
+ }
+
+ /**
+ * Factory method for creating new action views.
+ *
+ * @return A new action view.
+ */
+ public abstract View onCreateActionView();
+
+ /**
+ * Performs an optional default action.
+ * <p>
+ * For the case of an action provider placed in a menu item not shown as an action this
+ * method is invoked if previous callbacks for processing menu selection has handled
+ * the event.
+ * </p>
+ * <p>
+ * A menu item selection is processed in the following order:
+ * <ul>
+ * <li>
+ * Receiving a call to {@link MenuItem.OnMenuItemClickListener#onMenuItemClick
+ * MenuItem.OnMenuItemClickListener.onMenuItemClick}.
+ * </li>
+ * <li>
+ * Receiving a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+ * Activity.onOptionsItemSelected(MenuItem)}
+ * </li>
+ * <li>
+ * Receiving a call to {@link android.app.Fragment#onOptionsItemSelected(MenuItem)
+ * Fragment.onOptionsItemSelected(MenuItem)}
+ * </li>
+ * <li>
+ * Launching the {@link android.content.Intent} set via
+ * {@link MenuItem#setIntent(android.content.Intent) MenuItem.setIntent(android.content.Intent)}
+ * </li>
+ * <li>
+ * Invoking this method.
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * The default implementation does not perform any action and returns false.
+ * </p>
+ */
+ public boolean onPerformDefaultAction() {
+ return false;
+ }
+
+ /**
+ * Determines if this ActionProvider has a submenu associated with it.
+ *
+ * <p>Associated submenus will be shown when an action view is not. This
+ * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)}
+ * after the call to {@link #onPerformDefaultAction()} and before a submenu is
+ * displayed to the user.
+ *
+ * @return true if the item backed by this provider should have an associated submenu
+ */
+ public boolean hasSubMenu() {
+ return false;
+ }
+
+ /**
+ * Called to prepare an associated submenu for the menu item backed by this ActionProvider.
+ *
+ * <p>if {@link #hasSubMenu()} returns true, this method will be called when the
+ * menu item is selected to prepare the submenu for presentation to the user. Apps
+ * may use this to create or alter submenu content right before display.
+ *
+ * @param subMenu Submenu that will be displayed
+ */
+ public void onPrepareSubMenu(SubMenu subMenu) {
+ }
+
+ /**
+ * Notify the system that the visibility of an action view's sub-UI such as
+ * an anchored popup has changed. This will affect how other system
+ * visibility notifications occur.
+ *
+ * @hide Pending future API approval
+ */
+ public void subUiVisibilityChanged(boolean isVisible) {
+ if (mSubUiVisibilityListener != null) {
+ mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible);
+ }
+ }
+
+ /**
+ * @hide Internal use only
+ */
+ public void setSubUiVisibilityListener(SubUiVisibilityListener listener) {
+ mSubUiVisibilityListener = listener;
+ }
+
+ /**
+ * @hide Internal use only
+ */
+ public interface SubUiVisibilityListener {
+ public void onSubUiVisibilityChanged(boolean isVisible);
+ }
+}
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java b/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java
new file mode 100644
index 000000000..43281b013
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+/**
+ * When a {@link View} implements this interface it will receive callbacks
+ * when expanded or collapsed as an action view alongside the optional,
+ * app-specified callbacks to {@link OnActionExpandListener}.
+ *
+ * <p>See {@link MenuItem} for more information about action views.
+ * See {@link android.app.ActionBar} for more information about the action bar.
+ */
+public interface CollapsibleActionView {
+ /**
+ * Called when this view is expanded as an action view.
+ * See {@link MenuItem#expandActionView()}.
+ */
+ public void onActionViewExpanded();
+
+ /**
+ * Called when this view is collapsed as an action view.
+ * See {@link MenuItem#collapseActionView()}.
+ */
+ public void onActionViewCollapsed();
+}
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java b/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java
new file mode 100644
index 000000000..951f4ccef
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.view.KeyEvent;
+
+/**
+ * Interface for managing the items in a menu.
+ * <p>
+ * By default, every Activity supports an options menu of actions or options.
+ * You can add items to this menu and handle clicks on your additions. The
+ * easiest way of adding menu items is inflating an XML file into the
+ * {@link Menu} via {@link MenuInflater}. The easiest way of attaching code to
+ * clicks is via {@link Activity#onOptionsItemSelected(MenuItem)} and
+ * {@link Activity#onContextItemSelected(MenuItem)}.
+ * <p>
+ * Different menu types support different features:
+ * <ol>
+ * <li><b>Context menus</b>: Do not support item shortcuts and item icons.
+ * <li><b>Options menus</b>: The <b>icon menus</b> do not support item check
+ * marks and only show the item's
+ * {@link MenuItem#setTitleCondensed(CharSequence) condensed title}. The
+ * <b>expanded menus</b> (only available if six or more menu items are visible,
+ * reached via the 'More' item in the icon menu) do not show item icons, and
+ * item check marks are discouraged.
+ * <li><b>Sub menus</b>: Do not support item icons, or nested sub menus.
+ * </ol>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
+ */
+public interface Menu {
+
+ /**
+ * This is the part of an order integer that the user can provide.
+ * @hide
+ */
+ static final int USER_MASK = 0x0000ffff;
+ /**
+ * Bit shift of the user portion of the order integer.
+ * @hide
+ */
+ static final int USER_SHIFT = 0;
+
+ /**
+ * This is the part of an order integer that supplies the category of the
+ * item.
+ * @hide
+ */
+ static final int CATEGORY_MASK = 0xffff0000;
+ /**
+ * Bit shift of the category portion of the order integer.
+ * @hide
+ */
+ static final int CATEGORY_SHIFT = 16;
+
+ /**
+ * Value to use for group and item identifier integers when you don't care
+ * about them.
+ */
+ static final int NONE = 0;
+
+ /**
+ * First value for group and item identifier integers.
+ */
+ static final int FIRST = 1;
+
+ // Implementation note: Keep these CATEGORY_* in sync with the category enum
+ // in attrs.xml
+
+ /**
+ * Category code for the order integer for items/groups that are part of a
+ * container -- or/add this with your base value.
+ */
+ static final int CATEGORY_CONTAINER = 0x00010000;
+
+ /**
+ * Category code for the order integer for items/groups that are provided by
+ * the system -- or/add this with your base value.
+ */
+ static final int CATEGORY_SYSTEM = 0x00020000;
+
+ /**
+ * Category code for the order integer for items/groups that are
+ * user-supplied secondary (infrequently used) options -- or/add this with
+ * your base value.
+ */
+ static final int CATEGORY_SECONDARY = 0x00030000;
+
+ /**
+ * Category code for the order integer for items/groups that are
+ * alternative actions on the data that is currently displayed -- or/add
+ * this with your base value.
+ */
+ static final int CATEGORY_ALTERNATIVE = 0x00040000;
+
+ /**
+ * Flag for {@link #addIntentOptions}: if set, do not automatically remove
+ * any existing menu items in the same group.
+ */
+ static final int FLAG_APPEND_TO_GROUP = 0x0001;
+
+ /**
+ * Flag for {@link #performShortcut}: if set, do not close the menu after
+ * executing the shortcut.
+ */
+ static final int FLAG_PERFORM_NO_CLOSE = 0x0001;
+
+ /**
+ * Flag for {@link #performShortcut(int, KeyEvent, int)}: if set, always
+ * close the menu after executing the shortcut. Closing the menu also resets
+ * the prepared state.
+ */
+ static final int FLAG_ALWAYS_PERFORM_CLOSE = 0x0002;
+
+ /**
+ * Add a new item to the menu. This item displays the given title for its
+ * label.
+ *
+ * @param title The text to display for the item.
+ * @return The newly added menu item.
+ */
+ public MenuItem add(CharSequence title);
+
+ /**
+ * Add a new item to the menu. This item displays the given title for its
+ * label.
+ *
+ * @param titleRes Resource identifier of title string.
+ * @return The newly added menu item.
+ */
+ public MenuItem add(int titleRes);
+
+ /**
+ * Add a new item to the menu. This item displays the given title for its
+ * label.
+ *
+ * @param groupId The group identifier that this item should be part of.
+ * This can be used to define groups of items for batch state
+ * changes. Normally use {@link #NONE} if an item should not be in a
+ * group.
+ * @param itemId Unique item ID. Use {@link #NONE} if you do not need a
+ * unique ID.
+ * @param order The order for the item. Use {@link #NONE} if you do not care
+ * about the order. See {@link MenuItem#getOrder()}.
+ * @param title The text to display for the item.
+ * @return The newly added menu item.
+ */
+ public MenuItem add(int groupId, int itemId, int order, CharSequence title);
+
+ /**
+ * Variation on {@link #add(int, int, int, CharSequence)} that takes a
+ * string resource identifier instead of the string itself.
+ *
+ * @param groupId The group identifier that this item should be part of.
+ * This can also be used to define groups of items for batch state
+ * changes. Normally use {@link #NONE} if an item should not be in a
+ * group.
+ * @param itemId Unique item ID. Use {@link #NONE} if you do not need a
+ * unique ID.
+ * @param order The order for the item. Use {@link #NONE} if you do not care
+ * about the order. See {@link MenuItem#getOrder()}.
+ * @param titleRes Resource identifier of title string.
+ * @return The newly added menu item.
+ */
+ public MenuItem add(int groupId, int itemId, int order, int titleRes);
+
+ /**
+ * Add a new sub-menu to the menu. This item displays the given title for
+ * its label. To modify other attributes on the submenu's menu item, use
+ * {@link SubMenu#getItem()}.
+ *
+ * @param title The text to display for the item.
+ * @return The newly added sub-menu
+ */
+ SubMenu addSubMenu(final CharSequence title);
+
+ /**
+ * Add a new sub-menu to the menu. This item displays the given title for
+ * its label. To modify other attributes on the submenu's menu item, use
+ * {@link SubMenu#getItem()}.
+ *
+ * @param titleRes Resource identifier of title string.
+ * @return The newly added sub-menu
+ */
+ SubMenu addSubMenu(final int titleRes);
+
+ /**
+ * Add a new sub-menu to the menu. This item displays the given
+ * <var>title</var> for its label. To modify other attributes on the
+ * submenu's menu item, use {@link SubMenu#getItem()}.
+ *<p>
+ * Note that you can only have one level of sub-menus, i.e. you cannnot add
+ * a subMenu to a subMenu: An {@link UnsupportedOperationException} will be
+ * thrown if you try.
+ *
+ * @param groupId The group identifier that this item should be part of.
+ * This can also be used to define groups of items for batch state
+ * changes. Normally use {@link #NONE} if an item should not be in a
+ * group.
+ * @param itemId Unique item ID. Use {@link #NONE} if you do not need a
+ * unique ID.
+ * @param order The order for the item. Use {@link #NONE} if you do not care
+ * about the order. See {@link MenuItem#getOrder()}.
+ * @param title The text to display for the item.
+ * @return The newly added sub-menu
+ */
+ SubMenu addSubMenu(final int groupId, final int itemId, int order, final CharSequence title);
+
+ /**
+ * Variation on {@link #addSubMenu(int, int, int, CharSequence)} that takes
+ * a string resource identifier for the title instead of the string itself.
+ *
+ * @param groupId The group identifier that this item should be part of.
+ * This can also be used to define groups of items for batch state
+ * changes. Normally use {@link #NONE} if an item should not be in a group.
+ * @param itemId Unique item ID. Use {@link #NONE} if you do not need a unique ID.
+ * @param order The order for the item. Use {@link #NONE} if you do not care about the
+ * order. See {@link MenuItem#getOrder()}.
+ * @param titleRes Resource identifier of title string.
+ * @return The newly added sub-menu
+ */
+ SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes);
+
+ /**
+ * Add a group of menu items corresponding to actions that can be performed
+ * for a particular Intent. The Intent is most often configured with a null
+ * action, the data that the current activity is working with, and includes
+ * either the {@link Intent#CATEGORY_ALTERNATIVE} or
+ * {@link Intent#CATEGORY_SELECTED_ALTERNATIVE} to find activities that have
+ * said they would like to be included as optional action. You can, however,
+ * use any Intent you want.
+ *
+ * <p>
+ * See {@link android.content.pm.PackageManager#queryIntentActivityOptions}
+ * for more * details on the <var>caller</var>, <var>specifics</var>, and
+ * <var>intent</var> arguments. The list returned by that function is used
+ * to populate the resulting menu items.
+ *
+ * <p>
+ * All of the menu items of possible options for the intent will be added
+ * with the given group and id. You can use the group to control ordering of
+ * the items in relation to other items in the menu. Normally this function
+ * will automatically remove any existing items in the menu in the same
+ * group and place a divider above and below the added items; this behavior
+ * can be modified with the <var>flags</var> parameter. For each of the
+ * generated items {@link MenuItem#setIntent} is called to associate the
+ * appropriate Intent with the item; this means the activity will
+ * automatically be started for you without having to do anything else.
+ *
+ * @param groupId The group identifier that the items should be part of.
+ * This can also be used to define groups of items for batch state
+ * changes. Normally use {@link #NONE} if the items should not be in
+ * a group.
+ * @param itemId Unique item ID. Use {@link #NONE} if you do not need a
+ * unique ID.
+ * @param order The order for the items. Use {@link #NONE} if you do not
+ * care about the order. See {@link MenuItem#getOrder()}.
+ * @param caller The current activity component name as defined by
+ * queryIntentActivityOptions().
+ * @param specifics Specific items to place first as defined by
+ * queryIntentActivityOptions().
+ * @param intent Intent describing the kinds of items to populate in the
+ * list as defined by queryIntentActivityOptions().
+ * @param flags Additional options controlling how the items are added.
+ * @param outSpecificItems Optional array in which to place the menu items
+ * that were generated for each of the <var>specifics</var> that were
+ * requested. Entries may be null if no activity was found for that
+ * specific action.
+ * @return The number of menu items that were added.
+ *
+ * @see #FLAG_APPEND_TO_GROUP
+ * @see MenuItem#setIntent
+ * @see android.content.pm.PackageManager#queryIntentActivityOptions
+ */
+ public int addIntentOptions(int groupId, int itemId, int order,
+ ComponentName caller, Intent[] specifics,
+ Intent intent, int flags, MenuItem[] outSpecificItems);
+
+ /**
+ * Remove the item with the given identifier.
+ *
+ * @param id The item to be removed. If there is no item with this
+ * identifier, nothing happens.
+ */
+ public void removeItem(int id);
+
+ /**
+ * Remove all items in the given group.
+ *
+ * @param groupId The group to be removed. If there are no items in this
+ * group, nothing happens.
+ */
+ public void removeGroup(int groupId);
+
+ /**
+ * Remove all existing items from the menu, leaving it empty as if it had
+ * just been created.
+ */
+ public void clear();
+
+ /**
+ * Control whether a particular group of items can show a check mark. This
+ * is similar to calling {@link MenuItem#setCheckable} on all of the menu items
+ * with the given group identifier, but in addition you can control whether
+ * this group contains a mutually-exclusive set items. This should be called
+ * after the items of the group have been added to the menu.
+ *
+ * @param group The group of items to operate on.
+ * @param checkable Set to true to allow a check mark, false to
+ * disallow. The default is false.
+ * @param exclusive If set to true, only one item in this group can be
+ * checked at a time; checking an item will automatically
+ * uncheck all others in the group. If set to false, each
+ * item can be checked independently of the others.
+ *
+ * @see MenuItem#setCheckable
+ * @see MenuItem#setChecked
+ */
+ public void setGroupCheckable(int group, boolean checkable, boolean exclusive);
+
+ /**
+ * Show or hide all menu items that are in the given group.
+ *
+ * @param group The group of items to operate on.
+ * @param visible If true the items are visible, else they are hidden.
+ *
+ * @see MenuItem#setVisible
+ */
+ public void setGroupVisible(int group, boolean visible);
+
+ /**
+ * Enable or disable all menu items that are in the given group.
+ *
+ * @param group The group of items to operate on.
+ * @param enabled If true the items will be enabled, else they will be disabled.
+ *
+ * @see MenuItem#setEnabled
+ */
+ public void setGroupEnabled(int group, boolean enabled);
+
+ /**
+ * Return whether the menu currently has item items that are visible.
+ *
+ * @return True if there is one or more item visible,
+ * else false.
+ */
+ public boolean hasVisibleItems();
+
+ /**
+ * Return the menu item with a particular identifier.
+ *
+ * @param id The identifier to find.
+ *
+ * @return The menu item object, or null if there is no item with
+ * this identifier.
+ */
+ public MenuItem findItem(int id);
+
+ /**
+ * Get the number of items in the menu. Note that this will change any
+ * times items are added or removed from the menu.
+ *
+ * @return The item count.
+ */
+ public int size();
+
+ /**
+ * Gets the menu item at the given index.
+ *
+ * @param index The index of the menu item to return.
+ * @return The menu item.
+ * @exception IndexOutOfBoundsException
+ * when {@code index < 0 || >= size()}
+ */
+ public MenuItem getItem(int index);
+
+ /**
+ * Closes the menu, if open.
+ */
+ public void close();
+
+ /**
+ * Execute the menu item action associated with the given shortcut
+ * character.
+ *
+ * @param keyCode The keycode of the shortcut key.
+ * @param event Key event message.
+ * @param flags Additional option flags or 0.
+ *
+ * @return If the given shortcut exists and is shown, returns
+ * true; else returns false.
+ *
+ * @see #FLAG_PERFORM_NO_CLOSE
+ */
+ public boolean performShortcut(int keyCode, KeyEvent event, int flags);
+
+ /**
+ * Is a keypress one of the defined shortcut keys for this window.
+ * @param keyCode the key code from {@link KeyEvent} to check.
+ * @param event the {@link KeyEvent} to use to help check.
+ */
+ boolean isShortcutKey(int keyCode, KeyEvent event);
+
+ /**
+ * Execute the menu item action associated with the given menu identifier.
+ *
+ * @param id Identifier associated with the menu item.
+ * @param flags Additional option flags or 0.
+ *
+ * @return If the given identifier exists and is shown, returns
+ * true; else returns false.
+ *
+ * @see #FLAG_PERFORM_NO_CLOSE
+ */
+ public boolean performIdentifierAction(int id, int flags);
+
+
+ /**
+ * Control whether the menu should be running in qwerty mode (alphabetic
+ * shortcuts) or 12-key mode (numeric shortcuts).
+ *
+ * @param isQwerty If true the menu will use alphabetic shortcuts; else it
+ * will use numeric shortcuts.
+ */
+ public void setQwertyMode(boolean isQwerty);
+}
+
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java b/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java
new file mode 100644
index 000000000..969459749
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ * 2011 Jake Wharton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.util.Xml;
+import android.view.InflateException;
+import android.view.View;
+
+import com.actionbarsherlock.R;
+import com.actionbarsherlock.internal.view.menu.MenuItemImpl;
+
+/**
+ * This class is used to instantiate menu XML files into Menu objects.
+ * <p>
+ * For performance reasons, menu inflation relies heavily on pre-processing of
+ * XML files that is done at build time. Therefore, it is not currently possible
+ * to use MenuInflater with an XmlPullParser over a plain XML file at runtime;
+ * it only works with an XmlPullParser returned from a compiled resource (R.
+ * <em>something</em> file.)
+ */
+public class MenuInflater {
+ private static final String LOG_TAG = "MenuInflater";
+
+ /** Menu tag name in XML. */
+ private static final String XML_MENU = "menu";
+
+ /** Group tag name in XML. */
+ private static final String XML_GROUP = "group";
+
+ /** Item tag name in XML. */
+ private static final String XML_ITEM = "item";
+
+ private static final int NO_ID = 0;
+
+ private static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class};
+
+ private static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE;
+
+ private final Object[] mActionViewConstructorArguments;
+
+ private final Object[] mActionProviderConstructorArguments;
+
+ private Context mContext;
+
+ /**
+ * Constructs a menu inflater.
+ *
+ * @see Activity#getMenuInflater()
+ */
+ public MenuInflater(Context context) {
+ mContext = context;
+ mActionViewConstructorArguments = new Object[] {context};
+ mActionProviderConstructorArguments = mActionViewConstructorArguments;
+ }
+
+ /**
+ * Inflate a menu hierarchy from the specified XML resource. Throws
+ * {@link InflateException} if there is an error.
+ *
+ * @param menuRes Resource ID for an XML layout resource to load (e.g.,
+ * <code>R.menu.main_activity</code>)
+ * @param menu The Menu to inflate into. The items and submenus will be
+ * added to this Menu.
+ */
+ public void inflate(int menuRes, Menu menu) {
+ XmlResourceParser parser = null;
+ try {
+ parser = mContext.getResources().getLayout(menuRes);
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ parseMenu(parser, attrs, menu);
+ } catch (XmlPullParserException e) {
+ throw new InflateException("Error inflating menu XML", e);
+ } catch (IOException e) {
+ throw new InflateException("Error inflating menu XML", e);
+ } finally {
+ if (parser != null) parser.close();
+ }
+ }
+
+ /**
+ * Called internally to fill the given menu. If a sub menu is seen, it will
+ * call this recursively.
+ */
+ private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu)
+ throws XmlPullParserException, IOException {
+ MenuState menuState = new MenuState(menu);
+
+ int eventType = parser.getEventType();
+ String tagName;
+ boolean lookingForEndOfUnknownTag = false;
+ String unknownTagName = null;
+
+ // This loop will skip to the menu start tag
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ tagName = parser.getName();
+ if (tagName.equals(XML_MENU)) {
+ // Go to next tag
+ eventType = parser.next();
+ break;
+ }
+
+ throw new RuntimeException("Expecting menu, got " + tagName);
+ }
+ eventType = parser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ boolean reachedEndOfMenu = false;
+ while (!reachedEndOfMenu) {
+ switch (eventType) {
+ case XmlPullParser.START_TAG:
+ if (lookingForEndOfUnknownTag) {
+ break;
+ }
+
+ tagName = parser.getName();
+ if (tagName.equals(XML_GROUP)) {
+ menuState.readGroup(attrs);
+ } else if (tagName.equals(XML_ITEM)) {
+ menuState.readItem(attrs);
+ } else if (tagName.equals(XML_MENU)) {
+ // A menu start tag denotes a submenu for an item
+ SubMenu subMenu = menuState.addSubMenuItem();
+
+ // Parse the submenu into returned SubMenu
+ parseMenu(parser, attrs, subMenu);
+ } else {
+ lookingForEndOfUnknownTag = true;
+ unknownTagName = tagName;
+ }
+ break;
+
+ case XmlPullParser.END_TAG:
+ tagName = parser.getName();
+ if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) {
+ lookingForEndOfUnknownTag = false;
+ unknownTagName = null;
+ } else if (tagName.equals(XML_GROUP)) {
+ menuState.resetGroup();
+ } else if (tagName.equals(XML_ITEM)) {
+ // Add the item if it hasn't been added (if the item was
+ // a submenu, it would have been added already)
+ if (!menuState.hasAddedItem()) {
+ if (menuState.itemActionProvider != null &&
+ menuState.itemActionProvider.hasSubMenu()) {
+ menuState.addSubMenuItem();
+ } else {
+ menuState.addItem();
+ }
+ }
+ } else if (tagName.equals(XML_MENU)) {
+ reachedEndOfMenu = true;
+ }
+ break;
+
+ case XmlPullParser.END_DOCUMENT:
+ throw new RuntimeException("Unexpected end of document");
+ }
+
+ eventType = parser.next();
+ }
+ }
+
+ private static class InflatedOnMenuItemClickListener
+ implements MenuItem.OnMenuItemClickListener {
+ private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class };
+
+ private Context mContext;
+ private Method mMethod;
+
+ public InflatedOnMenuItemClickListener(Context context, String methodName) {
+ mContext = context;
+ Class<?> c = context.getClass();
+ try {
+ mMethod = c.getMethod(methodName, PARAM_TYPES);
+ } catch (Exception e) {
+ InflateException ex = new InflateException(
+ "Couldn't resolve menu item onClick handler " + methodName +
+ " in class " + c.getName());
+ ex.initCause(e);
+ throw ex;
+ }
+ }
+
+ public boolean onMenuItemClick(MenuItem item) {
+ try {
+ if (mMethod.getReturnType() == Boolean.TYPE) {
+ return (Boolean) mMethod.invoke(mContext, item);
+ } else {
+ mMethod.invoke(mContext, item);
+ return true;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * State for the current menu.
+ * <p>
+ * Groups can not be nested unless there is another menu (which will have
+ * its state class).
+ */
+ private class MenuState {
+ private Menu menu;
+
+ /*
+ * Group state is set on items as they are added, allowing an item to
+ * override its group state. (As opposed to set on items at the group end tag.)
+ */
+ private int groupId;
+ private int groupCategory;
+ private int groupOrder;
+ private int groupCheckable;
+ private boolean groupVisible;
+ private boolean groupEnabled;
+
+ private boolean itemAdded;
+ private int itemId;
+ private int itemCategoryOrder;
+ private CharSequence itemTitle;
+ private CharSequence itemTitleCondensed;
+ private int itemIconResId;
+ private char itemAlphabeticShortcut;
+ private char itemNumericShortcut;
+ /**
+ * Sync to attrs.xml enum:
+ * - 0: none
+ * - 1: all
+ * - 2: exclusive
+ */
+ private int itemCheckable;
+ private boolean itemChecked;
+ private boolean itemVisible;
+ private boolean itemEnabled;
+
+ /**
+ * Sync to attrs.xml enum, values in MenuItem:
+ * - 0: never
+ * - 1: ifRoom
+ * - 2: always
+ * - -1: Safe sentinel for "no value".
+ */
+ private int itemShowAsAction;
+
+ private int itemActionViewLayout;
+ private String itemActionViewClassName;
+ private String itemActionProviderClassName;
+
+ private String itemListenerMethodName;
+
+ private ActionProvider itemActionProvider;
+
+ private static final int defaultGroupId = NO_ID;
+ private static final int defaultItemId = NO_ID;
+ private static final int defaultItemCategory = 0;
+ private static final int defaultItemOrder = 0;
+ private static final int defaultItemCheckable = 0;
+ private static final boolean defaultItemChecked = false;
+ private static final boolean defaultItemVisible = true;
+ private static final boolean defaultItemEnabled = true;
+
+ public MenuState(final Menu menu) {
+ this.menu = menu;
+
+ resetGroup();
+ }
+
+ public void resetGroup() {
+ groupId = defaultGroupId;
+ groupCategory = defaultItemCategory;
+ groupOrder = defaultItemOrder;
+ groupCheckable = defaultItemCheckable;
+ groupVisible = defaultItemVisible;
+ groupEnabled = defaultItemEnabled;
+ }
+
+ /**
+ * Called when the parser is pointing to a group tag.
+ */
+ public void readGroup(AttributeSet attrs) {
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ R.styleable.SherlockMenuGroup);
+
+ groupId = a.getResourceId(R.styleable.SherlockMenuGroup_android_id, defaultGroupId);
+ groupCategory = a.getInt(R.styleable.SherlockMenuGroup_android_menuCategory, defaultItemCategory);
+ groupOrder = a.getInt(R.styleable.SherlockMenuGroup_android_orderInCategory, defaultItemOrder);
+ groupCheckable = a.getInt(R.styleable.SherlockMenuGroup_android_checkableBehavior, defaultItemCheckable);
+ groupVisible = a.getBoolean(R.styleable.SherlockMenuGroup_android_visible, defaultItemVisible);
+ groupEnabled = a.getBoolean(R.styleable.SherlockMenuGroup_android_enabled, defaultItemEnabled);
+
+ a.recycle();
+ }
+
+ /**
+ * Called when the parser is pointing to an item tag.
+ */
+ public void readItem(AttributeSet attrs) {
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ R.styleable.SherlockMenuItem);
+
+ // Inherit attributes from the group as default value
+ itemId = a.getResourceId(R.styleable.SherlockMenuItem_android_id, defaultItemId);
+ final int category = a.getInt(R.styleable.SherlockMenuItem_android_menuCategory, groupCategory);
+ final int order = a.getInt(R.styleable.SherlockMenuItem_android_orderInCategory, groupOrder);
+ itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK);
+ itemTitle = a.getText(R.styleable.SherlockMenuItem_android_title);
+ itemTitleCondensed = a.getText(R.styleable.SherlockMenuItem_android_titleCondensed);
+ itemIconResId = a.getResourceId(R.styleable.SherlockMenuItem_android_icon, 0);
+ itemAlphabeticShortcut =
+ getShortcut(a.getString(R.styleable.SherlockMenuItem_android_alphabeticShortcut));
+ itemNumericShortcut =
+ getShortcut(a.getString(R.styleable.SherlockMenuItem_android_numericShortcut));
+ if (a.hasValue(R.styleable.SherlockMenuItem_android_checkable)) {
+ // Item has attribute checkable, use it
+ itemCheckable = a.getBoolean(R.styleable.SherlockMenuItem_android_checkable, false) ? 1 : 0;
+ } else {
+ // Item does not have attribute, use the group's (group can have one more state
+ // for checkable that represents the exclusive checkable)
+ itemCheckable = groupCheckable;
+ }
+
+ itemChecked = a.getBoolean(R.styleable.SherlockMenuItem_android_checked, defaultItemChecked);
+ itemVisible = a.getBoolean(R.styleable.SherlockMenuItem_android_visible, groupVisible);
+ itemEnabled = a.getBoolean(R.styleable.SherlockMenuItem_android_enabled, groupEnabled);
+
+ TypedValue value = new TypedValue();
+ a.getValue(R.styleable.SherlockMenuItem_android_showAsAction, value);
+ itemShowAsAction = value.type == TypedValue.TYPE_INT_HEX ? value.data : -1;
+
+ itemListenerMethodName = a.getString(R.styleable.SherlockMenuItem_android_onClick);
+ itemActionViewLayout = a.getResourceId(R.styleable.SherlockMenuItem_android_actionLayout, 0);
+ itemActionViewClassName = a.getString(R.styleable.SherlockMenuItem_android_actionViewClass);
+ itemActionProviderClassName = a.getString(R.styleable.SherlockMenuItem_android_actionProviderClass);
+
+ final boolean hasActionProvider = itemActionProviderClassName != null;
+ if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) {
+ itemActionProvider = newInstance(itemActionProviderClassName,
+ ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE,
+ mActionProviderConstructorArguments);
+ } else {
+ if (hasActionProvider) {
+ Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'."
+ + " Action view already specified.");
+ }
+ itemActionProvider = null;
+ }
+
+ a.recycle();
+
+ itemAdded = false;
+ }
+
+ private char getShortcut(String shortcutString) {
+ if (shortcutString == null) {
+ return 0;
+ } else {
+ return shortcutString.charAt(0);
+ }
+ }
+
+ private void setItem(MenuItem item) {
+ item.setChecked(itemChecked)
+ .setVisible(itemVisible)
+ .setEnabled(itemEnabled)
+ .setCheckable(itemCheckable >= 1)
+ .setTitleCondensed(itemTitleCondensed)
+ .setIcon(itemIconResId)
+ .setAlphabeticShortcut(itemAlphabeticShortcut)
+ .setNumericShortcut(itemNumericShortcut);
+
+ if (itemShowAsAction >= 0) {
+ item.setShowAsAction(itemShowAsAction);
+ }
+
+ if (itemListenerMethodName != null) {
+ if (mContext.isRestricted()) {
+ throw new IllegalStateException("The android:onClick attribute cannot "
+ + "be used within a restricted context");
+ }
+ item.setOnMenuItemClickListener(
+ new InflatedOnMenuItemClickListener(mContext, itemListenerMethodName));
+ }
+
+ if (itemCheckable >= 2) {
+ if (item instanceof MenuItemImpl) {
+ MenuItemImpl impl = (MenuItemImpl) item;
+ impl.setExclusiveCheckable(true);
+ } else {
+ menu.setGroupCheckable(groupId, true, true);
+ }
+ }
+
+ boolean actionViewSpecified = false;
+ if (itemActionViewClassName != null) {
+ View actionView = (View) newInstance(itemActionViewClassName,
+ ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments);
+ item.setActionView(actionView);
+ actionViewSpecified = true;
+ }
+ if (itemActionViewLayout > 0) {
+ if (!actionViewSpecified) {
+ item.setActionView(itemActionViewLayout);
+ actionViewSpecified = true;
+ } else {
+ Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'."
+ + " Action view already specified.");
+ }
+ }
+ if (itemActionProvider != null) {
+ item.setActionProvider(itemActionProvider);
+ }
+ }
+
+ public void addItem() {
+ itemAdded = true;
+ setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle));
+ }
+
+ public SubMenu addSubMenuItem() {
+ itemAdded = true;
+ SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle);
+ setItem(subMenu.getItem());
+ return subMenu;
+ }
+
+ public boolean hasAddedItem() {
+ return itemAdded;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T newInstance(String className, Class<?>[] constructorSignature,
+ Object[] arguments) {
+ try {
+ Class<?> clazz = mContext.getClassLoader().loadClass(className);
+ Constructor<?> constructor = clazz.getConstructor(constructorSignature);
+ return (T) constructor.newInstance(arguments);
+ } catch (Exception e) {
+ Log.w(LOG_TAG, "Cannot instantiate class: " + className, e);
+ }
+ return null;
+ }
+ }
+}
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java b/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java
new file mode 100644
index 000000000..7fc3aa430
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java
@@ -0,0 +1,598 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View;
+
+/**
+ * Interface for direct access to a previously created menu item.
+ * <p>
+ * An Item is returned by calling one of the {@link android.view.Menu#add}
+ * methods.
+ * <p>
+ * For a feature set of specific menu types, see {@link Menu}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
+ */
+public interface MenuItem {
+ /*
+ * These should be kept in sync with attrs.xml enum constants for showAsAction
+ */
+ /** Never show this item as a button in an Action Bar. */
+ public static final int SHOW_AS_ACTION_NEVER = android.view.MenuItem.SHOW_AS_ACTION_NEVER;
+ /** Show this item as a button in an Action Bar if the system decides there is room for it. */
+ public static final int SHOW_AS_ACTION_IF_ROOM = android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM;
+ /**
+ * Always show this item as a button in an Action Bar.
+ * Use sparingly! If too many items are set to always show in the Action Bar it can
+ * crowd the Action Bar and degrade the user experience on devices with smaller screens.
+ * A good rule of thumb is to have no more than 2 items set to always show at a time.
+ */
+ public static final int SHOW_AS_ACTION_ALWAYS = android.view.MenuItem.SHOW_AS_ACTION_ALWAYS;
+
+ /**
+ * When this item is in the action bar, always show it with a text label even if
+ * it also has an icon specified.
+ */
+ public static final int SHOW_AS_ACTION_WITH_TEXT = android.view.MenuItem.SHOW_AS_ACTION_WITH_TEXT;
+
+ /**
+ * This item's action view collapses to a normal menu item.
+ * When expanded, the action view temporarily takes over
+ * a larger segment of its container.
+ */
+ public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = android.view.MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW;
+
+ /**
+ * Interface definition for a callback to be invoked when a menu item is
+ * clicked.
+ *
+ * @see Activity#onContextItemSelected(MenuItem)
+ * @see Activity#onOptionsItemSelected(MenuItem)
+ */
+ public interface OnMenuItemClickListener {
+ /**
+ * Called when a menu item has been invoked. This is the first code
+ * that is executed; if it returns true, no other callbacks will be
+ * executed.
+ *
+ * @param item The menu item that was invoked.
+ *
+ * @return Return true to consume this click and prevent others from
+ * executing.
+ */
+ public boolean onMenuItemClick(MenuItem item);
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when a menu item
+ * marked with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is
+ * expanded or collapsed.
+ *
+ * @see MenuItem#expandActionView()
+ * @see MenuItem#collapseActionView()
+ * @see MenuItem#setShowAsActionFlags(int)
+ */
+ public interface OnActionExpandListener {
+ /**
+ * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
+ * is expanded.
+ * @param item Item that was expanded
+ * @return true if the item should expand, false if expansion should be suppressed.
+ */
+ public boolean onMenuItemActionExpand(MenuItem item);
+
+ /**
+ * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
+ * is collapsed.
+ * @param item Item that was collapsed
+ * @return true if the item should collapse, false if collapsing should be suppressed.
+ */
+ public boolean onMenuItemActionCollapse(MenuItem item);
+ }
+
+ /**
+ * Return the identifier for this menu item. The identifier can not
+ * be changed after the menu is created.
+ *
+ * @return The menu item's identifier.
+ */
+ public int getItemId();
+
+ /**
+ * Return the group identifier that this menu item is part of. The group
+ * identifier can not be changed after the menu is created.
+ *
+ * @return The menu item's group identifier.
+ */
+ public int getGroupId();
+
+ /**
+ * Return the category and order within the category of this item. This
+ * item will be shown before all items (within its category) that have
+ * order greater than this value.
+ * <p>
+ * An order integer contains the item's category (the upper bits of the
+ * integer; set by or/add the category with the order within the
+ * category) and the ordering of the item within that category (the
+ * lower bits). Example categories are {@link Menu#CATEGORY_SYSTEM},
+ * {@link Menu#CATEGORY_SECONDARY}, {@link Menu#CATEGORY_ALTERNATIVE},
+ * {@link Menu#CATEGORY_CONTAINER}. See {@link Menu} for a full list.
+ *
+ * @return The order of this item.
+ */
+ public int getOrder();
+
+ /**
+ * Change the title associated with this item.
+ *
+ * @param title The new text to be displayed.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setTitle(CharSequence title);
+
+ /**
+ * Change the title associated with this item.
+ * <p>
+ * Some menu types do not sufficient space to show the full title, and
+ * instead a condensed title is preferred. See {@link Menu} for more
+ * information.
+ *
+ * @param title The resource id of the new text to be displayed.
+ * @return This Item so additional setters can be called.
+ * @see #setTitleCondensed(CharSequence)
+ */
+
+ public MenuItem setTitle(int title);
+
+ /**
+ * Retrieve the current title of the item.
+ *
+ * @return The title.
+ */
+ public CharSequence getTitle();
+
+ /**
+ * Change the condensed title associated with this item. The condensed
+ * title is used in situations where the normal title may be too long to
+ * be displayed.
+ *
+ * @param title The new text to be displayed as the condensed title.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setTitleCondensed(CharSequence title);
+
+ /**
+ * Retrieve the current condensed title of the item. If a condensed
+ * title was never set, it will return the normal title.
+ *
+ * @return The condensed title, if it exists.
+ * Otherwise the normal title.
+ */
+ public CharSequence getTitleCondensed();
+
+ /**
+ * Change the icon associated with this item. This icon will not always be
+ * shown, so the title should be sufficient in describing this item. See
+ * {@link Menu} for the menu types that support icons.
+ *
+ * @param icon The new icon (as a Drawable) to be displayed.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setIcon(Drawable icon);
+
+ /**
+ * Change the icon associated with this item. This icon will not always be
+ * shown, so the title should be sufficient in describing this item. See
+ * {@link Menu} for the menu types that support icons.
+ * <p>
+ * This method will set the resource ID of the icon which will be used to
+ * lazily get the Drawable when this item is being shown.
+ *
+ * @param iconRes The new icon (as a resource ID) to be displayed.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setIcon(int iconRes);
+
+ /**
+ * Returns the icon for this item as a Drawable (getting it from resources if it hasn't been
+ * loaded before).
+ *
+ * @return The icon as a Drawable.
+ */
+ public Drawable getIcon();
+
+ /**
+ * Change the Intent associated with this item. By default there is no
+ * Intent associated with a menu item. If you set one, and nothing
+ * else handles the item, then the default behavior will be to call
+ * {@link android.content.Context#startActivity} with the given Intent.
+ *
+ * <p>Note that setIntent() can not be used with the versions of
+ * {@link Menu#add} that take a Runnable, because {@link Runnable#run}
+ * does not return a value so there is no way to tell if it handled the
+ * item. In this case it is assumed that the Runnable always handles
+ * the item, and the intent will never be started.
+ *
+ * @see #getIntent
+ * @param intent The Intent to associated with the item. This Intent
+ * object is <em>not</em> copied, so be careful not to
+ * modify it later.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setIntent(Intent intent);
+
+ /**
+ * Return the Intent associated with this item. This returns a
+ * reference to the Intent which you can change as desired to modify
+ * what the Item is holding.
+ *
+ * @see #setIntent
+ * @return Returns the last value supplied to {@link #setIntent}, or
+ * null.
+ */
+ public Intent getIntent();
+
+ /**
+ * Change both the numeric and alphabetic shortcut associated with this
+ * item. Note that the shortcut will be triggered when the key that
+ * generates the given character is pressed alone or along with with the alt
+ * key. Also note that case is not significant and that alphabetic shortcut
+ * characters will be displayed in lower case.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a numeric (e.g., 12-key) keyboard.
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setShortcut(char numericChar, char alphaChar);
+
+ /**
+ * Change the numeric shortcut associated with this item.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a 12-key (numeric) keyboard.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setNumericShortcut(char numericChar);
+
+ /**
+ * Return the char for this menu item's numeric (12-key) shortcut.
+ *
+ * @return Numeric character to use as a shortcut.
+ */
+ public char getNumericShortcut();
+
+ /**
+ * Change the alphabetic shortcut associated with this item. The shortcut
+ * will be triggered when the key that generates the given character is
+ * pressed alone or along with with the alt key. Case is not significant and
+ * shortcut characters will be displayed in lower case. Note that menu items
+ * with the characters '\b' or '\n' as shortcuts will get triggered by the
+ * Delete key or Carriage Return key, respectively.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setAlphabeticShortcut(char alphaChar);
+
+ /**
+ * Return the char for this menu item's alphabetic shortcut.
+ *
+ * @return Alphabetic character to use as a shortcut.
+ */
+ public char getAlphabeticShortcut();
+
+ /**
+ * Control whether this item can display a check mark. Setting this does
+ * not actually display a check mark (see {@link #setChecked} for that);
+ * rather, it ensures there is room in the item in which to display a
+ * check mark.
+ * <p>
+ * See {@link Menu} for the menu types that support check marks.
+ *
+ * @param checkable Set to true to allow a check mark, false to
+ * disallow. The default is false.
+ * @see #setChecked
+ * @see #isCheckable
+ * @see Menu#setGroupCheckable
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setCheckable(boolean checkable);
+
+ /**
+ * Return whether the item can currently display a check mark.
+ *
+ * @return If a check mark can be displayed, returns true.
+ *
+ * @see #setCheckable
+ */
+ public boolean isCheckable();
+
+ /**
+ * Control whether this item is shown with a check mark. Note that you
+ * must first have enabled checking with {@link #setCheckable} or else
+ * the check mark will not appear. If this item is a member of a group that contains
+ * mutually-exclusive items (set via {@link Menu#setGroupCheckable(int, boolean, boolean)},
+ * the other items in the group will be unchecked.
+ * <p>
+ * See {@link Menu} for the menu types that support check marks.
+ *
+ * @see #setCheckable
+ * @see #isChecked
+ * @see Menu#setGroupCheckable
+ * @param checked Set to true to display a check mark, false to hide
+ * it. The default value is false.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setChecked(boolean checked);
+
+ /**
+ * Return whether the item is currently displaying a check mark.
+ *
+ * @return If a check mark is displayed, returns true.
+ *
+ * @see #setChecked
+ */
+ public boolean isChecked();
+
+ /**
+ * Sets the visibility of the menu item. Even if a menu item is not visible,
+ * it may still be invoked via its shortcut (to completely disable an item,
+ * set it to invisible and {@link #setEnabled(boolean) disabled}).
+ *
+ * @param visible If true then the item will be visible; if false it is
+ * hidden.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setVisible(boolean visible);
+
+ /**
+ * Return the visibility of the menu item.
+ *
+ * @return If true the item is visible; else it is hidden.
+ */
+ public boolean isVisible();
+
+ /**
+ * Sets whether the menu item is enabled. Disabling a menu item will not
+ * allow it to be invoked via its shortcut. The menu item will still be
+ * visible.
+ *
+ * @param enabled If true then the item will be invokable; if false it is
+ * won't be invokable.
+ * @return This Item so additional setters can be called.
+ */
+ public MenuItem setEnabled(boolean enabled);
+
+ /**
+ * Return the enabled state of the menu item.
+ *
+ * @return If true the item is enabled and hence invokable; else it is not.
+ */
+ public boolean isEnabled();
+
+ /**
+ * Check whether this item has an associated sub-menu. I.e. it is a
+ * sub-menu of another menu.
+ *
+ * @return If true this item has a menu; else it is a
+ * normal item.
+ */
+ public boolean hasSubMenu();
+
+ /**
+ * Get the sub-menu to be invoked when this item is selected, if it has
+ * one. See {@link #hasSubMenu()}.
+ *
+ * @return The associated menu if there is one, else null
+ */
+ public SubMenu getSubMenu();
+
+ /**
+ * Set a custom listener for invocation of this menu item. In most
+ * situations, it is more efficient and easier to use
+ * {@link Activity#onOptionsItemSelected(MenuItem)} or
+ * {@link Activity#onContextItemSelected(MenuItem)}.
+ *
+ * @param menuItemClickListener The object to receive invokations.
+ * @return This Item so additional setters can be called.
+ * @see Activity#onOptionsItemSelected(MenuItem)
+ * @see Activity#onContextItemSelected(MenuItem)
+ */
+ public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener menuItemClickListener);
+
+ /**
+ * Gets the extra information linked to this menu item. This extra
+ * information is set by the View that added this menu item to the
+ * menu.
+ *
+ * @see OnCreateContextMenuListener
+ * @return The extra information linked to the View that added this
+ * menu item to the menu. This can be null.
+ */
+ public ContextMenuInfo getMenuInfo();
+
+ /**
+ * Sets how this item should display in the presence of an Action Bar.
+ * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS},
+ * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should
+ * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}.
+ * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action,
+ * it should be shown with a text label.
+ *
+ * @param actionEnum How the item should display. One of
+ * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or
+ * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default.
+ *
+ * @see android.app.ActionBar
+ * @see #setActionView(View)
+ */
+ public void setShowAsAction(int actionEnum);
+
+ /**
+ * Sets how this item should display in the presence of an Action Bar.
+ * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS},
+ * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should
+ * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}.
+ * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action,
+ * it should be shown with a text label.
+ *
+ * <p>Note: This method differs from {@link #setShowAsAction(int)} only in that it
+ * returns the current MenuItem instance for call chaining.
+ *
+ * @param actionEnum How the item should display. One of
+ * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or
+ * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default.
+ *
+ * @see android.app.ActionBar
+ * @see #setActionView(View)
+ * @return This MenuItem instance for call chaining.
+ */
+ public MenuItem setShowAsActionFlags(int actionEnum);
+
+ /**
+ * Set an action view for this menu item. An action view will be displayed in place
+ * of an automatically generated menu item element in the UI when this item is shown
+ * as an action within a parent.
+ * <p>
+ * <strong>Note:</strong> Setting an action view overrides the action provider
+ * set via {@link #setActionProvider(ActionProvider)}.
+ * </p>
+ *
+ * @param view View to use for presenting this item to the user.
+ * @return This Item so additional setters can be called.
+ *
+ * @see #setShowAsAction(int)
+ */
+ public MenuItem setActionView(View view);
+
+ /**
+ * Set an action view for this menu item. An action view will be displayed in place
+ * of an automatically generated menu item element in the UI when this item is shown
+ * as an action within a parent.
+ * <p>
+ * <strong>Note:</strong> Setting an action view overrides the action provider
+ * set via {@link #setActionProvider(ActionProvider)}.
+ * </p>
+ *
+ * @param resId Layout resource to use for presenting this item to the user.
+ * @return This Item so additional setters can be called.
+ *
+ * @see #setShowAsAction(int)
+ */
+ public MenuItem setActionView(int resId);
+
+ /**
+ * Returns the currently set action view for this menu item.
+ *
+ * @return This item's action view
+ *
+ * @see #setActionView(View)
+ * @see #setShowAsAction(int)
+ */
+ public View getActionView();
+
+ /**
+ * Sets the {@link ActionProvider} responsible for creating an action view if
+ * the item is placed on the action bar. The provider also provides a default
+ * action invoked if the item is placed in the overflow menu.
+ * <p>
+ * <strong>Note:</strong> Setting an action provider overrides the action view
+ * set via {@link #setActionView(int)} or {@link #setActionView(View)}.
+ * </p>
+ *
+ * @param actionProvider The action provider.
+ * @return This Item so additional setters can be called.
+ *
+ * @see ActionProvider
+ */
+ public MenuItem setActionProvider(ActionProvider actionProvider);
+
+ /**
+ * Gets the {@link ActionProvider}.
+ *
+ * @return The action provider.
+ *
+ * @see ActionProvider
+ * @see #setActionProvider(ActionProvider)
+ */
+ public ActionProvider getActionProvider();
+
+ /**
+ * Expand the action view associated with this menu item.
+ * The menu item must have an action view set, as well as
+ * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
+ * If a listener has been set using {@link #setOnActionExpandListener(OnActionExpandListener)}
+ * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)}
+ * method invoked. The listener may return false from this method to prevent expanding
+ * the action view.
+ *
+ * @return true if the action view was expanded, false otherwise.
+ */
+ public boolean expandActionView();
+
+ /**
+ * Collapse the action view associated with this menu item.
+ * The menu item must have an action view set, as well as the showAsAction flag
+ * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a listener has been set using
+ * {@link #setOnActionExpandListener(OnActionExpandListener)} it will have its
+ * {@link OnActionExpandListener#onMenuItemActionCollapse(MenuItem)} method invoked.
+ * The listener may return false from this method to prevent collapsing the action view.
+ *
+ * @return true if the action view was collapsed, false otherwise.
+ */
+ public boolean collapseActionView();
+
+ /**
+ * Returns true if this menu item's action view has been expanded.
+ *
+ * @return true if the item's action view is expanded, false otherwise.
+ *
+ * @see #expandActionView()
+ * @see #collapseActionView()
+ * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
+ * @see OnActionExpandListener
+ */
+ public boolean isActionViewExpanded();
+
+ /**
+ * Set an {@link OnActionExpandListener} on this menu item to be notified when
+ * the associated action view is expanded or collapsed. The menu item must
+ * be configured to expand or collapse its action view using the flag
+ * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
+ *
+ * @param listener Listener that will respond to expand/collapse events
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setOnActionExpandListener(OnActionExpandListener listener);
+} \ No newline at end of file
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java b/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java
new file mode 100644
index 000000000..397fd1c2d
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+/**
+ * Subclass of {@link Menu} for sub menus.
+ * <p>
+ * Sub menus do not support item icons, or nested sub menus.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
+ */
+
+public interface SubMenu extends Menu {
+ /**
+ * Sets the submenu header's title to the title given in <var>titleRes</var>
+ * resource identifier.
+ *
+ * @param titleRes The string resource identifier used for the title.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setHeaderTitle(int titleRes);
+
+ /**
+ * Sets the submenu header's title to the title given in <var>title</var>.
+ *
+ * @param title The character sequence used for the title.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setHeaderTitle(CharSequence title);
+
+ /**
+ * Sets the submenu header's icon to the icon given in <var>iconRes</var>
+ * resource id.
+ *
+ * @param iconRes The resource identifier used for the icon.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setHeaderIcon(int iconRes);
+
+ /**
+ * Sets the submenu header's icon to the icon given in <var>icon</var>
+ * {@link Drawable}.
+ *
+ * @param icon The {@link Drawable} used for the icon.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setHeaderIcon(Drawable icon);
+
+ /**
+ * Sets the header of the submenu to the {@link View} given in
+ * <var>view</var>. This replaces the header title and icon (and those
+ * replace this).
+ *
+ * @param view The {@link View} used for the header.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setHeaderView(View view);
+
+ /**
+ * Clears the header of the submenu.
+ */
+ public void clearHeader();
+
+ /**
+ * Change the icon associated with this submenu's item in its parent menu.
+ *
+ * @see MenuItem#setIcon(int)
+ * @param iconRes The new icon (as a resource ID) to be displayed.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setIcon(int iconRes);
+
+ /**
+ * Change the icon associated with this submenu's item in its parent menu.
+ *
+ * @see MenuItem#setIcon(Drawable)
+ * @param icon The new icon (as a Drawable) to be displayed.
+ * @return This SubMenu so additional setters can be called.
+ */
+ public SubMenu setIcon(Drawable icon);
+
+ /**
+ * Gets the {@link MenuItem} that represents this submenu in the parent
+ * menu. Use this for setting additional item attributes.
+ *
+ * @return The {@link MenuItem} that launches the submenu when invoked.
+ */
+ public MenuItem getItem();
+}
diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/Window.java b/actionbarsherlock/src/com/actionbarsherlock/view/Window.java
new file mode 100644
index 000000000..a340a4291
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/view/Window.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2011 Jake Wharton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.actionbarsherlock.view;
+
+import android.content.Context;
+
+/**
+ * <p>Abstract base class for a top-level window look and behavior policy. An
+ * instance of this class should be used as the top-level view added to the
+ * window manager. It provides standard UI policies such as a background, title
+ * area, default key processing, etc.</p>
+ *
+ * <p>The only existing implementation of this abstract class is
+ * android.policy.PhoneWindow, which you should instantiate when needing a
+ * Window. Eventually that class will be refactored and a factory method added
+ * for creating Window instances without knowing about a particular
+ * implementation.</p>
+ */
+public abstract class Window extends android.view.Window {
+ public static final long FEATURE_ACTION_BAR = android.view.Window.FEATURE_ACTION_BAR;
+ public static final long FEATURE_ACTION_BAR_OVERLAY = android.view.Window.FEATURE_ACTION_BAR_OVERLAY;
+ public static final long FEATURE_ACTION_MODE_OVERLAY = android.view.Window.FEATURE_ACTION_MODE_OVERLAY;
+ public static final long FEATURE_NO_TITLE = android.view.Window.FEATURE_NO_TITLE;
+ public static final long FEATURE_PROGRESS = android.view.Window.FEATURE_PROGRESS;
+ public static final long FEATURE_INDETERMINATE_PROGRESS = android.view.Window.FEATURE_INDETERMINATE_PROGRESS;
+
+ /**
+ * Create a new instance for a context.
+ *
+ * @param context Context.
+ */
+ private Window(Context context) {
+ super(context);
+ }
+
+
+ public interface Callback {
+ /**
+ * Called when a panel's menu item has been selected by the user.
+ *
+ * @param featureId The panel that the menu is in.
+ * @param item The menu item that was selected.
+ *
+ * @return boolean Return true to finish processing of selection, or
+ * false to perform the normal menu handling (calling its
+ * Runnable or sending a Message to its target Handler).
+ */
+ public boolean onMenuItemSelected(int featureId, MenuItem item);
+ }
+}