Home | History | Annotate | Download | only in inputmethodservice
      1 /*
      2  * Copyright (C) 2011 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 android.inputmethodservice;
     18 
     19 import com.android.internal.view.menu.MenuBuilder;
     20 import com.android.internal.view.menu.MenuPopupHelper;
     21 
     22 import android.content.Context;
     23 import android.util.AttributeSet;
     24 import android.view.ActionMode;
     25 import android.view.Menu;
     26 import android.view.MenuInflater;
     27 import android.view.MenuItem;
     28 import android.view.View;
     29 import android.view.accessibility.AccessibilityEvent;
     30 import android.widget.Button;
     31 import android.widget.LinearLayout;
     32 
     33 /**
     34  * ExtractEditLayout provides an ActionMode presentation for the
     35  * limited screen real estate in extract mode.
     36  *
     37  * @hide
     38  */
     39 public class ExtractEditLayout extends LinearLayout {
     40     ExtractActionMode mActionMode;
     41     Button mExtractActionButton;
     42     Button mEditButton;
     43 
     44     public ExtractEditLayout(Context context) {
     45         super(context);
     46     }
     47 
     48     public ExtractEditLayout(Context context, AttributeSet attrs) {
     49         super(context, attrs);
     50     }
     51 
     52     @Override
     53     public ActionMode startActionModeForChild(View sourceView, ActionMode.Callback cb) {
     54         final ExtractActionMode mode = new ExtractActionMode(cb);
     55         if (mode.dispatchOnCreate()) {
     56             mode.invalidate();
     57             mExtractActionButton.setVisibility(INVISIBLE);
     58             mEditButton.setVisibility(VISIBLE);
     59             mActionMode = mode;
     60             sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     61             return mode;
     62         }
     63         return null;
     64     }
     65 
     66     /**
     67      * @return true if an action mode is currently active.
     68      */
     69     public boolean isActionModeStarted() {
     70         return mActionMode != null;
     71     }
     72 
     73     /**
     74      * Finishes a possibly started action mode.
     75      */
     76     public void finishActionMode() {
     77         if (mActionMode != null) {
     78             mActionMode.finish();
     79         }
     80     }
     81 
     82     @Override
     83     public void onFinishInflate() {
     84         super.onFinishInflate();
     85         mExtractActionButton = (Button) findViewById(com.android.internal.R.id.inputExtractAction);
     86         mEditButton = (Button) findViewById(com.android.internal.R.id.inputExtractEditButton);
     87         mEditButton.setOnClickListener(new OnClickListener() {
     88             public void onClick(View clicked) {
     89                 if (mActionMode != null) {
     90                     new MenuPopupHelper(getContext(), mActionMode.mMenu, clicked).show();
     91                 }
     92             }
     93         });
     94     }
     95 
     96     private class ExtractActionMode extends ActionMode implements MenuBuilder.Callback {
     97         private ActionMode.Callback mCallback;
     98         MenuBuilder mMenu;
     99 
    100         public ExtractActionMode(Callback cb) {
    101             mMenu = new MenuBuilder(getContext());
    102             mMenu.setCallback(this);
    103             mCallback = cb;
    104         }
    105 
    106         @Override
    107         public void setTitle(CharSequence title) {
    108             // Title will not be shown.
    109         }
    110 
    111         @Override
    112         public void setTitle(int resId) {
    113             // Title will not be shown.
    114         }
    115 
    116         @Override
    117         public void setSubtitle(CharSequence subtitle) {
    118             // Subtitle will not be shown.
    119         }
    120 
    121         @Override
    122         public void setSubtitle(int resId) {
    123             // Subtitle will not be shown.
    124         }
    125 
    126         @Override
    127         public boolean isTitleOptional() {
    128             // Not only is it optional, it will *never* be shown.
    129             return true;
    130         }
    131 
    132         @Override
    133         public void setCustomView(View view) {
    134             // Custom view is not supported here.
    135         }
    136 
    137         @Override
    138         public void invalidate() {
    139             mMenu.stopDispatchingItemsChanged();
    140             try {
    141                 mCallback.onPrepareActionMode(this, mMenu);
    142             } finally {
    143                 mMenu.startDispatchingItemsChanged();
    144             }
    145         }
    146 
    147         public boolean dispatchOnCreate() {
    148             mMenu.stopDispatchingItemsChanged();
    149             try {
    150                 return mCallback.onCreateActionMode(this, mMenu);
    151             } finally {
    152                 mMenu.startDispatchingItemsChanged();
    153             }
    154         }
    155 
    156         @Override
    157         public void finish() {
    158             if (mActionMode != this) {
    159                 // Not the active action mode - no-op
    160                 return;
    161             }
    162 
    163             mCallback.onDestroyActionMode(this);
    164             mCallback = null;
    165 
    166             mExtractActionButton.setVisibility(VISIBLE);
    167             mEditButton.setVisibility(INVISIBLE);
    168 
    169             sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
    170 
    171             mActionMode = null;
    172         }
    173 
    174         @Override
    175         public Menu getMenu() {
    176             return mMenu;
    177         }
    178 
    179         @Override
    180         public CharSequence getTitle() {
    181             return null;
    182         }
    183 
    184         @Override
    185         public CharSequence getSubtitle() {
    186             return null;
    187         }
    188 
    189         @Override
    190         public View getCustomView() {
    191             return null;
    192         }
    193 
    194         @Override
    195         public MenuInflater getMenuInflater() {
    196             return new MenuInflater(getContext());
    197         }
    198 
    199         @Override
    200         public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
    201             if (mCallback != null) {
    202                 return mCallback.onActionItemClicked(this, item);
    203             }
    204             return false;
    205         }
    206 
    207         @Override
    208         public void onMenuModeChange(MenuBuilder menu) {
    209         }
    210 
    211     }
    212 }
    213