diff options
author | Owen Lin <owenlin@google.com> | 2012-07-11 11:20:00 +0800 |
---|---|---|
committer | Owen Lin <owenlin@google.com> | 2012-07-17 17:43:36 +0800 |
commit | 44ef42f215d68ade8b63d18fede944c244a2a1dd (patch) | |
tree | 240871bd37e4fcb555095eb206b4dbc58a321ff4 /src/com/android/gallery3d/ui | |
parent | 624c2d4ccd9dd497e75797976a4bec4fd79d0f88 (diff) | |
download | android_packages_apps_Gallery2-44ef42f215d68ade8b63d18fede944c244a2a1dd.tar.gz android_packages_apps_Gallery2-44ef42f215d68ade8b63d18fede944c244a2a1dd.tar.bz2 android_packages_apps_Gallery2-44ef42f215d68ade8b63d18fede944c244a2a1dd.zip |
Make CustomMenu compatible with API level 10.
bug: 6802855
Change-Id: I230c91bd9744935a181881131dcd2275ed89d819
Diffstat (limited to 'src/com/android/gallery3d/ui')
-rw-r--r-- | src/com/android/gallery3d/ui/ActionModeHandler.java | 50 | ||||
-rw-r--r-- | src/com/android/gallery3d/ui/CustomMenu.java | 89 | ||||
-rw-r--r-- | src/com/android/gallery3d/ui/PopupList.java | 188 | ||||
-rw-r--r-- | src/com/android/gallery3d/ui/SelectionMenu.java | 61 |
4 files changed, 271 insertions, 117 deletions
diff --git a/src/com/android/gallery3d/ui/ActionModeHandler.java b/src/com/android/gallery3d/ui/ActionModeHandler.java index 190b2b8c6..80d2500d4 100644 --- a/src/com/android/gallery3d/ui/ActionModeHandler.java +++ b/src/com/android/gallery3d/ui/ActionModeHandler.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.nfc.NfcAdapter; -import android.os.Build; import android.os.Handler; import android.view.ActionMode; import android.view.LayoutInflater; @@ -31,7 +30,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; -import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.ShareActionProvider; import android.widget.ShareActionProvider.OnShareTargetSelectedListener; @@ -43,7 +41,6 @@ import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.DataManager; import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.Path; -import com.android.gallery3d.ui.CustomMenu.DropDownMenu; import com.android.gallery3d.ui.MenuExecutor.ProgressListener; import com.android.gallery3d.util.Future; import com.android.gallery3d.util.GalleryUtils; @@ -52,7 +49,8 @@ import com.android.gallery3d.util.ThreadPool.JobContext; import java.util.ArrayList; -public class ActionModeHandler implements ActionMode.Callback { +public class ActionModeHandler implements + ActionMode.Callback, PopupList.OnPopupItemClickListener { private static final String TAG = "ActionModeHandler"; private static final int SUPPORT_MULTIPLE_MASK = MediaObject.SUPPORT_DELETE | MediaObject.SUPPORT_ROTATE | MediaObject.SUPPORT_SHARE @@ -67,7 +65,7 @@ public class ActionModeHandler implements ActionMode.Callback { private final SelectionManager mSelectionManager; private final NfcAdapter mNfcAdapter; private Menu mMenu; - private DropDownMenu mSelectionMenu; + private SelectionMenu mSelectionMenu; private ActionModeListener mListener; private Future<?> mMenuTask; private final Handler mMainHandler; @@ -85,20 +83,13 @@ public class ActionModeHandler implements ActionMode.Callback { public ActionMode startActionMode() { Activity a = (Activity) mActivity; final ActionMode actionMode = a.startActionMode(this); - CustomMenu customMenu = new CustomMenu(a); View customView = LayoutInflater.from(a).inflate( R.layout.action_mode, null); actionMode.setCustomView(customView); - mSelectionMenu = customMenu.addDropDownMenu( - (Button) customView.findViewById(R.id.selection_menu), - R.menu.selection); + mSelectionMenu = new SelectionMenu(a, + (Button) customView.findViewById(R.id.selection_menu), this); updateSelectionMenu(); - customMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onActionItemClicked(actionMode, item); - } - }); + return actionMode; } @@ -137,14 +128,25 @@ public class ActionModeHandler implements ActionMode.Callback { R.plurals.delete_selection, mSelectionManager.getSelectedCount()); } mMenuExecutor.onMenuClicked(item, confirmMsg, listener); - if (action == R.id.action_select_all) { + } finally { + root.unlockRenderThread(); + } + return true; + } + + @Override + public boolean onPopupItemClick(int itemId) { + GLRoot root = mActivity.getGLRoot(); + root.lockRenderThread(); + try { + if (itemId == R.id.action_select_all) { updateSupportedOperation(); - updateSelectionMenu(); + mMenuExecutor.onMenuClicked(itemId, null, false, true); } + return true; } finally { root.unlockRenderThread(); } - return true; } private void updateSelectionMenu() { @@ -153,18 +155,10 @@ public class ActionModeHandler implements ActionMode.Callback { String format = mActivity.getResources().getQuantityString( R.plurals.number_of_items_selected, count); setTitle(String.format(format, count)); + // For clients who call SelectionManager.selectAll() directly, we need to ensure the // menu status is consistent with selection manager. - MenuItem item = mSelectionMenu.findItem(R.id.action_select_all); - if (item != null) { - if (mSelectionManager.inSelectAllMode()) { - item.setChecked(true); - item.setTitle(R.string.deselect_all); - } else { - item.setChecked(false); - item.setTitle(R.string.select_all); - } - } + mSelectionMenu.updateSelectAllMode(mSelectionManager.inSelectAllMode()); } public boolean onCreateActionMode(ActionMode mode, Menu menu) { diff --git a/src/com/android/gallery3d/ui/CustomMenu.java b/src/com/android/gallery3d/ui/CustomMenu.java deleted file mode 100644 index 15b3dc2c2..000000000 --- a/src/com/android/gallery3d/ui/CustomMenu.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.android.gallery3d.ui; - -import android.content.Context; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnMenuItemClickListener; - -import java.util.ArrayList; - -public class CustomMenu implements OnMenuItemClickListener { - @SuppressWarnings("unused") - private static final String TAG = "FilterMenu"; - - public static class DropDownMenu { - private Button mButton; - private PopupMenu mPopupMenu; - private Menu mMenu; - - public DropDownMenu(Context context, Button button, int menuId, - OnMenuItemClickListener listener) { - mButton = button; - mPopupMenu = new PopupMenu(context, mButton); - mMenu = mPopupMenu.getMenu(); - mPopupMenu.getMenuInflater().inflate(menuId, mMenu); - mPopupMenu.setOnMenuItemClickListener(listener); - mButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mPopupMenu.show(); - } - }); - } - - public MenuItem findItem(int id) { - return mMenu.findItem(id); - } - - public void setTitle(CharSequence title) { - mButton.setText(title); - } - } - - private Context mContext; - private ArrayList<DropDownMenu> mMenus; - private OnMenuItemClickListener mListener; - - public CustomMenu(Context context) { - mContext = context; - mMenus = new ArrayList<DropDownMenu>(); - } - - public DropDownMenu addDropDownMenu(Button button, int menuId) { - DropDownMenu menu = new DropDownMenu(mContext, button, menuId, this); - mMenus.add(menu); - return menu; - } - - public void setOnMenuItemClickListener(OnMenuItemClickListener listener) { - mListener = listener; - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - if (mListener != null) { - return mListener.onMenuItemClick(item); - } - return false; - } -} diff --git a/src/com/android/gallery3d/ui/PopupList.java b/src/com/android/gallery3d/ui/PopupList.java new file mode 100644 index 000000000..ee02029c7 --- /dev/null +++ b/src/com/android/gallery3d/ui/PopupList.java @@ -0,0 +1,188 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +package com.android.gallery3d.ui; + +import android.content.Context; +import android.graphics.Rect; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.BaseAdapter; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.TextView; + +import com.android.gallery3d.R; +import com.android.gallery3d.common.Utils; + +import java.util.ArrayList; + +public class PopupList { + + public static interface OnPopupItemClickListener { + public boolean onPopupItemClick(int itemId); + } + + public static class Item { + public final int id; + public String title; + + public Item(int id, String title) { + this.id = id; + this.title = title; + } + + public void setTitle(String title) { + this.title = title; + } + } + + private final Context mContext; + private final View mAnchorView; + private final ArrayList<Item> mItems = new ArrayList<Item>(); + private PopupWindow mPopupWindow; + private ListView mContentList; + private OnPopupItemClickListener mOnPopupItemClickListener; + private int mPopupOffsetX; + private int mPopupOffsetY; + private int mPopupWidth; + private int mPopupHeight; + + public PopupList(Context context, View anchorView) { + mContext = context; + mAnchorView = anchorView; + } + + public void setOnPopupItemClickListener(OnPopupItemClickListener listener) { + mOnPopupItemClickListener = listener; + } + + public void addItem(int id, String title) { + mItems.add(new Item(id, title)); + } + + private final PopupWindow.OnDismissListener mOnDismissListener = + new PopupWindow.OnDismissListener() { + @SuppressWarnings("deprecation") + @Override + public void onDismiss() { + if (mPopupWindow == null) return; + mPopupWindow = null; + ViewTreeObserver observer = mAnchorView.getViewTreeObserver(); + if (observer.isAlive()) { + // We used the deprecated function for backward compatibility + // The new "removeOnGlobalLayoutListener" is introduced in API level 16 + observer.removeGlobalOnLayoutListener(mOnGLobalLayoutListener); + } + } + }; + + private final OnItemClickListener mOnItemClickListener = + new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + Utils.debug("onItemClick: %s, %s", position, id); + if (mPopupWindow == null) return; + mPopupWindow.dismiss(); + if (mOnPopupItemClickListener != null) { + mOnPopupItemClickListener.onPopupItemClick((int) id); + } + } + }; + + private final OnGlobalLayoutListener mOnGLobalLayoutListener = + new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (mPopupWindow == null) return; + updatePopupLayoutParams(); + // Need to update the position of the popup window + mPopupWindow.update(mAnchorView, + mPopupOffsetX, mPopupOffsetY, mPopupWidth, mPopupHeight); + } + }; + + public void show() { + if (mPopupWindow != null) return; + mAnchorView.getViewTreeObserver() + .addOnGlobalLayoutListener(mOnGLobalLayoutListener); + mPopupWindow = createPopupWindow(); + updatePopupLayoutParams(); + mPopupWindow.setWidth(mPopupWidth); + mPopupWindow.setHeight(mPopupHeight); + mPopupWindow.showAsDropDown(mAnchorView, mPopupOffsetX, mPopupOffsetY); + } + + private void updatePopupLayoutParams() { + ListView content = mContentList; + PopupWindow popup = mPopupWindow; + + Rect p = new Rect(); + popup.getBackground().getPadding(p); + + int maxHeight = mPopupWindow.getMaxAvailableHeight(mAnchorView) - p.top - p.bottom; + mContentList.measure( + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)); + mPopupWidth = content.getMeasuredWidth() + p.top + p.bottom; + mPopupHeight = Math.min(maxHeight, content.getMeasuredHeight() + p.left + p.right); + mPopupOffsetX = -p.left; + mPopupOffsetY = -p.top; + } + + private PopupWindow createPopupWindow() { + PopupWindow popup = new PopupWindow(); + popup.setOnDismissListener(mOnDismissListener); + + popup.setBackgroundDrawable(mContext.getResources().getDrawable( + R.drawable.menu_dropdown_panel_holo_dark)); + mContentList = new ListView(mContext); + mContentList.setAdapter(new ItemDataAdapter()); + mContentList.setOnItemClickListener(mOnItemClickListener); + popup.setContentView(mContentList); + popup.setFocusable(true); + popup.setOutsideTouchable(true); + + return popup; + } + + public Item findItem(int id) { + for (Item item : mItems) { + if (item.id == id) return item; + } + return null; + } + + private class ItemDataAdapter extends BaseAdapter { + @Override + public int getCount() { + return mItems.size(); + } + + @Override + public Object getItem(int position) { + return mItems.get(position); + } + + @Override + public long getItemId(int position) { + return mItems.get(position).id; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = LayoutInflater.from(mContext) + .inflate(R.layout.popup_list_item, null); + } + TextView text = (TextView) convertView.findViewById(android.R.id.text1); + text.setText(mItems.get(position).title); + return convertView; + } + } +} diff --git a/src/com/android/gallery3d/ui/SelectionMenu.java b/src/com/android/gallery3d/ui/SelectionMenu.java new file mode 100644 index 000000000..5b0828328 --- /dev/null +++ b/src/com/android/gallery3d/ui/SelectionMenu.java @@ -0,0 +1,61 @@ +/* + * 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.android.gallery3d.ui; + +import android.content.Context; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +import com.android.gallery3d.R; +import com.android.gallery3d.ui.PopupList.OnPopupItemClickListener; + +public class SelectionMenu implements OnClickListener { + @SuppressWarnings("unused") + private static final String TAG = "SelectionMenu"; + + private final Context mContext; + private final Button mButton; + private final PopupList mPopupList; + + public SelectionMenu(Context context, Button button, OnPopupItemClickListener listener) { + mContext = context; + mButton = button; + mPopupList = new PopupList(context, mButton); + mPopupList.addItem(R.id.action_select_all, + context.getString(R.string.select_all)); + mPopupList.setOnPopupItemClickListener(listener); + mButton.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + mPopupList.show(); + } + + public void updateSelectAllMode(boolean inSelectAllMode) { + PopupList.Item item = mPopupList.findItem(R.id.action_select_all); + if (item != null) { + item.setTitle(mContext.getString( + inSelectAllMode ? R.string.deselect_all : R.string.select_all)); + } + } + + public void setTitle(CharSequence title) { + mButton.setText(title); + } +} |