| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/widget/findinpage/FindResultBar.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/widget/findinpage/FindResultBar.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/widget/findinpage/FindResultBar.java
|
| deleted file mode 100644
|
| index a0e094a54522ce36d39261c830da904595d9de43..0000000000000000000000000000000000000000
|
| --- a/chrome/android/java_staging/src/org/chromium/chrome/browser/widget/findinpage/FindResultBar.java
|
| +++ /dev/null
|
| @@ -1,401 +0,0 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -package org.chromium.chrome.browser.widget.findinpage;
|
| -
|
| -import android.animation.Animator;
|
| -import android.animation.AnimatorListenerAdapter;
|
| -import android.animation.ObjectAnimator;
|
| -import android.annotation.SuppressLint;
|
| -import android.content.Context;
|
| -import android.content.res.Resources;
|
| -import android.graphics.Canvas;
|
| -import android.graphics.Paint;
|
| -import android.graphics.RectF;
|
| -import android.view.Gravity;
|
| -import android.view.MotionEvent;
|
| -import android.view.View;
|
| -import android.view.ViewGroup;
|
| -import android.widget.FrameLayout;
|
| -
|
| -import org.chromium.base.annotations.SuppressFBWarnings;
|
| -import org.chromium.chrome.R;
|
| -import org.chromium.chrome.browser.Tab;
|
| -import org.chromium.chrome.browser.findinpage.FindInPageBridge;
|
| -import org.chromium.chrome.browser.util.MathUtils;
|
| -import org.chromium.ui.UiUtils;
|
| -import org.chromium.ui.base.LocalizationUtils;
|
| -import org.chromium.ui.interpolators.BakedBezierInterpolator;
|
| -
|
| -import java.util.ArrayList;
|
| -import java.util.Arrays;
|
| -import java.util.Collections;
|
| -import java.util.Comparator;
|
| -import java.util.List;
|
| -
|
| -/**
|
| - * The view that shows the positions of the find in page matches and allows scrubbing
|
| - * between the entries.
|
| - */
|
| -class FindResultBar extends View {
|
| - private static final int VISIBILTY_ANIMATION_DURATION_MS = 200;
|
| -
|
| - private final int mBackgroundColor;
|
| - private final int mBackgroundBorderColor;
|
| - private final int mResultColor;
|
| - private final int mResultBorderColor;
|
| - private final int mActiveColor;
|
| - private final int mActiveBorderColor;
|
| -
|
| - private final int mBarTouchWidth;
|
| - private final int mBarDrawWidth;
|
| - private final int mResultMinHeight;
|
| - private final int mActiveMinHeight;
|
| - private final int mBarVerticalPadding;
|
| - private final int mMinGapBetweenStacks;
|
| - private final int mStackedResultHeight;
|
| -
|
| - private final Tab mTab;
|
| - private FindInPageBridge mFindInPageBridge;
|
| -
|
| - int mRectsVersion = -1;
|
| - private RectF[] mMatches = new RectF[0];
|
| - private RectF mActiveMatch;
|
| -
|
| - private ArrayList<Tickmark> mTickmarks = new ArrayList<Tickmark>(0);
|
| - private int mBarHeightForWhichTickmarksWereCached = -1;
|
| -
|
| - private Animator mVisibilityAnimation;
|
| - private boolean mDismissing;
|
| -
|
| - private final Paint mFillPaint;
|
| - private final Paint mStrokePaint;
|
| -
|
| - boolean mWaitingForActivateAck = false;
|
| -
|
| - private static Comparator<RectF> sComparator = new Comparator<RectF>() {
|
| - @Override
|
| - public int compare(RectF a, RectF b) {
|
| - if (a.top != b.top) return a.top > b.top ? 1 : -1;
|
| - if (a.top != b.top) return a.left > b.left ? 1 : -1;
|
| - return 0;
|
| - }
|
| - };
|
| -
|
| - /**
|
| - * Creates an instance of a {@link FindResultBar}.
|
| - * @param context The Context to create this {@link FindResultBar} under.
|
| - * @param tab The Tab containing the ContentView this {@link FindResultBar} will be drawn in.
|
| - */
|
| - public FindResultBar(Context context, Tab tab, FindInPageBridge findInPageBridge) {
|
| - super(context);
|
| -
|
| - Resources res = context.getResources();
|
| - mBackgroundColor = res.getColor(
|
| - R.color.find_result_bar_background_color);
|
| - mBackgroundBorderColor = res.getColor(
|
| - R.color.find_result_bar_background_border_color);
|
| - mResultColor = res.getColor(
|
| - R.color.find_result_bar_result_color);
|
| - mResultBorderColor = res.getColor(
|
| - R.color.find_result_bar_result_border_color);
|
| - mActiveColor = res.getColor(
|
| - R.color.find_result_bar_active_color);
|
| - mActiveBorderColor = res.getColor(
|
| - R.color.find_result_bar_active_border_color);
|
| - mBarTouchWidth = res.getDimensionPixelSize(
|
| - R.dimen.find_result_bar_touch_width);
|
| - mBarDrawWidth = res.getDimensionPixelSize(R.dimen.find_result_bar_draw_width)
|
| - + res.getDimensionPixelSize(R.dimen.find_in_page_separator_width);
|
| - mResultMinHeight = res.getDimensionPixelSize(R.dimen.find_result_bar_result_min_height);
|
| - mActiveMinHeight = res.getDimensionPixelSize(
|
| - R.dimen.find_result_bar_active_min_height);
|
| - mBarVerticalPadding = res.getDimensionPixelSize(
|
| - R.dimen.find_result_bar_vertical_padding);
|
| - mMinGapBetweenStacks = res.getDimensionPixelSize(
|
| - R.dimen.find_result_bar_min_gap_between_stacks);
|
| - mStackedResultHeight = res.getDimensionPixelSize(
|
| - R.dimen.find_result_bar_stacked_result_height);
|
| -
|
| - mFillPaint = new Paint();
|
| - mStrokePaint = new Paint();
|
| - mFillPaint.setAntiAlias(true);
|
| - mStrokePaint.setAntiAlias(true);
|
| - mFillPaint.setStyle(Paint.Style.FILL);
|
| - mStrokePaint.setStyle(Paint.Style.STROKE);
|
| - mStrokePaint.setStrokeWidth(1.0f);
|
| -
|
| - mFindInPageBridge = findInPageBridge;
|
| - mTab = tab;
|
| - mTab.getContentViewCore().getContainerView().addView(
|
| - this, new FrameLayout.LayoutParams(mBarTouchWidth,
|
| - ViewGroup.LayoutParams.MATCH_PARENT, Gravity.END));
|
| - setTranslationX(
|
| - MathUtils.flipSignIf(mBarTouchWidth, LocalizationUtils.isLayoutRtl()));
|
| -
|
| - mVisibilityAnimation = ObjectAnimator.ofFloat(this, TRANSLATION_X, 0);
|
| - mVisibilityAnimation.setDuration(VISIBILTY_ANIMATION_DURATION_MS);
|
| - mVisibilityAnimation.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE);
|
| - mTab.getWindowAndroid().startAnimationOverContent(mVisibilityAnimation);
|
| - }
|
| -
|
| - /** Dismisses this results bar by removing it from the view hierarchy. */
|
| - public void dismiss() {
|
| - mDismissing = true;
|
| - if (mVisibilityAnimation != null && mVisibilityAnimation.isRunning()) {
|
| - mVisibilityAnimation.cancel();
|
| - }
|
| -
|
| - mVisibilityAnimation = ObjectAnimator.ofFloat(this, TRANSLATION_X,
|
| - MathUtils.flipSignIf(mBarTouchWidth, LocalizationUtils.isLayoutRtl()));
|
| - mVisibilityAnimation.setDuration(VISIBILTY_ANIMATION_DURATION_MS);
|
| - mVisibilityAnimation.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
|
| - mTab.getWindowAndroid().startAnimationOverContent(mVisibilityAnimation);
|
| - mVisibilityAnimation.addListener(new AnimatorListenerAdapter() {
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - super.onAnimationEnd(animation);
|
| -
|
| - if (getParent() != null) ((ViewGroup) getParent()).removeView(FindResultBar.this);
|
| - }
|
| - });
|
| - }
|
| -
|
| - /** Setup the tickmarks to draw using the rects of the find results. */
|
| - public void setMatchRects(int version, RectF[] rects, RectF activeRect) {
|
| - if (mRectsVersion != version) {
|
| - mRectsVersion = version;
|
| - assert rects != null;
|
| - mMatches = rects;
|
| - mTickmarks.clear();
|
| - Arrays.sort(mMatches, sComparator);
|
| - mBarHeightForWhichTickmarksWereCached = -1;
|
| - }
|
| - mActiveMatch = activeRect; // Can be null.
|
| - invalidate();
|
| - }
|
| -
|
| - /** Clears the tickmarks. */
|
| - public void clearMatchRects() {
|
| - setMatchRects(-1, new RectF[0], null);
|
| - }
|
| -
|
| - @Override
|
| - @SuppressLint("ClickableViewAccessibility")
|
| - public boolean onTouchEvent(MotionEvent event) {
|
| - if (!mDismissing && mTickmarks.size() > 0 && mTickmarks.size() == mMatches.length
|
| - && !mWaitingForActivateAck && event.getAction() != MotionEvent.ACTION_CANCEL) {
|
| - // We decided it's more important to get the keyboard out of the
|
| - // way asap; the user can compensate if their next MotionEvent
|
| - // scrolls somewhere unintended.
|
| - UiUtils.hideKeyboard(this);
|
| -
|
| - // Identify which drawn tickmark is closest to the user's finger.
|
| - int closest = Collections.binarySearch(mTickmarks,
|
| - new Tickmark(event.getY(), event.getY()));
|
| - if (closest < 0) {
|
| - // No exact match, so must determine nearest.
|
| - int insertionPoint = -1 - closest;
|
| - if (insertionPoint == 0) {
|
| - closest = 0;
|
| - } else if (insertionPoint == mTickmarks.size()) {
|
| - closest = mTickmarks.size() - 1;
|
| - } else {
|
| - float distanceA = Math.abs(event.getY()
|
| - - mTickmarks.get(insertionPoint - 1).centerY());
|
| - float distanceB = Math.abs(event.getY()
|
| - - mTickmarks.get(insertionPoint).centerY());
|
| - closest = insertionPoint - (distanceA <= distanceB ? 1 : 0);
|
| - }
|
| - }
|
| -
|
| - // Now activate the find match corresponding to that tickmark.
|
| - // Since mTickmarks may be outdated, we can't just pass the index.
|
| - // Instead we send the renderer the coordinates of the center of the
|
| - // find match's rect (as originally received in setMatchRects), and
|
| - // it will activate whatever find result is currently closest to
|
| - // that point (which will usually be the same one).
|
| - mWaitingForActivateAck = true;
|
| - mFindInPageBridge.activateNearestFindResult(
|
| - mMatches[closest].centerX(),
|
| - mMatches[closest].centerY());
|
| - }
|
| - return true; // Consume the event, whether or not we acted upon it.
|
| - }
|
| -
|
| - @Override
|
| - protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
| - super.onSizeChanged(w, h, oldw, oldh);
|
| - // Check for new rects, as they may move if the document size changes.
|
| - if (!mDismissing && mMatches.length > 0) {
|
| - mFindInPageBridge.requestFindMatchRects(mRectsVersion);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - protected void onDraw(Canvas canvas) {
|
| - super.onDraw(canvas);
|
| -
|
| - int leftMargin = getLeftMargin();
|
| - mFillPaint.setColor(mBackgroundColor);
|
| - mStrokePaint.setColor(mBackgroundBorderColor);
|
| - canvas.drawRect(leftMargin, 0,
|
| - leftMargin + mBarDrawWidth, getHeight(), mFillPaint);
|
| - float lineX = LocalizationUtils.isLayoutRtl()
|
| - ? leftMargin + mBarDrawWidth - 0.5f
|
| - : leftMargin + 0.5f;
|
| - canvas.drawLine(lineX, 0, lineX, getHeight(), mStrokePaint);
|
| -
|
| - if (mMatches.length == 0) {
|
| - return;
|
| - }
|
| -
|
| - if (mBarHeightForWhichTickmarksWereCached != getHeight()) {
|
| - calculateTickmarks();
|
| - }
|
| -
|
| - // Draw all matches (since they're sorted by increasing y-position
|
| - // overlapping tickmarks will form nice stacks).
|
| - mFillPaint.setColor(mResultColor);
|
| - mStrokePaint.setColor(mResultBorderColor);
|
| - for (Tickmark tickmark : mTickmarks) {
|
| - RectF rect = tickmark.toRectF();
|
| - canvas.drawRoundRect(rect, 2, 2, mFillPaint);
|
| - canvas.drawRoundRect(rect, 2, 2, mStrokePaint);
|
| - }
|
| -
|
| - // Draw the active tickmark on top (covering up the inactive tickmark
|
| - // we probably already drew for it).
|
| - if (mActiveMatch != null) {
|
| - Tickmark tickmark;
|
| - int i = Arrays.binarySearch(mMatches, mActiveMatch, sComparator);
|
| - if (i >= 0) {
|
| - // We've already generated a tickmark for all rects in mMatches,
|
| - // so use the corresponding one. However it was generated
|
| - // assuming the match would be inactive. Keep the position, but
|
| - // re-expand it using mActiveMinHeight.
|
| - tickmark = expandTickmarkToMinHeight(mTickmarks.get(i), true);
|
| - } else {
|
| - // How strange - mActiveMatch isn't in mMatches. Do our best to
|
| - // draw it anyway (though it might not line up exactly).
|
| - tickmark = tickmarkForRect(mActiveMatch, true);
|
| - }
|
| - RectF rect = tickmark.toRectF();
|
| - mFillPaint.setColor(mActiveColor);
|
| - mStrokePaint.setColor(mActiveBorderColor);
|
| - canvas.drawRoundRect(rect, 2, 2, mFillPaint);
|
| - canvas.drawRoundRect(rect, 2, 2, mStrokePaint);
|
| - }
|
| - }
|
| -
|
| - private int getLeftMargin() {
|
| - return LocalizationUtils.isLayoutRtl() ? 0 : getWidth() - mBarDrawWidth;
|
| - }
|
| -
|
| - private void calculateTickmarks() {
|
| - // TODO(johnme): Simplify calculation, and switch to integer arithmetic
|
| - // where possible (tickmarks within groups will still need fractional
|
| - // y-positions for anti-aliasing, but the start and end positions of
|
| - // groups can and should be integer-aligned [will give crisp borders],
|
| - // and the intermediary logic uses more floats than necessary).
|
| - // TODO(johnme): Consider adding unit tests for this.
|
| -
|
| - mBarHeightForWhichTickmarksWereCached = getHeight();
|
| -
|
| - // Generate tickmarks, neatly clustering any overlapping matches.
|
| - mTickmarks = new ArrayList<Tickmark>(mMatches.length);
|
| - int i = 0;
|
| - Tickmark nextTickmark = tickmarkForRect(mMatches[i], false);
|
| - float lastGroupEnd = -mMinGapBetweenStacks;
|
| - while (i < mMatches.length) {
|
| - // Find next cluster of overlapping tickmarks.
|
| - List<Tickmark> cluster = new ArrayList<Tickmark>();
|
| - cluster.add(nextTickmark);
|
| - i++;
|
| - while (i < mMatches.length) {
|
| - nextTickmark = tickmarkForRect(mMatches[i], false);
|
| - if (nextTickmark.mTop <= cluster.get(cluster.size() - 1).mBottom
|
| - + mMinGapBetweenStacks) {
|
| - cluster.add(nextTickmark);
|
| - i++;
|
| - } else {
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // Draw cluster.
|
| - int cn = cluster.size();
|
| - float minStart = lastGroupEnd + mMinGapBetweenStacks;
|
| - lastGroupEnd = cluster.get(cn - 1).mBottom;
|
| - float preferredStart = lastGroupEnd
|
| - - (cn - 1) * mStackedResultHeight
|
| - - mResultMinHeight;
|
| - float maxStart = cluster.get(0).mTop;
|
| - float start = Math.round(MathUtils.clamp(preferredStart, minStart, maxStart));
|
| - float scale = start >= preferredStart ? 1.0f :
|
| - (lastGroupEnd - start) / (lastGroupEnd - preferredStart);
|
| - float spacing = cn == 1 ? 0 : (lastGroupEnd - start
|
| - - scale * mResultMinHeight) / (cn - 1);
|
| - for (int j = 0; j < cn; j++) {
|
| - Tickmark tickmark = cluster.get(j);
|
| - tickmark.mTop = start + j * spacing;
|
| - if (j != cn - 1) {
|
| - tickmark.mBottom = tickmark.mTop + scale * mResultMinHeight;
|
| - }
|
| - mTickmarks.add(tickmark);
|
| - }
|
| - }
|
| - }
|
| -
|
| - private Tickmark tickmarkForRect(RectF r, boolean active) {
|
| - // Ratio of results bar height to page height
|
| - float vScale = mBarHeightForWhichTickmarksWereCached - 2 * mBarVerticalPadding;
|
| - Tickmark tickmark = new Tickmark(
|
| - r.top * vScale + mBarVerticalPadding,
|
| - r.bottom * vScale + mBarVerticalPadding);
|
| - return expandTickmarkToMinHeight(tickmark, active);
|
| - }
|
| -
|
| - private Tickmark expandTickmarkToMinHeight(Tickmark tickmark,
|
| - boolean active) {
|
| - int minHeight = active ? mActiveMinHeight : mResultMinHeight;
|
| - float missingHeight = minHeight - tickmark.height();
|
| - if (missingHeight > 0) {
|
| - return new Tickmark(tickmark.mTop - missingHeight / 2.0f,
|
| - tickmark.mBottom + missingHeight / 2.0f);
|
| - }
|
| - return tickmark;
|
| - }
|
| -
|
| - /** Like android.graphics.RectF, but without a left or right. */
|
| - private class Tickmark implements Comparable<Tickmark> {
|
| - float mTop;
|
| - float mBottom;
|
| - Tickmark(float top, float bottom) {
|
| - this.mTop = top;
|
| - this.mBottom = bottom;
|
| - }
|
| - float height() {
|
| - return mBottom - mTop;
|
| - }
|
| - float centerY() {
|
| - return (mTop + mBottom) * 0.5f;
|
| - }
|
| - RectF toRectF() {
|
| - int leftMargin = getLeftMargin();
|
| - RectF rect = new RectF(leftMargin, mTop, leftMargin + mBarDrawWidth, mBottom);
|
| - rect.inset(2.0f, 0.5f);
|
| - rect.offset(LocalizationUtils.isLayoutRtl() ? -0.5f : 0.5f, 0);
|
| - return rect;
|
| - }
|
| - @SuppressFBWarnings("EQ_COMPARETO_USE_OBJECT_EQUAL")
|
| - @Override
|
| - public int compareTo(Tickmark other) {
|
| - float center = centerY();
|
| - float otherCenter = other.centerY();
|
| - if (center == otherCenter) return 0;
|
| - return center > otherCenter ? 1 : -1;
|
| - }
|
| - }
|
| -}
|
|
|