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 */ 164c2a95906254748cb9a843b061288265d6e185a9Chris Banespackage android.support.v7.internal.view; 174c2a95906254748cb9a843b061288265d6e185a9Chris Banes 184c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.content.Context; 19547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banesimport android.support.v4.view.MenuItemCompat; 204c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 214c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.menu.MenuPopupHelper; 224c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.menu.SubMenuBuilder; 234c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.widget.ActionBarContextView; 244c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.view.ActionMode; 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 33b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes/** 34b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes * @hide 35b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes */ 364c2a95906254748cb9a843b061288265d6e185a9Chris Banespublic class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback { 374c2a95906254748cb9a843b061288265d6e185a9Chris Banes private Context mContext; 384c2a95906254748cb9a843b061288265d6e185a9Chris Banes private ActionBarContextView mContextView; 394c2a95906254748cb9a843b061288265d6e185a9Chris Banes private ActionMode.Callback mCallback; 404c2a95906254748cb9a843b061288265d6e185a9Chris Banes private WeakReference<View> mCustomView; 414c2a95906254748cb9a843b061288265d6e185a9Chris Banes private boolean mFinished; 424c2a95906254748cb9a843b061288265d6e185a9Chris Banes private boolean mFocusable; 434c2a95906254748cb9a843b061288265d6e185a9Chris Banes 444c2a95906254748cb9a843b061288265d6e185a9Chris Banes private MenuBuilder mMenu; 454c2a95906254748cb9a843b061288265d6e185a9Chris Banes 464c2a95906254748cb9a843b061288265d6e185a9Chris Banes public StandaloneActionMode(Context context, ActionBarContextView view, 474c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode.Callback callback, boolean isFocusable) { 484c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContext = context; 494c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView = view; 504c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback = callback; 514c2a95906254748cb9a843b061288265d6e185a9Chris Banes 52547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mMenu = new MenuBuilder(view.getContext()).setDefaultShowAsAction( 53547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); 544c2a95906254748cb9a843b061288265d6e185a9Chris Banes mMenu.setCallback(this); 554c2a95906254748cb9a843b061288265d6e185a9Chris Banes mFocusable = isFocusable; 564c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 574c2a95906254748cb9a843b061288265d6e185a9Chris Banes 584c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 594c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitle(CharSequence title) { 604c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setTitle(title); 614c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 624c2a95906254748cb9a843b061288265d6e185a9Chris Banes 634c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 644c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setSubtitle(CharSequence subtitle) { 654c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setSubtitle(subtitle); 664c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 674c2a95906254748cb9a843b061288265d6e185a9Chris Banes 684c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 694c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitle(int resId) { 704c2a95906254748cb9a843b061288265d6e185a9Chris Banes setTitle(mContext.getString(resId)); 714c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 724c2a95906254748cb9a843b061288265d6e185a9Chris Banes 734c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 744c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setSubtitle(int resId) { 754c2a95906254748cb9a843b061288265d6e185a9Chris Banes setSubtitle(mContext.getString(resId)); 764c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 774c2a95906254748cb9a843b061288265d6e185a9Chris Banes 784c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 794c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setTitleOptionalHint(boolean titleOptional) { 804c2a95906254748cb9a843b061288265d6e185a9Chris Banes super.setTitleOptionalHint(titleOptional); 814c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setTitleOptional(titleOptional); 824c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 834c2a95906254748cb9a843b061288265d6e185a9Chris Banes 844c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 854c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean isTitleOptional() { 864c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.isTitleOptional(); 874c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 884c2a95906254748cb9a843b061288265d6e185a9Chris Banes 894c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 904c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void setCustomView(View view) { 914c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.setCustomView(view); 924c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCustomView = view != null ? new WeakReference<View>(view) : null; 934c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 944c2a95906254748cb9a843b061288265d6e185a9Chris Banes 954c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 964c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void invalidate() { 974c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback.onPrepareActionMode(this, mMenu); 984c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 994c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1004c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1014c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void finish() { 1024c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mFinished) { 1034c2a95906254748cb9a843b061288265d6e185a9Chris Banes return; 1044c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1054c2a95906254748cb9a843b061288265d6e185a9Chris Banes mFinished = true; 1064c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1074c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 1084c2a95906254748cb9a843b061288265d6e185a9Chris Banes mCallback.onDestroyActionMode(this); 1094c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1104c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1114c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1124c2a95906254748cb9a843b061288265d6e185a9Chris Banes public Menu getMenu() { 1134c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mMenu; 1144c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1154c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1164c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1174c2a95906254748cb9a843b061288265d6e185a9Chris Banes public CharSequence getTitle() { 1184c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.getTitle(); 1194c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1204c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1214c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1224c2a95906254748cb9a843b061288265d6e185a9Chris Banes public CharSequence getSubtitle() { 1234c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mContextView.getSubtitle(); 1244c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1254c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1264c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1274c2a95906254748cb9a843b061288265d6e185a9Chris Banes public View getCustomView() { 1284c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mCustomView != null ? mCustomView.get() : null; 1294c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1304c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1314c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 1324c2a95906254748cb9a843b061288265d6e185a9Chris Banes public MenuInflater getMenuInflater() { 133547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes return new MenuInflater(mContextView.getContext()); 1344c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1354c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1364c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 1374c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mCallback.onActionItemClicked(this, item); 1384c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1394c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1404c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 1414c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1424c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1434c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 1444c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (!subMenu.hasVisibleItems()) { 1454c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1464c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1474c2a95906254748cb9a843b061288265d6e185a9Chris Banes 148547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes new MenuPopupHelper(mContextView.getContext(), subMenu).show(); 1494c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1504c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1514c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1524c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseSubMenu(SubMenuBuilder menu) { 1534c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1544c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1554c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onMenuModeChange(MenuBuilder menu) { 1564c2a95906254748cb9a843b061288265d6e185a9Chris Banes invalidate(); 1574c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.showOverflowMenu(); 1584c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1594c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1604c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean isUiFocusable() { 1614c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mFocusable; 1624c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 163547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes} 164