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.Animator.AnimatorListener; | 8 import android.animation.Animator.AnimatorListener; |
9 import android.animation.AnimatorSet; | 9 import android.animation.AnimatorSet; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 /** | 126 /** |
127 * Creates and shows the app menu anchored to the specified view. | 127 * Creates and shows the app menu anchored to the specified view. |
128 * | 128 * |
129 * @param context The context of the AppMenu (ensure the proper theme is set
on this context). | 129 * @param context The context of the AppMenu (ensure the proper theme is set
on this context). |
130 * @param anchorView The anchor {@link View} of the {@link ListPopupWindow}. | 130 * @param anchorView The anchor {@link View} of the {@link ListPopupWindow}. |
131 * @param isByHardwareButton Whether or not hardware button triggered it. (o
ppose to software | 131 * @param isByHardwareButton Whether or not hardware button triggered it. (o
ppose to software |
132 * button). | 132 * button). |
133 * @param screenRotation Current device screen rotation. | 133 * @param screenRotation Current device screen rotation. |
134 * @param visibleDisplayFrame The display area rect in which AppMenu is supp
osed to fit in. | 134 * @param visibleDisplayFrame The display area rect in which AppMenu is supp
osed to fit in. |
135 * @param screenHeight Current device screen height. | 135 * @param screenHeight Current device screen height. |
| 136 * @param footerResourceId The resource id for a view to add to the end of t
he menu list. |
| 137 * Can be 0 if no such view is required. |
136 */ | 138 */ |
137 void show(Context context, View anchorView, boolean isByHardwareButton, int
screenRotation, | 139 void show(Context context, View anchorView, boolean isByHardwareButton, int
screenRotation, |
138 Rect visibleDisplayFrame, int screenHeight) { | 140 Rect visibleDisplayFrame, int screenHeight, int footerResourceId) { |
139 mPopup = new ListPopupWindow(context, null, android.R.attr.popupMenuStyl
e); | 141 mPopup = new ListPopupWindow(context, null, android.R.attr.popupMenuStyl
e); |
140 mPopup.setModal(true); | 142 mPopup.setModal(true); |
141 mPopup.setAnchorView(anchorView); | 143 mPopup.setAnchorView(anchorView); |
142 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); | 144 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); |
| 145 |
| 146 int footerHeight = 0; |
| 147 if (footerResourceId != 0) { |
| 148 mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); |
| 149 mPopup.setPromptView(LayoutInflater.from(context).inflate(footerReso
urceId, null)); |
| 150 footerHeight = context.getResources().getDimensionPixelSize( |
| 151 R.dimen.menu_footer_height); |
| 152 } |
143 mPopup.setOnDismissListener(new OnDismissListener() { | 153 mPopup.setOnDismissListener(new OnDismissListener() { |
144 @Override | 154 @Override |
145 public void onDismiss() { | 155 public void onDismiss() { |
146 if (mPopup.getAnchorView() instanceof ImageButton) { | 156 if (mPopup.getAnchorView() instanceof ImageButton) { |
147 ((ImageButton) mPopup.getAnchorView()).setSelected(false); | 157 ((ImageButton) mPopup.getAnchorView()).setSelected(false); |
148 } | 158 } |
149 | 159 |
150 if (mMenuItemEnterAnimator != null) mMenuItemEnterAnimator.cance
l(); | 160 if (mMenuItemEnterAnimator != null) mMenuItemEnterAnimator.cance
l(); |
151 | 161 |
152 mHandler.appMenuDismissed(); | 162 mHandler.appMenuDismissed(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 originalBgDrawable.getPadding(originalPadding); | 210 originalBgDrawable.getPadding(originalPadding); |
201 sizingPadding.top = originalPadding.top; | 211 sizingPadding.top = originalPadding.top; |
202 sizingPadding.bottom = originalPadding.bottom; | 212 sizingPadding.bottom = originalPadding.bottom; |
203 } | 213 } |
204 | 214 |
205 // A List adapter for visible items in the Menu. The first row is added
as a header to the | 215 // A List adapter for visible items in the Menu. The first row is added
as a header to the |
206 // list view. | 216 // list view. |
207 mAdapter = new AppMenuAdapter(this, menuItems, LayoutInflater.from(conte
xt)); | 217 mAdapter = new AppMenuAdapter(this, menuItems, LayoutInflater.from(conte
xt)); |
208 mPopup.setAdapter(mAdapter); | 218 mPopup.setAdapter(mAdapter); |
209 | 219 |
210 setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight, sizin
gPadding); | 220 setMenuHeight( |
| 221 menuItems.size(), visibleDisplayFrame, screenHeight, sizingPaddi
ng, footerHeight); |
211 setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame, sizi
ngPadding); | 222 setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame, sizi
ngPadding); |
212 mPopup.setOnItemClickListener(this); | 223 mPopup.setOnItemClickListener(this); |
213 mPopup.show(); | 224 mPopup.show(); |
214 mPopup.getListView().setItemsCanFocus(true); | 225 mPopup.getListView().setItemsCanFocus(true); |
215 mPopup.getListView().setOnKeyListener(this); | 226 mPopup.getListView().setOnKeyListener(this); |
216 | 227 |
217 mHandler.onMenuVisibilityChanged(true); | 228 mHandler.onMenuVisibilityChanged(true); |
218 | 229 |
219 if (mVerticalFadeDistance > 0) { | 230 if (mVerticalFadeDistance > 0) { |
220 mPopup.getListView().setVerticalFadingEdgeEnabled(true); | 231 mPopup.getListView().setVerticalFadingEdgeEnabled(true); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 } | 343 } |
333 | 344 |
334 /** | 345 /** |
335 * @return The menu instance inside of this class. | 346 * @return The menu instance inside of this class. |
336 */ | 347 */ |
337 @VisibleForTesting | 348 @VisibleForTesting |
338 public Menu getMenuForTest() { | 349 public Menu getMenuForTest() { |
339 return mMenu; | 350 return mMenu; |
340 } | 351 } |
341 | 352 |
342 private void setMenuHeight( | 353 private void setMenuHeight(int numMenuItems, Rect appDimensions, |
343 int numMenuItems, Rect appDimensions, int screenHeight, Rect padding
) { | 354 int screenHeight, Rect padding, int footerHeight) { |
344 assert mPopup.getAnchorView() != null; | 355 assert mPopup.getAnchorView() != null; |
345 View anchorView = mPopup.getAnchorView(); | 356 View anchorView = mPopup.getAnchorView(); |
346 int[] anchorViewLocation = new int[2]; | 357 int[] anchorViewLocation = new int[2]; |
347 anchorView.getLocationOnScreen(anchorViewLocation); | 358 anchorView.getLocationOnScreen(anchorViewLocation); |
348 anchorViewLocation[1] -= appDimensions.top; | 359 anchorViewLocation[1] -= appDimensions.top; |
349 int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight(
) : 0; | 360 int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight(
) : 0; |
350 | 361 |
351 // Set appDimensions.height() for abnormal anchorViewLocation. | 362 // Set appDimensions.height() for abnormal anchorViewLocation. |
352 if (anchorViewLocation[1] > screenHeight) { | 363 if (anchorViewLocation[1] > screenHeight) { |
353 anchorViewLocation[1] = appDimensions.height(); | 364 anchorViewLocation[1] = appDimensions.height(); |
354 } | 365 } |
355 int availableScreenSpace = Math.max(anchorViewLocation[1], | 366 int availableScreenSpace = Math.max(anchorViewLocation[1], |
356 appDimensions.height() - anchorViewLocation[1] - anchorViewImpac
tHeight); | 367 appDimensions.height() - anchorViewLocation[1] - anchorViewImpac
tHeight); |
357 | 368 |
358 availableScreenSpace -= padding.bottom; | 369 availableScreenSpace -= padding.bottom + footerHeight; |
359 if (mIsByHardwareButton) availableScreenSpace -= padding.top; | 370 if (mIsByHardwareButton) availableScreenSpace -= padding.top; |
360 | 371 |
361 int numCanFit = availableScreenSpace / (mItemRowHeight + mItemDividerHei
ght); | 372 int numCanFit = availableScreenSpace / (mItemRowHeight + mItemDividerHei
ght); |
362 | 373 |
363 // Fade out the last item if we cannot fit all items. | 374 // Fade out the last item if we cannot fit all items. |
364 if (numCanFit < numMenuItems) { | 375 if (numCanFit < numMenuItems) { |
365 int spaceForFullItems = numCanFit * (mItemRowHeight + mItemDividerHe
ight); | 376 int spaceForFullItems = numCanFit * (mItemRowHeight + mItemDividerHe
ight); |
366 int spaceForPartialItem = (int) (LAST_ITEM_SHOW_FRACTION * mItemRowH
eight); | 377 int spaceForPartialItem = (int) (LAST_ITEM_SHOW_FRACTION * mItemRowH
eight); |
367 // Determine which item needs hiding. | 378 // Determine which item needs hiding. |
368 if (spaceForFullItems + spaceForPartialItem < availableScreenSpace)
{ | 379 if (spaceForFullItems + spaceForPartialItem < availableScreenSpace)
{ |
(...skipping 22 matching lines...) Expand all Loading... |
391 } else { | 402 } else { |
392 builder.with((Animator) animatorObject); | 403 builder.with((Animator) animatorObject); |
393 } | 404 } |
394 } | 405 } |
395 } | 406 } |
396 | 407 |
397 mMenuItemEnterAnimator.addListener(mAnimationHistogramRecorder); | 408 mMenuItemEnterAnimator.addListener(mAnimationHistogramRecorder); |
398 mMenuItemEnterAnimator.start(); | 409 mMenuItemEnterAnimator.start(); |
399 } | 410 } |
400 } | 411 } |
OLD | NEW |