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

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 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.overlays.strip;
6
7 import static org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Ani matableAnimation.createAnimation;
8
9 import android.content.Context;
10 import android.graphics.RectF;
11
12 import com.google.android.apps.chrome.R;
13
14 import org.chromium.base.VisibleForTesting;
15 import org.chromium.chrome.browser.Tab;
16 import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation;
17 import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animatable ;
18 import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animation;
19 import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
20 import org.chromium.chrome.browser.compositor.layouts.components.CompositorButto n;
21 import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
22 import org.chromium.chrome.browser.compositor.overlays.strip.TabLoadTracker.TabL oadTrackerCallback;
23 import org.chromium.chrome.browser.util.MathUtils;
24 import org.chromium.ui.base.LocalizationUtils;
25 import org.chromium.ui.resources.AndroidResourceType;
26 import org.chromium.ui.resources.LayoutResource;
27 import org.chromium.ui.resources.ResourceManager;
28
29 import java.util.List;
30
31 /**
32 * {@link StripLayoutTab} is used to keep track of the strip position and render ing information for
33 * a particular tab so it can draw itself onto the GL canvas.
34 */
35 public class StripLayoutTab
36 implements ChromeAnimation.Animatable<StripLayoutTab.Property>, VirtualV iew {
37 /**
38 * Animatable properties that can be used with a {@link ChromeAnimation.Anim atable} on a
39 * {@link StripLayoutTab}.
40 */
41 enum Property {
42 X_OFFSET,
43 Y_OFFSET,
44 WIDTH,
45 }
46
47 // Behavior Constants
48 private static final float VISIBILITY_FADE_CLOSE_BUTTON_PERCENTAGE = 0.99f;
49
50 // Animation/Timer Constants
51 private static final int ANIM_TAB_CLOSE_BUTTON_FADE_MS = 150;
52
53 // Close button width
54 private static final int CLOSE_BUTTON_WIDTH_DP = 36;
55
56 private int mId = Tab.INVALID_TAB_ID;
57
58 private final TabLoadTracker mLoadTracker;
59 private final LayoutRenderHost mRenderHost;
60
61 private boolean mVisible = true;
62 private boolean mIsDying = false;
63 private boolean mCanShowCloseButton = true;
64 private boolean mIncognito;
65 private float mContentOffsetX;
66 private float mVisiblePercentage = 1.f;
67 private String mAccessibilityDescription;
68
69 // Ideal intermediate parameters
70 private float mIdealX;
71 private float mTabOffsetX;
72 private float mTabOffsetY;
73
74 // Actual draw parameters
75 private float mDrawX;
76 private float mDrawY;
77 private float mWidth;
78 private float mHeight;
79 private RectF mTouchTarget = new RectF();
80
81 private boolean mShowingCloseButton = true;
82
83 private final CompositorButton mCloseButton;
84
85 // Content Animations
86 private ChromeAnimation<Animatable<?>> mContentAnimations;
87
88 private float mLoadingSpinnerRotationDegrees = 0.0f;
89
90 // Preallocated
91 private final RectF mClosePlacement = new RectF();
92
93 /**
94 * Create a {@link StripLayoutTab} that represents the {@link Tab} with an i d of
95 * {@code id}.
96 *
97 * @param context An Android context for accessing system resources.
98 * @param id The id of the {@link Tab} to visually represent.
99 * @param loadTrackerCallback The {@link TabLoadTrackerCallback} to be notif ied of loading state
100 * changes.
101 * @param renderHost The {@link LayoutRenderHost}.
102 * @param incogntio Whether or not this layout tab is icognito.
103 */
104 public StripLayoutTab(Context context, int id, TabLoadTrackerCallback loadTr ackerCallback,
105 LayoutRenderHost renderHost, boolean incognito) {
106 mId = id;
107 mLoadTracker = new TabLoadTracker(id, loadTrackerCallback);
108 mRenderHost = renderHost;
109 mIncognito = incognito;
110 mCloseButton = new CompositorButton(context, 0, 0);
111 mCloseButton.setResources(R.drawable.btn_tab_close_normal, R.drawable.bt n_tab_close_pressed,
112 R.drawable.btn_tab_close_white_normal, R.drawable.btn_tab_close_ white_pressed);
113 mCloseButton.setIncognito(mIncognito);
114 mCloseButton.setBounds(getCloseRect());
115 mCloseButton.setClickSlop(0.f);
116 String description =
117 context.getResources().getString(R.string.accessibility_tabstrip _btn_close_tab);
118 mCloseButton.setAccessibilityDescription(description, description);
119 }
120
121 /**
122 * Get a list of virtual views for accessibility events.
123 *
124 * @param views A List to populate with virtual views.
125 */
126 public void getVirtualViews(List<VirtualView> views) {
127 if (mShowingCloseButton) views.add(mCloseButton);
128 views.add(this);
129 }
130
131 /**
132 * @param description A description for accessibility events.
133 */
134 public void setAccessibilityDescription(String description) {
135 mAccessibilityDescription = description;
136 }
137
138 @Override
139 public String getAccessibilityDescription() {
140 return mAccessibilityDescription;
141 }
142
143 @Override
144 public void getTouchTarget(RectF target) {
145 target.set(mTouchTarget);
146 }
147
148 @Override
149 public boolean checkClicked(float x, float y) {
150 return mTouchTarget.contains(x, y);
151 }
152
153 /**
154 * @return The id of the {@link Tab} this {@link StripLayoutTab} represents.
155 */
156 public int getId() {
157 return mId;
158 }
159
160 /**
161 * @param foreground Whether or not this tab is a foreground tab.
162 * @return The Android resource that represents the tab background.
163 */
164 public int getResourceId(boolean foreground) {
165 if (foreground) {
166 return mIncognito ? R.drawable.bg_tabstrip_incognito_tab : R.drawabl e.bg_tabstrip_tab;
167 }
168 return mIncognito ? R.drawable.bg_tabstrip_incognito_background_tab
169 : R.drawable.bg_tabstrip_background_tab;
170 }
171
172 /**
173 * @param visible Whether or not this {@link StripLayoutTab} should be drawn .
174 */
175 public void setVisible(boolean visible) {
176 mVisible = visible;
177 }
178
179 /**
180 * @return Whether or not this {@link StripLayoutTab} should be drawn.
181 */
182 public boolean isVisible() {
183 return mVisible;
184 }
185
186 /**
187 * Mark this tab as in the process of dying. This lets us track which tabs are dead after
188 * animations.
189 * @param isDying Whether or not the tab is dying.
190 */
191 public void setIsDying(boolean isDying) {
192 mIsDying = isDying;
193 }
194
195 /**
196 * @return Whether or not the tab is dying.
197 */
198 public boolean isDying() {
199 return mIsDying;
200 }
201
202 /**
203 * @return Whether or not this tab should be visually represented as loading .
204 */
205 public boolean isLoading() {
206 return mLoadTracker.isLoading();
207 }
208
209 /**
210 * @return The rotation of the loading spinner in degrees.
211 */
212 public float getLoadingSpinnerRotation() {
213 return mLoadingSpinnerRotationDegrees;
214 }
215
216 /**
217 * Additive spinner rotation update.
218 * @param rotation The amount to rotate the spinner by in degrees.
219 */
220 public void addLoadingSpinnerRotation(float rotation) {
221 mLoadingSpinnerRotationDegrees = (mLoadingSpinnerRotationDegrees + rotat ion) % 1080;
222 }
223
224 /**
225 * Called when this tab has started loading.
226 */
227 public void pageLoadingStarted() {
228 mLoadTracker.pageLoadingStarted();
229 }
230
231 /**
232 * Called when this tab has finished loading.
233 */
234 public void pageLoadingFinished() {
235 mLoadTracker.pageLoadingFinished();
236 }
237
238 /**
239 * Called when this tab has started loading resources.
240 */
241 public void loadingStarted() {
242 mLoadTracker.loadingStarted();
243 }
244
245 /**
246 * Called when this tab has finished loading resources.
247 */
248 public void loadingFinished() {
249 mLoadTracker.loadingFinished();
250 }
251
252 /**
253 * @param offsetX How far to offset the tab content (favicons and title).
254 */
255 public void setContentOffsetX(float offsetX) {
256 mContentOffsetX = MathUtils.clamp(offsetX, 0.f, mWidth);
257 }
258
259 /**
260 * @return How far to offset the tab content (favicons and title).
261 */
262 public float getContentOffsetX() {
263 return mContentOffsetX;
264 }
265
266 /**
267 * @param visiblePercentage How much of the tab is visible (not overlapped b y other tabs).
268 */
269 public void setVisiblePercentage(float visiblePercentage) {
270 mVisiblePercentage = visiblePercentage;
271 checkCloseButtonVisibility(true);
272 }
273
274 /**
275 * @return How much of the tab is visible (not overlapped by other tabs).
276 */
277 @VisibleForTesting
278 public float getVisiblePercentage() {
279 return mVisiblePercentage;
280 }
281
282 /**
283 * @param show Whether or not the close button is allowed to be shown.
284 */
285 public void setCanShowCloseButton(boolean show) {
286 mCanShowCloseButton = show;
287 checkCloseButtonVisibility(true);
288 }
289
290 /**
291 * @param x The actual position in the strip, taking into account stacking, scrolling, etc.
292 */
293 public void setDrawX(float x) {
294 mCloseButton.setX(mCloseButton.getX() + (x - mDrawX));
295 mDrawX = x;
296 mTouchTarget.left = mDrawX;
297 mTouchTarget.right = mDrawX + mWidth;
298 }
299
300 /**
301 * @return The actual position in the strip, taking into account stacking, s crolling, etc.
302 */
303 public float getDrawX() {
304 return mDrawX;
305 }
306
307 /**
308 * @param y The vertical position for the tab.
309 */
310 public void setDrawY(float y) {
311 mCloseButton.setY(mCloseButton.getY() + (y - mDrawY));
312 mDrawY = y;
313 mTouchTarget.top = mDrawY;
314 mTouchTarget.bottom = mDrawY + mHeight;
315 }
316
317 /**
318 * @return The vertical position for the tab.
319 */
320 public float getDrawY() {
321 return mDrawY;
322 }
323
324 /**
325 * @param width The width of the tab.
326 */
327 public void setWidth(float width) {
328 mWidth = width;
329 resetCloseRect();
330 mTouchTarget.right = mDrawX + mWidth;
331 }
332
333 /**
334 * @return The width of the tab.
335 */
336 public float getWidth() {
337 return mWidth;
338 }
339
340 /**
341 * @param height The height of the tab.
342 */
343 public void setHeight(float height) {
344 mHeight = height;
345 resetCloseRect();
346 mTouchTarget.bottom = mDrawY + mHeight;
347 }
348
349 /**
350 * @return The height of the tab.
351 */
352 public float getHeight() {
353 return mHeight;
354 }
355
356 /**
357 * @param closePressed The current pressed state of the attached button.
358 */
359 public void setClosePressed(boolean closePressed) {
360 mCloseButton.setPressed(closePressed);
361 }
362
363 /**
364 * @return The current pressed state of the close button.
365 */
366 public boolean getClosePressed() {
367 return mCloseButton.isPressed();
368 }
369
370 /**
371 * @return The close button for this tab.
372 */
373 public CompositorButton getCloseButton() {
374 return mCloseButton;
375 }
376
377 /**
378 * This represents how much this tab's width should be counted when position ing tabs in the
379 * stack. As tabs close or open, their width weight is increased. They vis ually take up
380 * the same amount of space but the other tabs will smoothly move out of the way to make room.
381 * @return The weight from 0 to 1 that the width of this tab should have on the stack.
382 */
383 public float getWidthWeight() {
384 return MathUtils.clamp(1.f - mDrawY / mHeight, 0.f, 1.f);
385 }
386
387 /**
388 * @param x The x position of the position to test.
389 * @param y The y position of the position to test.
390 * @return Whether or not {@code x} and {@code y} is over the close button f or this tab and
391 * if the button can be clicked.
392 */
393 public boolean checkCloseHitTest(float x, float y) {
394 return mShowingCloseButton ? mCloseButton.checkClicked(x, y) : false;
395 }
396
397 /**
398 * This is used to help calculate the tab's position and is not used for ren dering.
399 * @param offsetX The offset of the tab (used for drag and drop, slide anima ting, etc).
400 */
401 public void setOffsetX(float offsetX) {
402 mTabOffsetX = offsetX;
403 }
404
405 /**
406 * This is used to help calculate the tab's position and is not used for ren dering.
407 * @return The offset of the tab (used for drag and drop, slide animating, e tc).
408 */
409 public float getOffsetX() {
410 return mTabOffsetX;
411 }
412
413 /**
414 * This is used to help calculate the tab's position and is not used for ren dering.
415 * @param x The ideal position, in an infinitely long strip, of this tab.
416 */
417 public void setIdealX(float x) {
418 mIdealX = x;
419 }
420
421 /**
422 * This is used to help calculate the tab's position and is not used for ren dering.
423 * @return The ideal position, in an infinitely long strip, of this tab.
424 */
425 public float getIdealX() {
426 return mIdealX;
427 }
428
429 /**
430 * This is used to help calculate the tab's position and is not used for ren dering.
431 * @param offsetY The vertical offset of the tab.
432 */
433 public void setOffsetY(float offsetY) {
434 mTabOffsetY = offsetY;
435 }
436
437 /**
438 * This is used to help calculate the tab's position and is not used for ren dering.
439 * @return The vertical offset of the tab.
440 */
441 public float getOffsetY() {
442 return mTabOffsetY;
443 }
444
445 private void startAnimation(Animation<Animatable<?>> animation, boolean fini shPrevious) {
446 if (finishPrevious) finishAnimation();
447
448 if (mContentAnimations == null) {
449 mContentAnimations = new ChromeAnimation<Animatable<?>>();
450 }
451
452 mContentAnimations.add(animation);
453 }
454
455 /**
456 * Finishes any content animations currently owned and running on this Strip LayoutTab.
457 */
458 public void finishAnimation() {
459 if (mContentAnimations == null) return;
460
461 mContentAnimations.updateAndFinish();
462 mContentAnimations = null;
463 }
464
465 /**
466 * @return Whether or not there are any content animations running on this S tripLayoutTab.
467 */
468 public boolean isAnimating() {
469 return mContentAnimations != null;
470 }
471
472 /**
473 * Updates any content animations on this StripLayoutTab.
474 * @param time The current time of the app in ms.
475 * @param jumpToEnd Whether or not to force any current animations to end.
476 * @return Whether or not animations are done.
477 */
478 public boolean onUpdateAnimation(long time, boolean jumpToEnd) {
479 if (mContentAnimations == null) return true;
480
481 boolean finished = true;
482 if (jumpToEnd) {
483 finished = mContentAnimations.finished();
484 } else {
485 finished = mContentAnimations.update(time);
486 }
487
488 if (jumpToEnd || finished) finishAnimation();
489
490 return finished;
491 }
492
493 @Override
494 public void setProperty(Property prop, float val) {
495 switch (prop) {
496 case X_OFFSET:
497 setOffsetX(val);
498 break;
499 case Y_OFFSET:
500 setOffsetY(val);
501 break;
502 case WIDTH:
503 setWidth(val);
504 break;
505 }
506 }
507
508 private void resetCloseRect() {
509 RectF closeRect = getCloseRect();
510 mCloseButton.setWidth(closeRect.width());
511 mCloseButton.setHeight(closeRect.height());
512 mCloseButton.setX(closeRect.left);
513 mCloseButton.setY(closeRect.top);
514 }
515
516 private RectF getCloseRect() {
517 if (!LocalizationUtils.isLayoutRtl()) {
518 mClosePlacement.left = getWidth() - CLOSE_BUTTON_WIDTH_DP;
519 mClosePlacement.right = mClosePlacement.left + CLOSE_BUTTON_WIDTH_DP ;
520 } else {
521 mClosePlacement.left = 0;
522 mClosePlacement.right = CLOSE_BUTTON_WIDTH_DP;
523 }
524
525 mClosePlacement.top = 0;
526 mClosePlacement.bottom = getHeight();
527
528 float xOffset = 0;
529 ResourceManager manager = mRenderHost.getResourceManager();
530 if (manager != null) {
531 LayoutResource resource =
532 manager.getResource(AndroidResourceType.STATIC, getResourceI d(false));
533 if (resource != null) {
534 xOffset = LocalizationUtils.isLayoutRtl()
535 ? resource.getPadding().left
536 : -(resource.getBitmapSize().width() - resource.getPaddi ng().right);
537 }
538 }
539
540 mClosePlacement.offset(getDrawX() + xOffset, getDrawY());
541 return mClosePlacement;
542 }
543
544 // TODO(dtrainor): Don't animate this if we're selecting or deselecting this tab.
545 private void checkCloseButtonVisibility(boolean animate) {
546 boolean shouldShow =
547 mCanShowCloseButton && mVisiblePercentage > VISIBILITY_FADE_CLOS E_BUTTON_PERCENTAGE;
548
549 if (shouldShow != mShowingCloseButton) {
550 float opacity = shouldShow ? 1.f : 0.f;
551 if (animate) {
552 startAnimation(buildCloseButtonOpacityAnimation(opacity), true);
553 } else {
554 mCloseButton.setOpacity(opacity);
555 }
556 mShowingCloseButton = shouldShow;
557 if (!mShowingCloseButton) mCloseButton.setPressed(false);
558 }
559 }
560
561 private Animation<Animatable<?>> buildCloseButtonOpacityAnimation(float fina lOpacity) {
562 return createAnimation(mCloseButton, CompositorButton.Property.OPACITY,
563 mCloseButton.getOpacity(), finalOpacity, ANIM_TAB_CLOSE_BUTTON_F ADE_MS, 0, false,
564 ChromeAnimation.getLinearInterpolator());
565 }
566 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698