Home | History | Annotate | Download | only in view
      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 }