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 */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.appcompat.view; 174c2a95906254748cb9a843b061288265d6e185a9Chris Banes 18ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas 204c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.content.Context; 214c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Menu; 224c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.MenuInflater; 234c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.MenuItem; 244c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.View; 254c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent; 264c2a95906254748cb9a843b061288265d6e185a9Chris Banes 273de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.annotation.RestrictTo; 283de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.view.menu.MenuBuilder; 293de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.view.menu.MenuPopupHelper; 303de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.view.menu.SubMenuBuilder; 313de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.widget.ActionBarContextView; 323de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikas 334c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport java.lang.ref.WeakReference; 344c2a95906254748cb9a843b061288265d6e185a9Chris Banes 35b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes/** 36b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes * @hide 37b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes */ 388e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP) 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( 56458543f38db49fdcb1764f007ded33820964c3feAurimas Liutikas MenuItem.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 139e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 1404c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 1414c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mCallback.onActionItemClicked(this, item); 1424c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1434c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1444c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 1454c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1464c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1474c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 1484c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (!subMenu.hasVisibleItems()) { 1494c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1504c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1514c2a95906254748cb9a843b061288265d6e185a9Chris Banes 152547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes new MenuPopupHelper(mContextView.getContext(), subMenu).show(); 1534c2a95906254748cb9a843b061288265d6e185a9Chris Banes return true; 1544c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1554c2a95906254748cb9a843b061288265d6e185a9Chris Banes 1564c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onCloseSubMenu(SubMenuBuilder menu) { 1574c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1584c2a95906254748cb9a843b061288265d6e185a9Chris Banes 159e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 1604c2a95906254748cb9a843b061288265d6e185a9Chris Banes public void onMenuModeChange(MenuBuilder menu) { 1614c2a95906254748cb9a843b061288265d6e185a9Chris Banes invalidate(); 1624c2a95906254748cb9a843b061288265d6e185a9Chris Banes mContextView.showOverflowMenu(); 1634c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1644c2a95906254748cb9a843b061288265d6e185a9Chris Banes 165e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 1664c2a95906254748cb9a843b061288265d6e185a9Chris Banes public boolean isUiFocusable() { 1674c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mFocusable; 1684c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 169547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes} 170