summaryrefslogtreecommitdiffstats
path: root/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarTablet.java
blob: bd42e21016610c75e6d89534e1df28d9a2d050a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// 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.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

import org.chromium.chrome.R;

/**
 * A tablet specific version of the {@link FindToolbar}.
 */
public class FindToolbarTablet extends FindToolbar {
    private static final int ENTER_EXIT_ANIMATION_DURATION_MS = 200;
    private static final int MAKE_ROOM_ANIMATION_DURATION_MS = 200;

    private static final float Y_INSET_DP = 8.f;

    private ObjectAnimator mCurrentAnimation;

    private ObjectAnimator mAnimationEnter;
    private ObjectAnimator mAnimationLeave;

    private final int mYInsetPx;

    /**
     * Creates an instance of a {@link FindToolbarTablet}.
     * @param context The Context to create the {@link FindToolbarTablet} under.
     * @param attrs The AttributeSet used to create the {@link FindToolbarTablet}.
     */
    public FindToolbarTablet(Context context, AttributeSet attrs) {
        super(context, attrs);

        mYInsetPx = (int) (context.getResources().getDisplayMetrics().density * Y_INSET_DP);
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();

        setVisibility(View.GONE);

        Resources resources = getContext().getResources();
        int width = resources.getDimensionPixelSize(R.dimen.find_in_page_popup_width);
        int endMargin = resources.getDimensionPixelOffset(R.dimen.find_in_page_popup_margin_end);
        int translateWidth = width + endMargin;

        mAnimationEnter = ObjectAnimator.ofFloat(this, "translationX", translateWidth, 0);
        mAnimationEnter.setDuration(ENTER_EXIT_ANIMATION_DURATION_MS);
        mAnimationEnter.setInterpolator(new DecelerateInterpolator());
        mAnimationEnter.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                setVisibility(View.VISIBLE);
                postInvalidateOnAnimation();
                superActivate();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentAnimation = null;
            }
        });

        mAnimationLeave = ObjectAnimator.ofFloat(this, "translationX", 0, translateWidth);
        mAnimationLeave.setDuration(ENTER_EXIT_ANIMATION_DURATION_MS);
        mAnimationLeave.setInterpolator(new DecelerateInterpolator());
        mAnimationLeave.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                setVisibility(View.VISIBLE);
                postInvalidateOnAnimation();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                setVisibility(View.GONE);
                mCurrentAnimation = null;
            }
        });
    }

    @Override
    public void activate() {
        if (mCurrentAnimation == mAnimationEnter) return;

        if (isViewAvailable()) setShowState(true);
    }

    @Override
    public void deactivate(boolean clearSelection) {
        super.deactivate(clearSelection);

        if (mCurrentAnimation == mAnimationLeave) return;

        setShowState(false);
    }

    @Override
    public boolean isAnimating() {
        return mCurrentAnimation != null;
    }

    @Override
    public void findResultSelected(Rect rect) {
        super.findResultSelected(rect);

        boolean makeRoom = false;
        float density = getContext().getResources().getDisplayMetrics().density;

        if (rect != null && rect.intersects((int) (getLeft() / density), 0,
                (int) (getRight() / density), (int) (getHeight() / density))) {
            makeRoom = true;
        }

        setMakeRoomForResults(makeRoom);
    }

    @Override
    protected void clearResults() {
        super.clearResults();
        setMakeRoomForResults(false);
    }

    private void setMakeRoomForResults(boolean makeRoom) {
        float translationY = makeRoom ? -(getHeight() - mYInsetPx) : 0.f;

        if (translationY != getTranslationY()) {
            mCurrentAnimation = ObjectAnimator.ofFloat(this, "translationY", getTranslationY(),
                    translationY);
            mCurrentAnimation.setDuration(MAKE_ROOM_ANIMATION_DURATION_MS);
            mAnimationLeave.setInterpolator(new DecelerateInterpolator());
            mAnimationLeave.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    postInvalidateOnAnimation();
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    mCurrentAnimation = null;
                }
            });
            mTabModelSelector.getCurrentTab()
                             .getWindowAndroid()
                             .startAnimationOverContent(mCurrentAnimation);
        }
    }

    private void setShowState(boolean show) {
        ObjectAnimator nextAnimator = null;

        if (show && getVisibility() != View.VISIBLE && mCurrentAnimation != mAnimationEnter) {
            View anchorView = getRootView().findViewById(R.id.toolbar);
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
            lp.topMargin = anchorView.getBottom() - mYInsetPx;
            setLayoutParams(lp);
            nextAnimator = mAnimationEnter;
        } else if (!show && getVisibility() != View.GONE && mCurrentAnimation != mAnimationLeave) {
            nextAnimator = mAnimationLeave;
            onHideAnimationStart();
        }

        if (nextAnimator != null) {
            mCurrentAnimation = nextAnimator;
            mTabModelSelector.getCurrentTab()
                             .getWindowAndroid()
                             .startAnimationOverContent(nextAnimator);
            postInvalidateOnAnimation();
        }
    }

    /**
     * This is here so that Animation inner classes can access the parent activate methods.
     */
    private void superActivate() {
        super.activate();
    }
}