Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java

Issue 987883002: Upstream Layout.java and associated files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move to SuppressFBWarnings from findbugs_exclude.xml Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.compositor.bottombar.contextualsearch;
6
7 import android.content.Context;
8 import android.os.Handler;
9
10 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
11 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDe legate;
12
13 /**
14 * Controls the Contextual Search Panel.
15 */
16 public class ContextualSearchPanel extends ContextualSearchPanelAnimation
17 implements ContextualSearchPanelDelegate {
18
19 /**
20 * State of the Contextual Search Panel.
21 */
22 public static enum PanelState {
23 UNDEFINED,
24 CLOSED,
25 PEEKED,
26 PROMO,
27 EXPANDED,
28 MAXIMIZED;
29 }
30
31 /**
32 * The reason for a change in the Contextual Search Panel's state.
33 */
34 public static enum StateChangeReason {
35 UNKNOWN,
36 RESET,
37 BACK_PRESS,
38 TEXT_SELECT_TAP,
39 TEXT_SELECT_LONG_PRESS,
40 INVALID_SELECTION,
41 BASE_PAGE_TAP,
42 BASE_PAGE_SCROLL,
43 SEARCH_BAR_TAP,
44 SERP_NAVIGATION,
45 TAB_PROMOTION,
46 CLICK,
47 SWIPE,
48 FLING,
49 OPTIN,
50 OPTOUT;
51 }
52
53 /**
54 * The delay after which the hide progress will be hidden.
55 */
56 private static final long HIDE_PROGRESS_BAR_DELAY = 1000 / 60 * 4;
57
58 /**
59 * The initial height of the Contextual Search Panel.
60 */
61 private float mInitialPanelHeight;
62
63 /**
64 * Whether the Panel should be promoted to a new tab after being maximized.
65 */
66 private boolean mShouldPromoteToTabAfterMaximizing;
67
68 /**
69 * Whether a touch gesture has been detected.
70 */
71 private boolean mHasDetectedTouchGesture;
72
73 /**
74 * Whether the search content view has been touched.
75 */
76 private boolean mHasSearchContentViewBeenTouched;
77
78 /**
79 * The {@link ContextualSearchPanelHost} used to communicate with the suppor ted layout.
80 */
81 private ContextualSearchPanelHost mSearchPanelHost;
82
83 /**
84 * The object for handling global Contextual Search management duties
85 */
86 private ContextualSearchManagementDelegate mManagementDelegate;
87
88 // ========================================================================= ===================
89 // Constructor
90 // ========================================================================= ===================
91
92 /**
93 * @param context The current Android {@link Context}.
94 * @param updateHost The {@link LayoutUpdateHost} used to request updates in the Layout.
95 */
96 public ContextualSearchPanel(Context context, LayoutUpdateHost updateHost) {
97 super(context, updateHost);
98 }
99
100 // ========================================================================= ===================
101 // Layout Integration
102 // ========================================================================= ===================
103
104 /**
105 * Sets the {@ContextualSearchPanelHost} used to communicate with the suppor ted layout.
106 * @param host The {@ContextualSearchPanelHost}.
107 */
108 public void setHost(ContextualSearchPanelHost host) {
109 mSearchPanelHost = host;
110 }
111
112 // ========================================================================= ===================
113 // Contextual Search Manager Integration
114 // ========================================================================= ===================
115
116 /**
117 * Sets the {@code ContextualSearchManagementDelegate} associated with this Layout.
118 * @param delegate The {@code ContextualSearchManagementDelegate}.
119 */
120 public void setManagementDelegate(ContextualSearchManagementDelegate delegat e) {
121 mManagementDelegate = delegate;
122 }
123
124 /**
125 * @return The {@code ContextualSearchManagementDelegate} associated with th is Layout.
126 */
127 public ContextualSearchManagementDelegate getManagementDelegate() {
128 return mManagementDelegate;
129 }
130
131 /**
132 * Sets the visibility of the Search Content View.
133 * @param isVisible True to make it visible.
134 */
135 public void setSearchContentViewVisibility(boolean isVisible) {
136 if (mManagementDelegate != null) {
137 mManagementDelegate.setSearchContentViewVisibility(isVisible);
138 }
139 }
140
141 // ========================================================================= ===================
142 // Generic Event Handling
143 // ========================================================================= ===================
144
145 /**
146 * Handles the beginning of the swipe gesture.
147 */
148 public void handleSwipeStart() {
149 if (animationIsRunning()) {
150 cancelAnimation(this, Property.PANEL_HEIGHT);
151 }
152
153 mHasDetectedTouchGesture = false;
154 mInitialPanelHeight = getHeight();
155 }
156
157 /**
158 * Handles the movement of the swipe gesture.
159 *
160 * @param ty The movement's total displacement in dps.
161 */
162 public void handleSwipeMove(float ty) {
163 if (ty > 0 && getPanelState() == PanelState.MAXIMIZED) {
164 // Resets the Search Content View scroll position when swiping the P anel down
165 // after being maximized.
166 mManagementDelegate.resetSearchContentViewScroll();
167 }
168
169 // Negative ty value means an upward movement so subtracting ty means ex panding the panel.
170 setClampedPanelHeight(mInitialPanelHeight - ty);
171 requestUpdate();
172 }
173
174 /**
175 * Handles the end of the swipe gesture.
176 */
177 public void handleSwipeEnd() {
178 // This method will be called after handleFling() and handleClick()
179 // methods because we also need to track down the onUpOrCancel()
180 // action from the Layout. Therefore the animation to the nearest
181 // PanelState should only happen when no other gesture has been
182 // detected.
183 if (!mHasDetectedTouchGesture) {
184 mHasDetectedTouchGesture = true;
185 animateToNearestState();
186 }
187 }
188
189 /**
190 * Handles the fling gesture.
191 *
192 * @param velocity The velocity of the gesture in dps per second.
193 */
194 public void handleFling(float velocity) {
195 mHasDetectedTouchGesture = true;
196 animateToProjectedState(velocity);
197 }
198
199 /**
200 * Handles the click gesture.
201 *
202 * @param time The timestamp of the gesture.
203 * @param x The x coordinate of the gesture.
204 * @param y The y coordinate of the gesture.
205 */
206 public void handleClick(long time, float x, float y) {
207 mHasDetectedTouchGesture = true;
208 if (isYCoordinateInsideBasePage(y)) {
209 closePanel(StateChangeReason.BASE_PAGE_TAP, true);
210 } else if (isYCoordinateInsideSearchBar(y)) {
211 // TODO(pedrosimonetti): handle click in the close button here.
212 if (isPeeking()) {
213 if (mManagementDelegate.isRunningInCompatibilityMode()) {
214 mManagementDelegate.openResolvedSearchUrlInNewTab();
215 } else {
216 expandPanel(StateChangeReason.SEARCH_BAR_TAP);
217 }
218 } else if (isExpanded()) {
219 peekPanel(StateChangeReason.SEARCH_BAR_TAP);
220 } else if (isMaximized()) {
221 mManagementDelegate.promoteToTab(true);
222 }
223 }
224 }
225
226 // ========================================================================= ===================
227 // Gesture Event helpers
228 // ========================================================================= ===================
229
230 /**
231 * @param y The y coordinate in dp.
232 * @return Whether the given |y| coordinate is inside the Search Bar area.
233 */
234 public boolean isYCoordinateInsideSearchBar(float y) {
235 return !isYCoordinateInsideBasePage(y) && !isYCoordinateInsideSearchCont entView(y);
236 }
237
238 /**
239 * @param y The y coordinate in dp.
240 * @return Whether the given |y| coordinate is inside the Search Content
241 * View area.
242 */
243 public boolean isYCoordinateInsideSearchContentView(float y) {
244 return y > getSearchContentViewOffsetY();
245 }
246
247 /**
248 * @return The vertical offset of the Search Content View in dp.
249 */
250 public float getSearchContentViewOffsetY() {
251 return getOffsetY() + getSearchBarHeight();
252 }
253
254 /**
255 * @param y The y coordinate in dp.
256 * @return Whether the given |y| coordinate is inside the Base Page area.
257 */
258 private boolean isYCoordinateInsideBasePage(float y) {
259 return y < getOffsetY();
260 }
261
262 /**
263 * @return Whether the Panel is in its expanded state.
264 */
265 protected boolean isExpanded() {
266 return doesPanelHeightMatchState(PanelState.EXPANDED);
267 }
268
269 /**
270 * Acknowledges that there was a touch in the search content view, though no immediate action
271 * needs to be taken.
272 */
273 public void onTouchSearchContentViewAck() {
274 mHasSearchContentViewBeenTouched = true;
275 }
276
277 // ========================================================================= ===================
278 // Animation Handling
279 // ========================================================================= ===================
280
281 @Override
282 protected void onAnimationFinished() {
283 super.onAnimationFinished();
284
285 if (shouldHideContextualSearchLayout()) {
286 if (mSearchPanelHost != null) {
287 mSearchPanelHost.hideLayout(false);
288 }
289 if (getPanelState() == PanelState.CLOSED) {
290 mManagementDelegate.dismissContextualSearchBar();
291 }
292 }
293
294 if (mShouldPromoteToTabAfterMaximizing && getPanelState() == PanelState. MAXIMIZED) {
295 mShouldPromoteToTabAfterMaximizing = false;
296 mManagementDelegate.promoteToTab(false);
297 }
298 }
299
300 /**
301 * Whether the Contextual Search Layout should be hidden.
302 *
303 * @return Whether the Contextual Search Layout should be hidden.
304 */
305 private boolean shouldHideContextualSearchLayout() {
306 final PanelState state = getPanelState();
307
308 return (state == PanelState.PEEKED || state == PanelState.CLOSED)
309 && getHeight() == getPanelHeightFromState(state);
310 }
311
312 // ========================================================================= ===================
313 // Panel Delegate
314 // ========================================================================= ===================
315
316 @Override
317 public boolean isShowing() {
318 // NOTE(pedrosimonetti): exposing superclass method to the interface.
319 return super.isShowing();
320 }
321
322 @Override
323 public boolean isPeeking() {
324 return doesPanelHeightMatchState(PanelState.PEEKED);
325 }
326
327 @Override
328 public void maximizePanelThenPromoteToTab(StateChangeReason reason) {
329 mShouldPromoteToTabAfterMaximizing = true;
330 maximizePanel(reason);
331 }
332
333 @Override
334 public void maximizePanelThenPromoteToTab(StateChangeReason reason, long dur ation) {
335 mShouldPromoteToTabAfterMaximizing = true;
336 animatePanelToState(PanelState.MAXIMIZED, reason, duration);
337 }
338
339 @Override
340 public void peekPanel(StateChangeReason reason) {
341 // NOTE(pedrosimonetti): exposing superclass method to the interface.
342 super.peekPanel(reason);
343
344 if (getPanelState() == PanelState.CLOSED || getPanelState() == PanelStat e.PEEKED) {
345 mHasSearchContentViewBeenTouched = false;
346 }
347 }
348
349 @Override
350 public void closePanel(StateChangeReason reason, boolean animate) {
351 // If the close action is animated, the Layout will be hidden when
352 // the animation is finished, so we should only hide the Layout
353 // here when not animating.
354 if (!animate && mSearchPanelHost != null) {
355 mSearchPanelHost.hideLayout(true);
356 }
357 mHasSearchContentViewBeenTouched = false;
358
359 super.closePanel(reason, animate);
360 }
361
362 @Override
363 public void updateBasePageSelectionYPx(float y) {
364 // NOTE(pedrosimonetti): exposing superclass method to the interface.
365 super.updateBasePageSelectionYPx(y);
366 }
367
368 @Override
369 public void setPromoContentHeight(float height) {
370 // NOTE(pedrosimonetti): exposing superclass method to the interface.
371 super.setPromoContentHeight(height);
372 }
373
374 @Override
375 public void setShouldHidePromoHeader(boolean shouldHidePromoHeader) {
376 // NOTE(pedrosimonetti): exposing superclass method to the interface.
377 super.setShouldHidePromoHeader(shouldHidePromoHeader);
378 }
379
380 @Override
381 public void animateAfterFirstRunSuccess() {
382 // NOTE(pedrosimonetti): exposing superclass method to the interface.
383 super.animateAfterFirstRunSuccess();
384 }
385
386 @Override
387 public void onLoadStarted() {
388 setProgressBarCompletion(0);
389 setProgressBarVisible(true);
390 requestUpdate();
391 }
392
393 @Override
394 public void onLoadStopped() {
395 // Hides the Progress Bar after a delay to make sure it is rendered for at least
396 // a few frames, otherwise its completion won't be visually noticeable.
397 new Handler().postDelayed(new Runnable() {
398 @Override
399 public void run() {
400 setProgressBarVisible(false);
401 requestUpdate();
402 }
403 }, HIDE_PROGRESS_BAR_DELAY);
404 }
405
406 @Override
407 public void onLoadProgressChanged(int progress) {
408 setProgressBarCompletion(progress);
409 requestUpdate();
410 }
411
412 @Override
413 public PanelState getPanelState() {
414 // NOTE(pedrosimonetti): exposing superclass method to the interface.
415 return super.getPanelState();
416 }
417
418 @Override
419 public void setDidSearchInvolvePromo() {
420 // NOTE(pedrosimonetti): exposing superclass method to the interface.
421 super.setDidSearchInvolvePromo();
422 }
423
424 @Override
425 public void setWasSearchContentViewSeen() {
426 // NOTE(pedrosimonetti): exposing superclass method to the interface.
427 super.setWasSearchContentViewSeen();
428 }
429
430 @Override
431 public void setIsPromoActive(boolean shown) {
432 // NOTE(pedrosimonetti): exposing superclass method to the interface.
433 super.setIsPromoActive(shown);
434 }
435
436 @Override
437 public boolean didTouchSearchContentView() {
438 return mHasSearchContentViewBeenTouched;
439 }
440 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698