| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.view; |
| |
| import android.content.Context; |
| import android.view.ActionMode; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| |
| import com.android.internal.view.menu.MenuBuilder; |
| |
| /** |
| * ActionMode implementation that wraps several actions modes and creates them on the fly depending |
| * on the ActionMode type chosen by the client. |
| */ |
| public class ActionModeWrapper extends ActionMode { |
| |
| /** |
| * Interface to defer the ActionMode creation until the type is chosen. |
| */ |
| public interface ActionModeProvider { |
| /** |
| * Create the desired ActionMode, that will immediately be used as the current active mode |
| * in the decorator. |
| * |
| * @param callback The {@link ActionMode.Callback} to be used. |
| * @param menuBuilder The {@link MenuBuilder} that should be used by the created |
| * {@link ActionMode}. This will already have been populated. |
| * @return A new {@link ActionMode} ready to be used that uses menuBuilder as its menu. |
| */ |
| ActionMode createActionMode(ActionMode.Callback callback, MenuBuilder menuBuilder); |
| } |
| |
| private ActionMode mActionMode; |
| private final Context mContext; |
| private MenuBuilder mMenu; |
| private final ActionMode.Callback mCallback; |
| private boolean mTypeLocked = false; |
| |
| private CharSequence mTitle; |
| private CharSequence mSubtitle; |
| private View mCustomView; |
| |
| private final ActionModeProvider mActionModeProvider; |
| |
| public ActionModeWrapper( |
| Context context, ActionMode.Callback callback, ActionModeProvider actionModeProvider) { |
| mContext = context; |
| mMenu = new MenuBuilder(context).setDefaultShowAsAction( |
| MenuItem.SHOW_AS_ACTION_IF_ROOM); |
| mCallback = callback; |
| mActionModeProvider = actionModeProvider; |
| } |
| |
| @Override |
| public void setTitle(CharSequence title) { |
| if (mActionMode != null) { |
| mActionMode.setTitle(title); |
| } else { |
| mTitle = title; |
| } |
| } |
| |
| @Override |
| public void setTitle(int resId) { |
| if (mActionMode != null) { |
| mActionMode.setTitle(resId); |
| } else { |
| mTitle = resId != 0 ? mContext.getString(resId) : null; |
| } |
| } |
| |
| @Override |
| public void setSubtitle(CharSequence subtitle) { |
| if (mActionMode != null) { |
| mActionMode.setSubtitle(subtitle); |
| } else { |
| mSubtitle = subtitle; |
| } |
| } |
| |
| @Override |
| public void setSubtitle(int resId) { |
| if (mActionMode != null) { |
| mActionMode.setSubtitle(resId); |
| } else { |
| mSubtitle = resId != 0 ? mContext.getString(resId) : null; |
| } |
| } |
| |
| @Override |
| public void setCustomView(View view) { |
| if (mActionMode != null) { |
| mActionMode.setCustomView(view); |
| } else { |
| mCustomView = view; |
| } |
| } |
| |
| public ActionMode getWrappedActionMode() { |
| return mActionMode; |
| } |
| |
| /** |
| * Set the current type as final and create the necessary ActionMode. After this call, any |
| * changes to the ActionMode type will be ignored. |
| */ |
| public void lockType() { |
| mTypeLocked = true; |
| switch (getType()) { |
| case ActionMode.TYPE_PRIMARY: |
| default: |
| mActionMode = mActionModeProvider.createActionMode(mCallback, mMenu); |
| break; |
| case ActionMode.TYPE_FLOATING: |
| // Not implemented yet. |
| break; |
| } |
| |
| if (mActionMode == null) { |
| return; |
| } |
| |
| mActionMode.setTitle(mTitle); |
| mActionMode.setSubtitle(mSubtitle); |
| if (mCustomView != null) { |
| mActionMode.setCustomView(mCustomView); |
| } |
| |
| mTitle = null; |
| mSubtitle = null; |
| mCustomView = null; |
| } |
| |
| @Override |
| public void setType(int type) { |
| if (!mTypeLocked) { |
| super.setType(type); |
| } else { |
| throw new IllegalStateException( |
| "You can't change the ActionMode's type after onCreateActionMode."); |
| } |
| } |
| |
| @Override |
| public void invalidate() { |
| if (mActionMode != null) { |
| mActionMode.invalidate(); |
| } |
| } |
| |
| @Override |
| public void finish() { |
| if (mActionMode != null) { |
| mActionMode.finish(); |
| } else { |
| mCallback.onDestroyActionMode(this); |
| } |
| } |
| |
| @Override |
| public Menu getMenu() { |
| return mMenu; |
| } |
| |
| @Override |
| public CharSequence getTitle() { |
| if (mActionMode != null) { |
| return mActionMode.getTitle(); |
| } |
| return mTitle; |
| } |
| |
| @Override |
| public CharSequence getSubtitle() { |
| if (mActionMode != null) { |
| return mActionMode.getSubtitle(); |
| } |
| return mSubtitle; |
| } |
| |
| @Override |
| public View getCustomView() { |
| if (mActionMode != null) { |
| return mActionMode.getCustomView(); |
| } |
| return mCustomView; |
| } |
| |
| @Override |
| public MenuInflater getMenuInflater() { |
| return new MenuInflater(mContext); |
| } |
| |
| } |