ActionMenuItemView.java revision 7b5e9e6c1c7098b6d7b2c6f9ab0c316f0f66109e
1/*
2 * Copyright (C) 2010 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 com.android.internal.view.menu;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Rect;
22import android.graphics.drawable.Drawable;
23import android.text.TextUtils;
24import android.util.AttributeSet;
25import android.view.Gravity;
26import android.view.View;
27import android.widget.Button;
28import android.widget.ImageButton;
29import android.widget.LinearLayout;
30import android.widget.Toast;
31
32/**
33 * @hide
34 */
35public class ActionMenuItemView extends LinearLayout
36        implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener,
37        ActionMenuView.ActionMenuChildView {
38    private static final String TAG = "ActionMenuItemView";
39
40    private MenuItemImpl mItemData;
41    private CharSequence mTitle;
42    private MenuBuilder.ItemInvoker mItemInvoker;
43
44    private ImageButton mImageButton;
45    private Button mTextButton;
46    private boolean mAllowTextWithIcon;
47    private boolean mShowTextAllCaps;
48    private boolean mExpandedFormat;
49
50    public ActionMenuItemView(Context context) {
51        this(context, null);
52    }
53
54    public ActionMenuItemView(Context context, AttributeSet attrs) {
55        this(context, attrs, 0);
56    }
57
58    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
59        super(context, attrs, defStyle);
60        final Resources res = context.getResources();
61        mAllowTextWithIcon = res.getBoolean(
62                com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
63        mShowTextAllCaps = res.getBoolean(com.android.internal.R.bool.config_actionMenuItemAllCaps);
64    }
65
66    @Override
67    public void onFinishInflate() {
68        mImageButton = (ImageButton) findViewById(com.android.internal.R.id.imageButton);
69        mTextButton = (Button) findViewById(com.android.internal.R.id.textButton);
70        mImageButton.setOnClickListener(this);
71        mTextButton.setOnClickListener(this);
72        mImageButton.setOnLongClickListener(this);
73        setOnClickListener(this);
74        setOnLongClickListener(this);
75    }
76
77    public MenuItemImpl getItemData() {
78        return mItemData;
79    }
80
81    public void initialize(MenuItemImpl itemData, int menuType) {
82        mItemData = itemData;
83
84        setIcon(itemData.getIcon());
85        setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon
86        setId(itemData.getItemId());
87
88        setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
89        setEnabled(itemData.isEnabled());
90    }
91
92    @Override
93    public void setEnabled(boolean enabled) {
94        super.setEnabled(enabled);
95        mImageButton.setEnabled(enabled);
96        mTextButton.setEnabled(enabled);
97    }
98
99    public void onClick(View v) {
100        if (mItemInvoker != null) {
101            mItemInvoker.invokeItem(mItemData);
102        }
103    }
104
105    public void setItemInvoker(MenuBuilder.ItemInvoker invoker) {
106        mItemInvoker = invoker;
107    }
108
109    public boolean prefersCondensedTitle() {
110        return true;
111    }
112
113    public void setCheckable(boolean checkable) {
114        // TODO Support checkable action items
115    }
116
117    public void setChecked(boolean checked) {
118        // TODO Support checkable action items
119    }
120
121    public void setExpandedFormat(boolean expandedFormat) {
122        if (mExpandedFormat != expandedFormat) {
123            mExpandedFormat = expandedFormat;
124            if (mItemData != null) {
125                mItemData.actionFormatChanged();
126            }
127        }
128    }
129
130    private void updateTextButtonVisibility() {
131        boolean visible = !TextUtils.isEmpty(mTextButton.getText());
132        visible &= mImageButton.getDrawable() == null ||
133                (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));
134
135        mTextButton.setVisibility(visible ? VISIBLE : GONE);
136    }
137
138    public void setIcon(Drawable icon) {
139        mImageButton.setImageDrawable(icon);
140        if (icon != null) {
141            mImageButton.setVisibility(VISIBLE);
142        } else {
143            mImageButton.setVisibility(GONE);
144        }
145
146        updateTextButtonVisibility();
147    }
148
149    public boolean hasText() {
150        return mTextButton.getVisibility() != GONE;
151    }
152
153    public void setShortcut(boolean showShortcut, char shortcutKey) {
154        // Action buttons don't show text for shortcut keys.
155    }
156
157    public void setTitle(CharSequence title) {
158        mTitle = title;
159
160        // populate accessibility description with title
161        setContentDescription(title);
162
163        mTextButton.setText(mTitle);
164
165        updateTextButtonVisibility();
166    }
167
168    public boolean showsIcon() {
169        return true;
170    }
171
172    public boolean needsDividerBefore() {
173        return hasText() && mItemData.getIcon() == null;
174    }
175
176    public boolean needsDividerAfter() {
177        return hasText();
178    }
179
180    @Override
181    public boolean onLongClick(View v) {
182        if (hasText()) {
183            // Don't show the cheat sheet for items that already show text.
184            return false;
185        }
186
187        final int[] screenPos = new int[2];
188        final Rect displayFrame = new Rect();
189        getLocationOnScreen(screenPos);
190        getWindowVisibleDisplayFrame(displayFrame);
191
192        final Context context = getContext();
193        final int width = getWidth();
194        final int height = getHeight();
195        final int midy = screenPos[1] + height / 2;
196        final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
197
198        Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT);
199        if (midy < displayFrame.height()) {
200            // Show along the top; follow action buttons
201            cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
202                    screenWidth - screenPos[0] - width / 2, height);
203        } else {
204            // Show along the bottom center
205            cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
206        }
207        cheatSheet.show();
208        return true;
209    }
210}
211