1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.appcompat.view; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21 import android.content.Context; 22 import android.view.ActionMode; 23 import android.view.Menu; 24 import android.view.MenuInflater; 25 import android.view.View; 26 27 import androidx.annotation.RestrictTo; 28 import androidx.appcompat.view.menu.MenuWrapperFactory; 29 import androidx.collection.SimpleArrayMap; 30 import androidx.core.internal.view.SupportMenu; 31 import androidx.core.internal.view.SupportMenuItem; 32 33 import java.util.ArrayList; 34 35 /** 36 * Wraps a support {@link androidx.appcompat.view.ActionMode} as a framework 37 * {@link android.view.ActionMode}. 38 * 39 * @hide 40 */ 41 @RestrictTo(LIBRARY_GROUP) 42 public class SupportActionModeWrapper extends ActionMode { 43 44 final Context mContext; 45 final androidx.appcompat.view.ActionMode mWrappedObject; 46 47 public SupportActionModeWrapper(Context context, 48 androidx.appcompat.view.ActionMode supportActionMode) { 49 mContext = context; 50 mWrappedObject = supportActionMode; 51 } 52 53 @Override 54 public Object getTag() { 55 return mWrappedObject.getTag(); 56 } 57 58 @Override 59 public void setTag(Object tag) { 60 mWrappedObject.setTag(tag); 61 } 62 63 @Override 64 public void setTitle(CharSequence title) { 65 mWrappedObject.setTitle(title); 66 } 67 68 @Override 69 public void setSubtitle(CharSequence subtitle) { 70 mWrappedObject.setSubtitle(subtitle); 71 } 72 73 @Override 74 public void invalidate() { 75 mWrappedObject.invalidate(); 76 } 77 78 @Override 79 public void finish() { 80 mWrappedObject.finish(); 81 } 82 83 @Override 84 public Menu getMenu() { 85 return MenuWrapperFactory.wrapSupportMenu(mContext, (SupportMenu) mWrappedObject.getMenu()); 86 } 87 88 @Override 89 public CharSequence getTitle() { 90 return mWrappedObject.getTitle(); 91 } 92 93 @Override 94 public void setTitle(int resId) { 95 mWrappedObject.setTitle(resId); 96 } 97 98 @Override 99 public CharSequence getSubtitle() { 100 return mWrappedObject.getSubtitle(); 101 } 102 103 @Override 104 public void setSubtitle(int resId) { 105 mWrappedObject.setSubtitle(resId); 106 } 107 108 @Override 109 public View getCustomView() { 110 return mWrappedObject.getCustomView(); 111 } 112 113 @Override 114 public void setCustomView(View view) { 115 mWrappedObject.setCustomView(view); 116 } 117 118 @Override 119 public MenuInflater getMenuInflater() { 120 return mWrappedObject.getMenuInflater(); 121 } 122 123 @Override 124 public boolean getTitleOptionalHint() { 125 return mWrappedObject.getTitleOptionalHint(); 126 } 127 128 @Override 129 public void setTitleOptionalHint(boolean titleOptional) { 130 mWrappedObject.setTitleOptionalHint(titleOptional); 131 } 132 133 @Override 134 public boolean isTitleOptional() { 135 return mWrappedObject.isTitleOptional(); 136 } 137 138 /** 139 * @hide 140 */ 141 @RestrictTo(LIBRARY_GROUP) 142 public static class CallbackWrapper implements androidx.appcompat.view.ActionMode.Callback { 143 final Callback mWrappedCallback; 144 final Context mContext; 145 146 final ArrayList<SupportActionModeWrapper> mActionModes; 147 final SimpleArrayMap<Menu, Menu> mMenus; 148 149 public CallbackWrapper(Context context, Callback supportCallback) { 150 mContext = context; 151 mWrappedCallback = supportCallback; 152 mActionModes = new ArrayList<>(); 153 mMenus = new SimpleArrayMap<>(); 154 } 155 156 @Override 157 public boolean onCreateActionMode(androidx.appcompat.view.ActionMode mode, Menu menu) { 158 return mWrappedCallback.onCreateActionMode(getActionModeWrapper(mode), 159 getMenuWrapper(menu)); 160 } 161 162 @Override 163 public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode mode, Menu menu) { 164 return mWrappedCallback.onPrepareActionMode(getActionModeWrapper(mode), 165 getMenuWrapper(menu)); 166 } 167 168 @Override 169 public boolean onActionItemClicked(androidx.appcompat.view.ActionMode mode, 170 android.view.MenuItem item) { 171 return mWrappedCallback.onActionItemClicked(getActionModeWrapper(mode), 172 MenuWrapperFactory.wrapSupportMenuItem(mContext, (SupportMenuItem) item)); 173 } 174 175 @Override 176 public void onDestroyActionMode(androidx.appcompat.view.ActionMode mode) { 177 mWrappedCallback.onDestroyActionMode(getActionModeWrapper(mode)); 178 } 179 180 private Menu getMenuWrapper(Menu menu) { 181 Menu wrapper = mMenus.get(menu); 182 if (wrapper == null) { 183 wrapper = MenuWrapperFactory.wrapSupportMenu(mContext, (SupportMenu) menu); 184 mMenus.put(menu, wrapper); 185 } 186 return wrapper; 187 } 188 189 public ActionMode getActionModeWrapper(androidx.appcompat.view.ActionMode mode) { 190 // First see if we already have a wrapper for this mode 191 for (int i = 0, count = mActionModes.size(); i < count; i++) { 192 SupportActionModeWrapper wrapper = mActionModes.get(i); 193 if (wrapper != null && wrapper.mWrappedObject == mode) { 194 // We've found a wrapper, return it 195 return wrapper; 196 } 197 } 198 199 // If we reach here then we haven't seen this mode before. Create a new wrapper and 200 // add it to our collection 201 SupportActionModeWrapper wrapper = new SupportActionModeWrapper(mContext, mode); 202 mActionModes.add(wrapper); 203 return wrapper; 204 } 205 } 206 }