OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.appmenu; | 5 package org.chromium.chrome.browser.appmenu; |
6 | 6 |
7 import android.animation.Animator; | 7 import android.animation.Animator; |
8 import android.animation.AnimatorSet; | 8 import android.animation.AnimatorSet; |
9 import android.content.Context; | 9 import android.content.Context; |
10 import android.content.res.Resources; | 10 import android.content.res.Resources; |
11 import android.graphics.Rect; | 11 import android.graphics.Rect; |
| 12 import android.graphics.drawable.Drawable; |
12 import android.view.KeyEvent; | 13 import android.view.KeyEvent; |
13 import android.view.LayoutInflater; | 14 import android.view.LayoutInflater; |
14 import android.view.Menu; | 15 import android.view.Menu; |
15 import android.view.MenuItem; | 16 import android.view.MenuItem; |
16 import android.view.Surface; | 17 import android.view.Surface; |
17 import android.view.View; | 18 import android.view.View; |
18 import android.view.View.OnKeyListener; | 19 import android.view.View.OnKeyListener; |
19 import android.view.ViewGroup; | 20 import android.view.ViewGroup; |
20 import android.widget.AdapterView; | 21 import android.widget.AdapterView; |
21 import android.widget.AdapterView.OnItemClickListener; | 22 import android.widget.AdapterView.OnItemClickListener; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 mPopup.setOnDismissListener(new OnDismissListener() { | 100 mPopup.setOnDismissListener(new OnDismissListener() { |
100 @Override | 101 @Override |
101 public void onDismiss() { | 102 public void onDismiss() { |
102 if (mPopup.getAnchorView() instanceof ImageButton) { | 103 if (mPopup.getAnchorView() instanceof ImageButton) { |
103 ((ImageButton) mPopup.getAnchorView()).setSelected(false); | 104 ((ImageButton) mPopup.getAnchorView()).setSelected(false); |
104 } | 105 } |
105 mHandler.onMenuVisibilityChanged(false); | 106 mHandler.onMenuVisibilityChanged(false); |
106 } | 107 } |
107 }); | 108 }); |
108 | 109 |
| 110 // Some OEMs don't actually let us change the background... but they sti
ll return the |
| 111 // padding of the new background, which breaks the menu height. If we s
till have a |
| 112 // drawable here even though our style says @null we should use this pad
ding instead... |
| 113 Drawable originalBgDrawable = mPopup.getBackground(); |
| 114 |
109 // Need to explicitly set the background here. Relying on it being set
in the style caused | 115 // Need to explicitly set the background here. Relying on it being set
in the style caused |
110 // an incorrectly drawn background. | 116 // an incorrectly drawn background. |
111 if (isByHardwareButton) { | 117 if (isByHardwareButton) { |
112 mPopup.setBackgroundDrawable(context.getResources().getDrawable(R.dr
awable.menu_bg)); | 118 mPopup.setBackgroundDrawable(context.getResources().getDrawable(R.dr
awable.menu_bg)); |
113 } else { | 119 } else { |
114 mPopup.setBackgroundDrawable( | 120 mPopup.setBackgroundDrawable( |
115 context.getResources().getDrawable(R.drawable.edge_menu_bg))
; | 121 context.getResources().getDrawable(R.drawable.edge_menu_bg))
; |
116 mPopup.setAnimationStyle(R.style.OverflowMenuAnim); | 122 mPopup.setAnimationStyle(R.style.OverflowMenuAnim); |
117 } | 123 } |
118 | 124 |
(...skipping 14 matching lines...) Expand all Loading... |
133 // Extract visible items from the Menu. | 139 // Extract visible items from the Menu. |
134 int numItems = mMenu.size(); | 140 int numItems = mMenu.size(); |
135 List<MenuItem> menuItems = new ArrayList<MenuItem>(); | 141 List<MenuItem> menuItems = new ArrayList<MenuItem>(); |
136 for (int i = 0; i < numItems; ++i) { | 142 for (int i = 0; i < numItems; ++i) { |
137 MenuItem item = mMenu.getItem(i); | 143 MenuItem item = mMenu.getItem(i); |
138 if (item.isVisible()) { | 144 if (item.isVisible()) { |
139 menuItems.add(item); | 145 menuItems.add(item); |
140 } | 146 } |
141 } | 147 } |
142 | 148 |
| 149 Rect sizingPadding = new Rect(bgPadding); |
| 150 if (isByHardwareButton && originalBgDrawable != null) { |
| 151 Rect originalPadding = new Rect(); |
| 152 originalBgDrawable.getPadding(originalPadding); |
| 153 sizingPadding.top = originalPadding.top; |
| 154 sizingPadding.bottom = originalPadding.bottom; |
| 155 } |
| 156 |
143 boolean showMenuButton = !mIsByHardwareButton; | 157 boolean showMenuButton = !mIsByHardwareButton; |
144 if (!SHOW_SW_MENU_BUTTON) showMenuButton = false; | 158 if (!SHOW_SW_MENU_BUTTON) showMenuButton = false; |
145 // A List adapter for visible items in the Menu. The first row is added
as a header to the | 159 // A List adapter for visible items in the Menu. The first row is added
as a header to the |
146 // list view. | 160 // list view. |
147 mAdapter = new AppMenuAdapter( | 161 mAdapter = new AppMenuAdapter( |
148 this, menuItems, LayoutInflater.from(context), showMenuButton); | 162 this, menuItems, LayoutInflater.from(context), showMenuButton); |
149 mPopup.setAdapter(mAdapter); | 163 mPopup.setAdapter(mAdapter); |
150 | 164 |
151 setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight); | 165 setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight, sizin
gPadding); |
152 setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame); | 166 setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame, sizi
ngPadding); |
153 mPopup.setOnItemClickListener(this); | 167 mPopup.setOnItemClickListener(this); |
154 mPopup.show(); | 168 mPopup.show(); |
155 mPopup.getListView().setItemsCanFocus(true); | 169 mPopup.getListView().setItemsCanFocus(true); |
156 mPopup.getListView().setOnKeyListener(this); | 170 mPopup.getListView().setOnKeyListener(this); |
157 | 171 |
158 mHandler.onMenuVisibilityChanged(true); | 172 mHandler.onMenuVisibilityChanged(true); |
159 | 173 |
160 if (mVerticalFadeDistance > 0) { | 174 if (mVerticalFadeDistance > 0) { |
161 mPopup.getListView().setVerticalFadingEdgeEnabled(true); | 175 mPopup.getListView().setVerticalFadingEdgeEnabled(true); |
162 mPopup.getListView().setFadingEdgeLength(mVerticalFadeDistance); | 176 mPopup.getListView().setFadingEdgeLength(mVerticalFadeDistance); |
163 } | 177 } |
164 | 178 |
165 // Don't animate the menu items for low end devices. | 179 // Don't animate the menu items for low end devices. |
166 if (!SysUtils.isLowEndDevice()) { | 180 if (!SysUtils.isLowEndDevice()) { |
167 mPopup.getListView().addOnLayoutChangeListener(new View.OnLayoutChan
geListener() { | 181 mPopup.getListView().addOnLayoutChangeListener(new View.OnLayoutChan
geListener() { |
168 @Override | 182 @Override |
169 public void onLayoutChange(View v, int left, int top, int right,
int bottom, | 183 public void onLayoutChange(View v, int left, int top, int right,
int bottom, |
170 int oldLeft, int oldTop, int oldRight, int oldBottom) { | 184 int oldLeft, int oldTop, int oldRight, int oldBottom) { |
171 mPopup.getListView().removeOnLayoutChangeListener(this); | 185 mPopup.getListView().removeOnLayoutChangeListener(this); |
172 runMenuItemEnterAnimations(); | 186 runMenuItemEnterAnimations(); |
173 } | 187 } |
174 }); | 188 }); |
175 } | 189 } |
176 } | 190 } |
177 | 191 |
178 private void setPopupOffset(ListPopupWindow popup, int screenRotation, Rect
appRect) { | 192 private void setPopupOffset( |
179 Rect paddingRect = new Rect(); | 193 ListPopupWindow popup, int screenRotation, Rect appRect, Rect paddin
g) { |
180 popup.getBackground().getPadding(paddingRect); | |
181 int[] anchorLocation = new int[2]; | 194 int[] anchorLocation = new int[2]; |
182 popup.getAnchorView().getLocationInWindow(anchorLocation); | 195 popup.getAnchorView().getLocationInWindow(anchorLocation); |
183 int anchorHeight = popup.getAnchorView().getHeight(); | 196 int anchorHeight = popup.getAnchorView().getHeight(); |
184 | 197 |
185 // If we have a hardware menu button, locate the app menu closer to the
estimated | 198 // If we have a hardware menu button, locate the app menu closer to the
estimated |
186 // hardware menu button location. | 199 // hardware menu button location. |
187 if (mIsByHardwareButton) { | 200 if (mIsByHardwareButton) { |
188 int horizontalOffset = -anchorLocation[0]; | 201 int horizontalOffset = -anchorLocation[0]; |
189 switch (screenRotation) { | 202 switch (screenRotation) { |
190 case Surface.ROTATION_0: | 203 case Surface.ROTATION_0: |
191 case Surface.ROTATION_180: | 204 case Surface.ROTATION_180: |
192 horizontalOffset += (appRect.width() - mPopup.getWidth()) /
2; | 205 horizontalOffset += (appRect.width() - mPopup.getWidth()) /
2; |
193 break; | 206 break; |
194 case Surface.ROTATION_90: | 207 case Surface.ROTATION_90: |
195 horizontalOffset += appRect.width() - mPopup.getWidth(); | 208 horizontalOffset += appRect.width() - mPopup.getWidth(); |
196 break; | 209 break; |
197 case Surface.ROTATION_270: | 210 case Surface.ROTATION_270: |
198 break; | 211 break; |
199 default: | 212 default: |
200 assert false; | 213 assert false; |
201 break; | 214 break; |
202 } | 215 } |
203 popup.setHorizontalOffset(horizontalOffset); | 216 popup.setHorizontalOffset(horizontalOffset); |
204 // The menu is displayed above the anchored view, so shift the menu
up by the top | 217 // The menu is displayed above the anchored view, so shift the menu
up by the bottom |
205 // padding of the background. | 218 // padding of the background. |
206 popup.setVerticalOffset(-paddingRect.bottom); | 219 popup.setVerticalOffset(-padding.bottom); |
207 } else { | 220 } else { |
208 // The menu is displayed over and below the anchored view, so shift
the menu up by the | 221 // The menu is displayed over and below the anchored view, so shift
the menu up by the |
209 // height of the anchor view. | 222 // height of the anchor view. |
210 popup.setVerticalOffset(-mNegativeSoftwareVerticalOffset - anchorHei
ght); | 223 popup.setVerticalOffset(-mNegativeSoftwareVerticalOffset - anchorHei
ght); |
211 } | 224 } |
212 } | 225 } |
213 | 226 |
214 /** | 227 /** |
215 * Handles clicks on the AppMenu popup. | 228 * Handles clicks on the AppMenu popup. |
216 * @param menuItem The menu item in the popup that was clicked. | 229 * @param menuItem The menu item in the popup that was clicked. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 return mPopup.isShowing(); | 280 return mPopup.isShowing(); |
268 } | 281 } |
269 | 282 |
270 /** | 283 /** |
271 * @return ListPopupWindow that displays all the menu options. | 284 * @return ListPopupWindow that displays all the menu options. |
272 */ | 285 */ |
273 ListPopupWindow getPopup() { | 286 ListPopupWindow getPopup() { |
274 return mPopup; | 287 return mPopup; |
275 } | 288 } |
276 | 289 |
277 private void setMenuHeight(int numMenuItems, Rect appDimensions, int screenH
eight) { | 290 private void setMenuHeight( |
| 291 int numMenuItems, Rect appDimensions, int screenHeight, Rect padding
) { |
278 assert mPopup.getAnchorView() != null; | 292 assert mPopup.getAnchorView() != null; |
279 View anchorView = mPopup.getAnchorView(); | 293 View anchorView = mPopup.getAnchorView(); |
280 int[] anchorViewLocation = new int[2]; | 294 int[] anchorViewLocation = new int[2]; |
281 anchorView.getLocationOnScreen(anchorViewLocation); | 295 anchorView.getLocationOnScreen(anchorViewLocation); |
282 anchorViewLocation[1] -= appDimensions.top; | 296 anchorViewLocation[1] -= appDimensions.top; |
283 int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight(
) : 0; | 297 int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight(
) : 0; |
284 | 298 |
285 // Set appDimensions.height() for abnormal anchorViewLocation. | 299 // Set appDimensions.height() for abnormal anchorViewLocation. |
286 if (anchorViewLocation[1] > screenHeight) { | 300 if (anchorViewLocation[1] > screenHeight) { |
287 anchorViewLocation[1] = appDimensions.height(); | 301 anchorViewLocation[1] = appDimensions.height(); |
288 } | 302 } |
289 int availableScreenSpace = Math.max(anchorViewLocation[1], | 303 int availableScreenSpace = Math.max(anchorViewLocation[1], |
290 appDimensions.height() - anchorViewLocation[1] - anchorViewImpac
tHeight); | 304 appDimensions.height() - anchorViewLocation[1] - anchorViewImpac
tHeight); |
291 | 305 |
292 Rect padding = new Rect(); | 306 availableScreenSpace -= padding.bottom; |
293 mPopup.getBackground().getPadding(padding); | 307 if (mIsByHardwareButton) availableScreenSpace -= padding.top; |
294 availableScreenSpace -= mIsByHardwareButton ? padding.top : padding.bott
om; | |
295 | 308 |
296 int numCanFit = availableScreenSpace / (mItemRowHeight + mItemDividerHei
ght); | 309 int numCanFit = availableScreenSpace / (mItemRowHeight + mItemDividerHei
ght); |
297 | 310 |
298 // Fade out the last item if we cannot fit all items. | 311 // Fade out the last item if we cannot fit all items. |
299 if (numCanFit < numMenuItems) { | 312 if (numCanFit < numMenuItems) { |
300 int spaceForFullItems = numCanFit * (mItemRowHeight + mItemDividerHe
ight); | 313 int spaceForFullItems = numCanFit * (mItemRowHeight + mItemDividerHe
ight); |
301 int spaceForPartialItem = (int) (LAST_ITEM_SHOW_FRACTION * mItemRowH
eight); | 314 int spaceForPartialItem = (int) (LAST_ITEM_SHOW_FRACTION * mItemRowH
eight); |
302 // Determine which item needs hiding. | 315 // Determine which item needs hiding. |
303 if (spaceForFullItems + spaceForPartialItem < availableScreenSpace)
{ | 316 if (spaceForFullItems + spaceForPartialItem < availableScreenSpace)
{ |
304 mPopup.setHeight(spaceForFullItems + spaceForPartialItem + | 317 mPopup.setHeight(spaceForFullItems + spaceForPartialItem + |
(...skipping 20 matching lines...) Expand all Loading... |
325 builder = animation.play((Animator) animatorObject); | 338 builder = animation.play((Animator) animatorObject); |
326 } else { | 339 } else { |
327 builder.with((Animator) animatorObject); | 340 builder.with((Animator) animatorObject); |
328 } | 341 } |
329 } | 342 } |
330 } | 343 } |
331 | 344 |
332 animation.start(); | 345 animation.start(); |
333 } | 346 } |
334 } | 347 } |
OLD | NEW |