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
17package android.support.v7.view;
18
19import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20
21import android.content.Context;
22import android.support.annotation.RestrictTo;
23import android.support.v4.internal.view.SupportMenu;
24import android.support.v4.internal.view.SupportMenuItem;
25import android.support.v4.util.SimpleArrayMap;
26import android.support.v7.view.menu.MenuWrapperFactory;
27import android.view.ActionMode;
28import android.view.Menu;
29import android.view.MenuInflater;
30import android.view.View;
31
32import java.util.ArrayList;
33
34/**
35 * Wraps a support {@link android.support.v7.view.ActionMode} as a framework
36 * {@link android.view.ActionMode}.
37 *
38 * @hide
39 */
40@RestrictTo(LIBRARY_GROUP)
41public class SupportActionModeWrapper extends ActionMode {
42
43    final Context mContext;
44    final android.support.v7.view.ActionMode mWrappedObject;
45
46    public SupportActionModeWrapper(Context context,
47            android.support.v7.view.ActionMode supportActionMode) {
48        mContext = context;
49        mWrappedObject = supportActionMode;
50    }
51
52    @Override
53    public Object getTag() {
54        return mWrappedObject.getTag();
55    }
56
57    @Override
58    public void setTag(Object tag) {
59        mWrappedObject.setTag(tag);
60    }
61
62    @Override
63    public void setTitle(CharSequence title) {
64        mWrappedObject.setTitle(title);
65    }
66
67    @Override
68    public void setSubtitle(CharSequence subtitle) {
69        mWrappedObject.setSubtitle(subtitle);
70    }
71
72    @Override
73    public void invalidate() {
74        mWrappedObject.invalidate();
75    }
76
77    @Override
78    public void finish() {
79        mWrappedObject.finish();
80    }
81
82    @Override
83    public Menu getMenu() {
84        return MenuWrapperFactory.wrapSupportMenu(mContext, (SupportMenu) mWrappedObject.getMenu());
85    }
86
87    @Override
88    public CharSequence getTitle() {
89        return mWrappedObject.getTitle();
90    }
91
92    @Override
93    public void setTitle(int resId) {
94        mWrappedObject.setTitle(resId);
95    }
96
97    @Override
98    public CharSequence getSubtitle() {
99        return mWrappedObject.getSubtitle();
100    }
101
102    @Override
103    public void setSubtitle(int resId) {
104        mWrappedObject.setSubtitle(resId);
105    }
106
107    @Override
108    public View getCustomView() {
109        return mWrappedObject.getCustomView();
110    }
111
112    @Override
113    public void setCustomView(View view) {
114        mWrappedObject.setCustomView(view);
115    }
116
117    @Override
118    public MenuInflater getMenuInflater() {
119        return mWrappedObject.getMenuInflater();
120    }
121
122    @Override
123    public boolean getTitleOptionalHint() {
124        return mWrappedObject.getTitleOptionalHint();
125    }
126
127    @Override
128    public void setTitleOptionalHint(boolean titleOptional) {
129        mWrappedObject.setTitleOptionalHint(titleOptional);
130    }
131
132    @Override
133    public boolean isTitleOptional() {
134        return mWrappedObject.isTitleOptional();
135    }
136
137    /**
138     * @hide
139     */
140    @RestrictTo(LIBRARY_GROUP)
141    public static class CallbackWrapper implements android.support.v7.view.ActionMode.Callback {
142        final Callback mWrappedCallback;
143        final Context mContext;
144
145        final ArrayList<SupportActionModeWrapper> mActionModes;
146        final SimpleArrayMap<Menu, Menu> mMenus;
147
148        public CallbackWrapper(Context context, Callback supportCallback) {
149            mContext = context;
150            mWrappedCallback = supportCallback;
151            mActionModes = new ArrayList<>();
152            mMenus = new SimpleArrayMap<>();
153        }
154
155        @Override
156        public boolean onCreateActionMode(android.support.v7.view.ActionMode mode, Menu menu) {
157            return mWrappedCallback.onCreateActionMode(getActionModeWrapper(mode),
158                    getMenuWrapper(menu));
159        }
160
161        @Override
162        public boolean onPrepareActionMode(android.support.v7.view.ActionMode mode, Menu menu) {
163            return mWrappedCallback.onPrepareActionMode(getActionModeWrapper(mode),
164                    getMenuWrapper(menu));
165        }
166
167        @Override
168        public boolean onActionItemClicked(android.support.v7.view.ActionMode mode,
169                android.view.MenuItem item) {
170            return mWrappedCallback.onActionItemClicked(getActionModeWrapper(mode),
171                    MenuWrapperFactory.wrapSupportMenuItem(mContext, (SupportMenuItem) item));
172        }
173
174        @Override
175        public void onDestroyActionMode(android.support.v7.view.ActionMode mode) {
176            mWrappedCallback.onDestroyActionMode(getActionModeWrapper(mode));
177        }
178
179        private Menu getMenuWrapper(Menu menu) {
180            Menu wrapper = mMenus.get(menu);
181            if (wrapper == null) {
182                wrapper = MenuWrapperFactory.wrapSupportMenu(mContext, (SupportMenu) menu);
183                mMenus.put(menu, wrapper);
184            }
185            return wrapper;
186        }
187
188        public ActionMode getActionModeWrapper(android.support.v7.view.ActionMode mode) {
189            // First see if we already have a wrapper for this mode
190            for (int i = 0, count = mActionModes.size(); i < count; i++) {
191                SupportActionModeWrapper wrapper = mActionModes.get(i);
192                if (wrapper != null && wrapper.mWrappedObject == mode) {
193                    // We've found a wrapper, return it
194                    return wrapper;
195                }
196            }
197
198            // If we reach here then we haven't seen this mode before. Create a new wrapper and
199            // add it to our collection
200            SupportActionModeWrapper wrapper = new SupportActionModeWrapper(mContext, mode);
201            mActionModes.add(wrapper);
202            return wrapper;
203        }
204    }
205}