OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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.TimeAnimator; | 7 import android.animation.TimeAnimator; |
8 import android.annotation.SuppressLint; | 8 import android.annotation.SuppressLint; |
9 import android.app.Activity; | 9 import android.app.Activity; |
10 import android.content.res.Resources; | 10 import android.content.res.Resources; |
11 import android.graphics.Point; | 11 import android.graphics.Point; |
12 import android.graphics.Rect; | 12 import android.graphics.Rect; |
13 import android.os.SystemClock; | 13 import android.os.SystemClock; |
14 import android.util.Log; | 14 import android.util.Log; |
15 import android.view.Display; | 15 import android.view.Display; |
16 import android.view.MotionEvent; | 16 import android.view.MotionEvent; |
17 import android.view.Surface; | 17 import android.view.Surface; |
18 import android.view.View; | 18 import android.view.View; |
19 import android.view.View.OnTouchListener; | 19 import android.view.View.OnTouchListener; |
20 import android.view.ViewConfiguration; | 20 import android.view.ViewConfiguration; |
21 import android.view.ViewParent; | 21 import android.view.ViewParent; |
22 import android.widget.ImageButton; | |
23 import android.widget.LinearLayout; | |
22 import android.widget.ListPopupWindow; | 24 import android.widget.ListPopupWindow; |
23 import android.widget.ListView; | 25 import android.widget.ListView; |
24 | 26 |
25 import org.chromium.chrome.R; | 27 import org.chromium.chrome.R; |
26 import org.chromium.chrome.browser.UmaBridge; | 28 import org.chromium.chrome.browser.UmaBridge; |
27 | 29 |
28 import java.util.ArrayList; | 30 import java.util.ArrayList; |
29 | 31 |
30 /** | 32 /** |
31 * Handles the drag touch events on AppMenu that start from the menu button. | 33 * Handles the drag touch events on AppMenu that start from the menu button. |
(...skipping 29 matching lines...) Expand all Loading... | |
61 private int mDragScrollOffsetRounded; | 63 private int mDragScrollOffsetRounded; |
62 private volatile float mDragScrollingVelocity; | 64 private volatile float mDragScrollingVelocity; |
63 private volatile float mLastTouchX; | 65 private volatile float mLastTouchX; |
64 private volatile float mLastTouchY; | 66 private volatile float mLastTouchY; |
65 private float mTopTouchMovedBound; | 67 private float mTopTouchMovedBound; |
66 private float mBottomTouchMovedBound; | 68 private float mBottomTouchMovedBound; |
67 private boolean mIsDownScrollable; | 69 private boolean mIsDownScrollable; |
68 private boolean mIsUpScrollable; | 70 private boolean mIsUpScrollable; |
69 private boolean mIsByHardwareButton; | 71 private boolean mIsByHardwareButton; |
70 private int mCurrentScreenRotation = -1; | 72 private int mCurrentScreenRotation = -1; |
73 private final int mItemRowHeight; | |
71 | 74 |
72 // These are used in a function locally, but defined here to avoid heap allo cation on every | 75 // These are used in a function locally, but defined here to avoid heap allo cation on every |
73 // touch event. | 76 // touch event. |
74 private final Rect mScreenVisibleRect = new Rect(); | 77 private final Rect mScreenVisibleRect = new Rect(); |
75 private final int[] mScreenVisiblePoint = new int[2]; | 78 private final int[] mScreenVisiblePoint = new int[2]; |
76 | 79 |
77 // Sub-UI-controls, backward, forward, bookmark and listView, are getting a touch event first | 80 // Sub-UI-controls, backward, forward, bookmark and listView, are getting a touch event first |
78 // if the app menu is initiated by hardware menu button. For those cases, we need to | 81 // if the app menu is initiated by hardware menu button. For those cases, we need to |
79 // conditionally forward the touch event to our drag scrolling method. | 82 // conditionally forward the touch event to our drag scrolling method. |
80 private final OnTouchListener mDragScrollTouchEventForwarder = new OnTouchLi stener() { | 83 private final OnTouchListener mDragScrollTouchEventForwarder = new OnTouchLi stener() { |
81 @Override | 84 @Override |
82 public boolean onTouch(View view, MotionEvent event) { | 85 public boolean onTouch(View view, MotionEvent event) { |
83 return handleDragging(event); | 86 return handleDragging(event); |
84 } | 87 } |
85 }; | 88 }; |
86 | 89 |
87 AppMenuDragHelper(Activity activity, AppMenu appMenu) { | 90 AppMenuDragHelper(Activity activity, AppMenu appMenu, int itemRowHeight) { |
88 mActivity = activity; | 91 mActivity = activity; |
89 mAppMenu = appMenu; | 92 mAppMenu = appMenu; |
93 mItemRowHeight = itemRowHeight; | |
90 mScaledTouchSlop = ViewConfiguration.get( | 94 mScaledTouchSlop = ViewConfiguration.get( |
91 mActivity.getApplicationContext()).getScaledTouchSlop(); | 95 mActivity.getApplicationContext()).getScaledTouchSlop(); |
92 Resources res = mActivity.getResources(); | 96 Resources res = mActivity.getResources(); |
93 mAutoScrollFullVelocity = res.getDimensionPixelSize(R.dimen.auto_scroll_ full_velocity); | 97 mAutoScrollFullVelocity = res.getDimensionPixelSize(R.dimen.auto_scroll_ full_velocity); |
94 mEdgeSwipeInSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_in_slop) ; | 98 mEdgeSwipeInSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_in_slop) ; |
95 mEdgeSwipeInAdditionalSlop = res.getDimensionPixelSize( | 99 mEdgeSwipeInAdditionalSlop = res.getDimensionPixelSize( |
96 R.dimen.edge_swipe_in_additional_slop); | 100 R.dimen.edge_swipe_in_additional_slop); |
97 mEdgeSwipeOutSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_out_slo p); | 101 mEdgeSwipeOutSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_out_slo p); |
98 // If user is dragging and the popup ListView is too big to display at o nce, | 102 // If user is dragging and the popup ListView is too big to display at o nce, |
99 // mDragScrolling animator scrolls mPopup.getListView() automatically de pending on | 103 // mDragScrolling animator scrolls mPopup.getListView() automatically de pending on |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 | 159 |
156 // We assume that the parent of popup ListView is an instance of View. O therwise, dragging | 160 // We assume that the parent of popup ListView is an instance of View. O therwise, dragging |
157 // from a hardware menu button won't work. | 161 // from a hardware menu button won't work. |
158 ViewParent listViewParent = popup.getListView().getParent(); | 162 ViewParent listViewParent = popup.getListView().getParent(); |
159 if (listViewParent instanceof View) { | 163 if (listViewParent instanceof View) { |
160 ((View) listViewParent).setOnTouchListener(mDragScrollTouchEventForw arder); | 164 ((View) listViewParent).setOnTouchListener(mDragScrollTouchEventForw arder); |
161 } else { | 165 } else { |
162 assert false; | 166 assert false; |
163 } | 167 } |
164 | 168 |
165 if (mAppMenu.isShowingIconRow()) { | |
166 View iconRowView = mAppMenu.getIconRowView(); | |
167 iconRowView.findViewById(R.id.menu_item_back).setOnTouchListener( | |
168 mDragScrollTouchEventForwarder); | |
169 iconRowView.findViewById(R.id.menu_item_forward).setOnTouchListener( | |
170 mDragScrollTouchEventForwarder); | |
171 iconRowView.findViewById(R.id.menu_item_bookmark).setOnTouchListener ( | |
172 mDragScrollTouchEventForwarder); | |
173 | 169 |
174 } | |
Kibeom Kim (inactive)
2014/03/19 22:04:46
not sure dragging from hardware menu button would
Kibeom Kim (inactive)
2014/03/19 22:35:05
-> discussed with Aurimas, it seems the current ha
| |
175 | 170 |
176 if (!isByHardwareButton && startDragging) mDragScrolling.start(); | 171 if (!isByHardwareButton && startDragging) mDragScrolling.start(); |
177 } | 172 } |
178 | 173 |
179 void onDismiss() { | 174 void onDismiss() { |
180 mDragScrolling.cancel(); | 175 mDragScrolling.cancel(); |
181 } | 176 } |
182 | 177 |
183 /** | 178 /** |
184 * This is a hint for adjusting edgeSwipeInSlop. For example. If the touch e vent started | 179 * This is a hint for adjusting edgeSwipeInSlop. For example. If the touch e vent started |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 } | 268 } |
274 } | 269 } |
275 didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction); | 270 didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction); |
276 | 271 |
277 if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) { | 272 if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) { |
278 mAppMenu.dismiss(); | 273 mAppMenu.dismiss(); |
279 } else if (eventActionMasked == MotionEvent.ACTION_MOVE) { | 274 } else if (eventActionMasked == MotionEvent.ACTION_MOVE) { |
280 // Auto scrolling on the top or the bottom of the listView. | 275 // Auto scrolling on the top or the bottom of the listView. |
281 if (listView.getHeight() > 0) { | 276 if (listView.getHeight() > 0) { |
282 float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO, | 277 float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO, |
283 mAppMenu.getItemRowHeight() * 1.2f / listView.getHeight( )); | 278 mItemRowHeight * 1.2f / listView.getHeight()); |
284 float normalizedY = | 279 float normalizedY = |
285 (rawY - getScreenVisibleRect(listView).top) / listView.g etHeight(); | 280 (rawY - getScreenVisibleRect(listView).top) / listView.g etHeight(); |
286 if (mIsUpScrollable && normalizedY < autoScrollAreaRatio) { | 281 if (mIsUpScrollable && normalizedY < autoScrollAreaRatio) { |
287 // Top | 282 // Top |
288 mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f) | 283 mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f) |
289 * mAutoScrollFullVelocity; | 284 * mAutoScrollFullVelocity; |
290 } else if (mIsDownScrollable && normalizedY > 1.0f - autoScrollA reaRatio) { | 285 } else if (mIsDownScrollable && normalizedY > 1.0f - autoScrollA reaRatio) { |
291 // Bottom | 286 // Bottom |
292 mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollA reaRatio + 1.0f) | 287 mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollA reaRatio + 1.0f) |
293 * mAutoScrollFullVelocity; | 288 * mAutoScrollFullVelocity; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 * @param screenX X in screen space coordinate. | 328 * @param screenX X in screen space coordinate. |
334 * @param screenY Y in screen space coordinate. | 329 * @param screenY Y in screen space coordinate. |
335 * @param action Action type to perform, it should be one of ITEM_ACTION_* constants. | 330 * @param action Action type to perform, it should be one of ITEM_ACTION_* constants. |
336 * @return true whether or not a menu item is performed (executed). | 331 * @return true whether or not a menu item is performed (executed). |
337 */ | 332 */ |
338 private boolean menuItemAction(int screenX, int screenY, int action) { | 333 private boolean menuItemAction(int screenX, int screenY, int action) { |
339 ListView listView = mAppMenu.getPopup().getListView(); | 334 ListView listView = mAppMenu.getPopup().getListView(); |
340 | 335 |
341 ArrayList<View> itemViews = new ArrayList<View>(); | 336 ArrayList<View> itemViews = new ArrayList<View>(); |
342 for (int i = 0; i < listView.getChildCount(); ++i) { | 337 for (int i = 0; i < listView.getChildCount(); ++i) { |
343 itemViews.add(listView.getChildAt(i)); | 338 boolean hasImageButtons = false; |
344 } | 339 if (listView.getChildAt(i) instanceof LinearLayout) { |
345 | 340 LinearLayout layout = (LinearLayout) listView.getChildAt(i); |
346 View iconRowView = mAppMenu.getIconRowView(); | 341 for (int j = 0; j < layout.getChildCount(); ++j) { |
347 if (iconRowView != null && mAppMenu.isShowingIconRow()) { | 342 itemViews.add(layout.getChildAt(j)); |
348 itemViews.add(iconRowView.findViewById(R.id.menu_item_back)); | 343 if (layout.getChildAt(j) instanceof ImageButton) hasImageBut tons = true; |
349 itemViews.add(iconRowView.findViewById(R.id.menu_item_forward)); | 344 } |
350 itemViews.add(iconRowView.findViewById(R.id.menu_item_bookmark)); | 345 } |
346 if (!hasImageButtons) itemViews.add(listView.getChildAt(i)); | |
351 } | 347 } |
352 | 348 |
353 boolean didPerformClick = false; | 349 boolean didPerformClick = false; |
354 for (int i = 0; i < itemViews.size(); ++i) { | 350 for (int i = 0; i < itemViews.size(); ++i) { |
355 View itemView = itemViews.get(i); | 351 View itemView = itemViews.get(i); |
356 | 352 |
357 // Skip the icon row that belongs to the listView because that doesn 't really | |
358 // exist as an item. | |
359 int listViewPositionIndex = listView.getFirstVisiblePosition() + i; | |
360 if (mAppMenu.isShowingIconRow() && listViewPositionIndex == 0) conti nue; | |
361 | |
362 boolean shouldPerform = itemView.isEnabled() && itemView.isShown() & & | 353 boolean shouldPerform = itemView.isEnabled() && itemView.isShown() & & |
363 getScreenVisibleRect(itemView).contains(screenX, screenY); | 354 getScreenVisibleRect(itemView).contains(screenX, screenY); |
364 | 355 |
365 switch (action) { | 356 switch (action) { |
366 case ITEM_ACTION_HIGHLIGHT: | 357 case ITEM_ACTION_HIGHLIGHT: |
367 itemView.setPressed(shouldPerform); | 358 itemView.setPressed(shouldPerform); |
368 break; | 359 break; |
369 case ITEM_ACTION_PERFORM: | 360 case ITEM_ACTION_PERFORM: |
370 if (shouldPerform) { | 361 if (shouldPerform) { |
371 if (itemView.getParent() == listView) { | 362 itemView.performClick(); |
372 listView.performItemClick(itemView, listViewPosition Index, 0); | |
373 } else { | |
374 itemView.performClick(); | |
375 } | |
376 didPerformClick = true; | 363 didPerformClick = true; |
377 } | 364 } |
378 break; | 365 break; |
379 case ITEM_ACTION_CLEAR_HIGHLIGHT_ALL: | 366 case ITEM_ACTION_CLEAR_HIGHLIGHT_ALL: |
380 itemView.setPressed(false); | 367 itemView.setPressed(false); |
381 break; | 368 break; |
382 default: | 369 default: |
383 assert false; | 370 assert false; |
384 break; | 371 break; |
385 } | 372 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 // If it's right after we had hardware menu button UP event, use lar ge edgeSwipeInSlop, | 442 // If it's right after we had hardware menu button UP event, use lar ge edgeSwipeInSlop, |
456 // Otherwise, use small edgeSwipeInSlop. | 443 // Otherwise, use small edgeSwipeInSlop. |
457 float additionalEdgeSwipeInSlop = ((mHardwareMenuButtonUpTime - even t.getEventTime() | 444 float additionalEdgeSwipeInSlop = ((mHardwareMenuButtonUpTime - even t.getEventTime() |
458 + EDGE_SWIPE_IN_ADDITIONAL_SLOP_TIME_MS) * 0.001f) | 445 + EDGE_SWIPE_IN_ADDITIONAL_SLOP_TIME_MS) * 0.001f) |
459 * mEdgeSwipeInAdditionalSlop; | 446 * mEdgeSwipeInAdditionalSlop; |
460 edgeSwipeInSlope += Math.max(0.0f, additionalEdgeSwipeInSlop); | 447 edgeSwipeInSlope += Math.max(0.0f, additionalEdgeSwipeInSlop); |
461 } | 448 } |
462 return edgeSwipeInSlope; | 449 return edgeSwipeInSlope; |
463 } | 450 } |
464 } | 451 } |
OLD | NEW |