/* * 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.talkback.contextmenu; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.view.ActionProvider; import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; public abstract class ContextMenuItem implements MenuItem { private Context mContext; private int mItemId; private int mGroupId; private char mAlphaShortcut; private char mNumericShortcut; private Drawable mIcon; private int mOrder; private Intent mIntent; private boolean mEnabled = true; private CharSequence mTitle; private CharSequence mTitleCondensed; private boolean mVisible = true; private boolean mCheckable = false; private boolean mChecked = false; private OnMenuItemClickListener mListener; private ContextMenuInfo mMenuInfo; // Used for EditText cursor control. // When the user performs cursor control(Move cursor to end, etc, from Local Context Menu) // in an EditText, the accessibility focus will be saved (when navigating in the context menu) // and reset back(when the context menu dismisses). A TYPE_ACCESSIBILITY_VIEW_FOCUS and a // TYPE_WINDOWS_CHANGED event will be fired. To avoid EditText description re-read after // the cursor control, we need to skip these two events. private boolean mSkipRefocusEvents = false; protected ContextMenuItem(Context context, int groupId, int itemId, int order, CharSequence title) { mItemId = itemId; mGroupId = groupId; mContext = context; mOrder = order; mTitle = title; mMenuInfo = new ContextMenuInfo(); } @Override public char getAlphabeticShortcut() { return mAlphaShortcut; } @Override public char getNumericShortcut() { return mNumericShortcut; } @Override public ContextMenuItem setAlphabeticShortcut(char alphaChar) { mAlphaShortcut = alphaChar; return this; } @Override public ContextMenuItem setNumericShortcut(char numericChar) { mNumericShortcut = numericChar; return this; } @Override public ContextMenuItem setShortcut(char numericChar, char alphaChar) { mNumericShortcut = numericChar; mAlphaShortcut = alphaChar; return this; } @Override public int getGroupId() { return mGroupId; } @Override public Drawable getIcon() { return mIcon; } @Override public MenuItem setIcon(Drawable icon) { mIcon = icon; return this; } @Override public MenuItem setIcon(int iconRes) { if (iconRes == 0) { mIcon = null; } else { mIcon = mContext.getResources().getDrawable(iconRes); } return this; } @Override public int getOrder() { return mOrder; } @Override public Intent getIntent() { return mIntent; } @Override public MenuItem setIntent(Intent intent) { mIntent = intent; return this; } @Override public boolean isEnabled() { return mEnabled; } @Override public MenuItem setEnabled(boolean enabled) { mEnabled = enabled; return this; } @Override public CharSequence getTitle() { return mTitle; } @Override public MenuItem setTitle(CharSequence title) { mTitle = title; return this; } @Override public CharSequence getTitleCondensed() { return mTitleCondensed; } @Override public MenuItem setTitleCondensed(CharSequence titleCondensed) { mTitleCondensed = titleCondensed; return this; } @Override public MenuItem setTitle(int titleRes) { mTitle = mContext.getText(titleRes); return this; } @Override public int getItemId() { return mItemId; } @Override public boolean isCheckable() { return mCheckable; } @Override public boolean isChecked() { return mCheckable && mChecked; } @Override public boolean isVisible() { return mVisible; } @Override public MenuItem setCheckable(boolean checkable) { mCheckable = checkable; return this; } @Override public MenuItem setChecked(boolean checked) { mChecked = checked; return this; } @Override public MenuItem setVisible(boolean visible) { mVisible = visible; return this; } @Override public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { mListener = menuItemClickListener; return this; } @Override public boolean collapseActionView() { return false; } @Override public boolean expandActionView() { return false; } @TargetApi(14) @Override public ActionProvider getActionProvider() { return null; } @Override public View getActionView() { return null; } @Override public boolean isActionViewExpanded() { return false; } @TargetApi(14) @Override public MenuItem setActionProvider(ActionProvider actionProvider) { throw new UnsupportedOperationException(); } @Override public MenuItem setActionView(View view) { throw new UnsupportedOperationException(); } @Override public MenuItem setActionView(int resId) { throw new UnsupportedOperationException(); } @Override public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { throw new UnsupportedOperationException(); } @Override public void setShowAsAction(int actionEnum) { throw new UnsupportedOperationException(); } @Override public MenuItem setShowAsActionFlags(int actionEnum) { throw new UnsupportedOperationException(); } @Override public ContextMenu.ContextMenuInfo getMenuInfo() { return mMenuInfo; } //TODO internal sdk has no setIconTintList abstract method but public sdk does. // Check it after M release public MenuItem setIconTintList(ColorStateList tint) { return this; } //TODO internal sdk has no setIconTintMode abstract method but public sdk does. // Check it after M release public MenuItem setIconTintMode(PorterDuff.Mode tintMode) { return this; } public void setSkipRefocusEvents(boolean skip) { mSkipRefocusEvents = skip; } public boolean getSkipRefocusEvents() { return mSkipRefocusEvents; } /** * Attempts to perform this item's click action. * * @return {@code true} if this item performs an action */ public boolean onClickPerformed() { if (mCheckable) { mChecked = !mChecked; } return mListener != null && mListener.onMenuItemClick(this); } /** * This class doesn't actually do anything. */ private static class ContextMenuInfo implements ContextMenu.ContextMenuInfo { // Empty class. } }