14c2a95906254748cb9a843b061288265d6e185a9Chris Banes/* 24c2a95906254748cb9a843b061288265d6e185a9Chris Banes * Copyright (C) 2014 The Android Open Source Project 34c2a95906254748cb9a843b061288265d6e185a9Chris Banes * 44c2a95906254748cb9a843b061288265d6e185a9Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 54c2a95906254748cb9a843b061288265d6e185a9Chris Banes * you may not use this file except in compliance with the License. 64c2a95906254748cb9a843b061288265d6e185a9Chris Banes * You may obtain a copy of the License at 74c2a95906254748cb9a843b061288265d6e185a9Chris Banes * 84c2a95906254748cb9a843b061288265d6e185a9Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 94c2a95906254748cb9a843b061288265d6e185a9Chris Banes * 104c2a95906254748cb9a843b061288265d6e185a9Chris Banes * Unless required by applicable law or agreed to in writing, software 114c2a95906254748cb9a843b061288265d6e185a9Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 124c2a95906254748cb9a843b061288265d6e185a9Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134c2a95906254748cb9a843b061288265d6e185a9Chris Banes * See the License for the specific language governing permissions and 144c2a95906254748cb9a843b061288265d6e185a9Chris Banes * limitations under the License. 154c2a95906254748cb9a843b061288265d6e185a9Chris Banes */ 1666698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banespackage android.support.v7.view; 174c2a95906254748cb9a843b061288265d6e185a9Chris Banes 184c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.content.Context; 19c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 20547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banesimport android.support.v4.view.MenuItemCompat; 2166698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuBuilder; 2266698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuPopupHelper; 2366698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.SubMenuBuilder; 2466698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ActionBarContextView; 254c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Menu; 264c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.MenuInflater; 274c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.MenuItem; 284c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.View; 294c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent; 304c2a95906254748cb9a843b061288265d6e185a9Chris Banes 314c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport java.lang.ref.WeakReference; 324c2a95906254748cb9a843b061288265d6e185a9Chris Banes 33c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport static android.support.annotation.RestrictTo.Scope.GROUP_ID; 34c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette 35b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes/** 36b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes * @hide 37b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes */ 38c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette@RestrictTo(GROUP_ID) 394c2a95906254748cb9a843b061288265d6e185a9Chris Banespublic class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback { 404c2a95906254748cb9a843b061288265d6e185a9Chris Banes private Context mContext; 414c2a95906254748cb9a843b061288265d6e185a9Chris Banes private ActionBarContextView mContextView; 424c2a95906254748cb9a843b061288265d6e185a9Chris Banes private ActionMode.Callback mCallback; 434c2a95906254748cb9a843b061288265d6e185a9Chris Banes private WeakReference<View> mCustomView; 444c2a95906254748cb9a843b061288265d6e185a9Chris Banes private boolean mFinished; 454c2a95906254748cb9a843b061288265d6e185a9Chris Banes private boolean mFocusable; 464c2a95906254748cb9a843b061288265d6e185a9Chris Banes 474c2a95906254748cb9a843b061288265d6e185a9Chris Banes private MenuBuilder mMenu; 484c2a95906254748cb9a843b061288265d6e185a9Chris Banes 494c2a95906254748cb9a843b061288265d6e185a9Chris Banes public StandaloneActionMode(Context context, ActionBarContextView view, 504c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode.Callback callback, boolean isFocusable) { 514c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContext = context; 524c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView = view; 534c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback = callback; 544c2a95906254748cb9a843b061288265d6e185a9Chris Banes 55547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mMenu = new MenuBuilder(view.getContext()).setDefaultShowAsAction( 56547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); 574c2a95906254748cb9a843b061288265d6e185a9Chris Banes mMenu.setCallback(this); 584c2a95906254748cb9a843b061288265d6e185a9Chris Banes mFocusable = isFocusable; 594c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 604c2a95906254748cb9a843b061288265d6e185a9Chris Banes 614c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 624c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitle(CharSequence title) { 634c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setTitle(title); 644c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 654c2a95906254748cb9a843b061288265d6e185a9Chris Banes 664c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 674c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setSubtitle(CharSequence subtitle) { 684c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setSubtitle(subtitle); 694c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 704c2a95906254748cb9a843b061288265d6e185a9Chris Banes 714c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 724c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitle(int resId) { 734c2a95906254748cb9a843b061288265d6e185a9Chris Banes setTitle(mContext.getString(resId)); 744c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 754c2a95906254748cb9a843b061288265d6e185a9Chris Banes 764c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 774c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setSubtitle(int resId) { 784c2a95906254748cb9a843b061288265d6e185a9Chris Banes setSubtitle(mContext.getString(resId)); 794c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 804c2a95906254748cb9a843b061288265d6e185a9Chris Banes 814c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 824c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitleOptionalHint(boolean titleOptional) { 834c2a95906254748cb9a843b061288265d6e185a9Chris Banes super.setTitleOptionalHint(titleOptional); 844c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setTitleOptional(titleOptional); 854c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 864c2a95906254748cb9a843b061288265d6e185a9Chris Banes 874c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 884c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean isTitleOptional() { 894c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.isTitleOptional(); 904c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 914c2a95906254748cb9a843b061288265d6e185a9Chris Banes 924c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 934c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setCustomView(View view) { 944c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setCustomView(view); 954c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCustomView = view != null ? new WeakReference<View>(view) : null; 964c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 974c2a95906254748cb9a843b061288265d6e185a9Chris Banes 984c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 994c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void invalidate() { 1004c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback.onPrepareActionMode(this, mMenu); 1014c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1024c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1034c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1044c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void finish() { 1054c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mFinished) { 1064c2a95906254748cb9a843b061288265d6e185a9Chris Banes return; 1074c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1084c2a95906254748cb9a843b061288265d6e185a9Chris Banes mFinished = true; 1094c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1104c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 1114c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback.onDestroyActionMode(this); 1124c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1134c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1144c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1154c2a95906254748cb9a843b061288265d6e185a9Chris Banes public Menu getMenu() { 1164c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mMenu; 1174c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1184c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1194c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1204c2a95906254748cb9a843b061288265d6e185a9Chris Banes public CharSequence getTitle() { 1214c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.getTitle(); 1224c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1234c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1244c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1254c2a95906254748cb9a843b061288265d6e185a9Chris Banes public CharSequence getSubtitle() { 1264c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.getSubtitle(); 1274c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1284c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1294c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1304c2a95906254748cb9a843b061288265d6e185a9Chris Banes public View getCustomView() { 1314c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mCustomView != null ? mCustomView.get() : null; 1324c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1334c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1344c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1354c2a95906254748cb9a843b061288265d6e185a9Chris Banes public MenuInflater getMenuInflater() { 136572ea71a163cf3e8fc1e6b9bbb7a39ee07a9a138Chris Banes return new SupportMenuInflater(mContextView.getContext()); 1374c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1384c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1394c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 1404c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mCallback.onActionItemClicked(this, item); 1414c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1424c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1434c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 1444c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1454c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1464c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 1474c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (!subMenu.hasVisibleItems()) { 1484c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1494c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1504c2a95906254748cb9a843b061288265d6e185a9Chris Banes 151547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes new MenuPopupHelper(mContextView.getContext(), subMenu).show(); 1524c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1534c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1544c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1554c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseSubMenu(SubMenuBuilder menu) { 1564c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1574c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1584c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onMenuModeChange(MenuBuilder menu) { 1594c2a95906254748cb9a843b061288265d6e185a9Chris Banes invalidate(); 1604c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.showOverflowMenu(); 1614c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1624c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1634c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean isUiFocusable() { 1644c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mFocusable; 1654c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 166547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes} 167