1838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri/*
2838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Copyright (C) 2015 The Android Open Source Project
3838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri *
4838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Licensed under the Apache License, Version 2.0 (the "License");
5838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * you may not use this file except in compliance with the License.
6838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * You may obtain a copy of the License at
7838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri *
8838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri *      http://www.apache.org/licenses/LICENSE-2.0
9838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri *
10838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Unless required by applicable law or agreed to in writing, software
11838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * distributed under the License is distributed on an "AS IS" BASIS,
12838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * See the License for the specific language governing permissions and
14838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * limitations under the License.
15838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri */
16838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
17838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarripackage com.android.internal.view;
18838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
19838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.content.Context;
20838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.graphics.Rect;
21838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.ActionMode;
22838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.Menu;
23838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.MenuInflater;
24838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.MenuItem;
25838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.View;
269e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Tokiimport android.view.ViewConfiguration;
27838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
2815a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Tokiimport com.android.internal.R;
290d7d4ef56083543d58ef5835ec594865a547347cClara Bayarriimport com.android.internal.util.Preconditions;
30838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport com.android.internal.view.menu.MenuBuilder;
31838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport com.android.internal.widget.FloatingToolbar;
32838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
33c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Tokiimport java.util.Arrays;
34c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki
35838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarripublic class FloatingActionMode extends ActionMode {
36838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
379e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki    private static final int MAX_HIDE_DURATION = 3000;
38fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private static final int MOVING_HIDE_DELAY = 300;
39fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
40838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private final Context mContext;
41838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private final ActionMode.Callback2 mCallback;
42838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private final MenuBuilder mMenu;
43838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private final Rect mContentRect;
44bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final Rect mContentRectOnScreen;
45bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final Rect mPreviousContentRectOnScreen;
46bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final int[] mViewPositionOnScreen;
47bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final int[] mPreviousViewPositionOnScreen;
48bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final int[] mRootViewPositionOnScreen;
49bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final Rect mViewRectOnScreen;
50bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa    private final Rect mPreviousViewRectOnScreen;
51a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki    private final Rect mScreenRect;
52838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private final View mOriginatingView;
5315a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki    private final int mBottomAllowance;
54fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
55fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private final Runnable mMovingOff = new Runnable() {
56fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        public void run() {
57fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki            mFloatingToolbarVisibilityHelper.setMoving(false);
58f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
59fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
60fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    };
61fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
629e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki    private final Runnable mHideOff = new Runnable() {
63fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        public void run() {
649e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            mFloatingToolbarVisibilityHelper.setHideRequested(false);
65f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
66fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
67fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    };
68fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
690d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri    private FloatingToolbar mFloatingToolbar;
70fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private FloatingToolbarVisibilityHelper mFloatingToolbarVisibilityHelper;
71838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
72838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public FloatingActionMode(
730d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri            Context context, ActionMode.Callback2 callback, View originatingView) {
74fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        mContext = Preconditions.checkNotNull(context);
75fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        mCallback = Preconditions.checkNotNull(callback);
76838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        mMenu = new MenuBuilder(context).setDefaultShowAsAction(
77838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                MenuItem.SHOW_AS_ACTION_IF_ROOM);
780d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri        setType(ActionMode.TYPE_FLOATING);
791e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri        mMenu.setCallback(new MenuBuilder.Callback() {
801e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri            @Override
811e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri            public void onMenuModeChange(MenuBuilder menu) {}
821e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri
831e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri            @Override
841e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri            public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
851e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri                return mCallback.onActionItemClicked(FloatingActionMode.this, item);
861e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri            }
871e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri        });
880d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri        mContentRect = new Rect();
89bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mContentRectOnScreen = new Rect();
90bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mPreviousContentRectOnScreen = new Rect();
91bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mViewPositionOnScreen = new int[2];
92bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mPreviousViewPositionOnScreen = new int[2];
93bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mRootViewPositionOnScreen = new int[2];
94bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mViewRectOnScreen = new Rect();
95bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mPreviousViewRectOnScreen = new Rect();
96a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki        mScreenRect = new Rect();
97fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        mOriginatingView = Preconditions.checkNotNull(originatingView);
98bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mOriginatingView.getLocationOnScreen(mViewPositionOnScreen);
9915a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki        // Allow the content rect to overshoot a little bit beyond the
10015a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki        // bottom view bound if necessary.
10115a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki        mBottomAllowance = context.getResources()
10215a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki                .getDimensionPixelSize(R.dimen.content_rect_bottom_clip_allowance);
1030d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri    }
1040d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri
1050d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri    public void setFloatingToolbar(FloatingToolbar floatingToolbar) {
106838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        mFloatingToolbar = floatingToolbar
107838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                .setMenu(mMenu)
108838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
109838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                        @Override
110838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                    public boolean onMenuItemClick(MenuItem item) {
1111e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri                        return mMenu.performItemAction(item, 0);
112838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                    }
113838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri                });
114fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
115f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        mFloatingToolbarVisibilityHelper.activate();
116838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
117838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
118838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
119838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void setTitle(CharSequence title) {}
120838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
121838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
122838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void setTitle(int resId) {}
123838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
124838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
125838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void setSubtitle(CharSequence subtitle) {}
126838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
127838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
128838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void setSubtitle(int resId) {}
129838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
130838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
131838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void setCustomView(View view) {}
132838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
133838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
134838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void invalidate() {
135fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
136838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        mCallback.onPrepareActionMode(this, mMenu);
137f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        invalidateContentRect();  // Will re-layout and show the toolbar if necessary.
138838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
139838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
140838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
141838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void invalidateContentRect() {
142fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
143838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        mCallback.onGetContentRect(this, mOriginatingView, mContentRect);
144838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        repositionToolbar();
145838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
146838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
147838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void updateViewLocationInWindow() {
148fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
149c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki
150bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mOriginatingView.getLocationOnScreen(mViewPositionOnScreen);
151bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mOriginatingView.getRootView().getLocationOnScreen(mRootViewPositionOnScreen);
152bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mOriginatingView.getGlobalVisibleRect(mViewRectOnScreen);
153bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mViewRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]);
154c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki
155bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        if (!Arrays.equals(mViewPositionOnScreen, mPreviousViewPositionOnScreen)
156bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                || !mViewRectOnScreen.equals(mPreviousViewRectOnScreen)) {
157c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki            repositionToolbar();
158bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            mPreviousViewPositionOnScreen[0] = mViewPositionOnScreen[0];
159bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            mPreviousViewPositionOnScreen[1] = mViewPositionOnScreen[1];
160bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            mPreviousViewRectOnScreen.set(mViewRectOnScreen);
161c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki        }
162838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
163838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
164838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    private void repositionToolbar() {
165fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
166601523ad007923779d156aaa8dc229468773e48cAbodunrinwa Toki
167bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mContentRectOnScreen.set(mContentRect);
168bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mContentRectOnScreen.offset(mViewPositionOnScreen[0], mViewPositionOnScreen[1]);
169a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki
170a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki        if (isContentRectWithinBounds()) {
171a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki            mFloatingToolbarVisibilityHelper.setOutOfBounds(false);
172f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            // Make sure that content rect is not out of the view's visible bounds.
173bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            mContentRectOnScreen.set(
174bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                    Math.max(mContentRectOnScreen.left, mViewRectOnScreen.left),
175bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                    Math.max(mContentRectOnScreen.top, mViewRectOnScreen.top),
176bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                    Math.min(mContentRectOnScreen.right, mViewRectOnScreen.right),
177bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                    Math.min(mContentRectOnScreen.bottom,
178bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                            mViewRectOnScreen.bottom + mBottomAllowance));
179bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa
180bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            if (!mContentRectOnScreen.equals(mPreviousContentRectOnScreen)) {
181f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                // Content rect is moving.
182f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                mOriginatingView.removeCallbacks(mMovingOff);
183f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                mFloatingToolbarVisibilityHelper.setMoving(true);
1841b57653b50892f143241ae0f0beb2246ca4b2aa7Abodunrinwa Toki                mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
185f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
186f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
187bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa                mFloatingToolbar.setContentRect(mContentRectOnScreen);
188f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                mFloatingToolbar.updateLayout();
189f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            }
190a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki        } else {
191a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki            mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
1921b57653b50892f143241ae0f0beb2246ca4b2aa7Abodunrinwa Toki            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
193bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa            mContentRectOnScreen.setEmpty();
194a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki        }
195a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki
196bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa        mPreviousContentRectOnScreen.set(mContentRectOnScreen);
197838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
198838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
199f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki    private boolean isContentRectWithinBounds() {
200f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        mScreenRect.set(
201f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            0,
202f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            0,
203f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mContext.getResources().getDisplayMetrics().widthPixels,
204f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mContext.getResources().getDisplayMetrics().heightPixels);
205f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
206f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri        return intersectsClosed(mContentRectOnScreen, mScreenRect)
207f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri            && intersectsClosed(mContentRectOnScreen, mViewRectOnScreen);
208f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri    }
209f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri
210f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri    /*
211f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri     * Same as Rect.intersects, but includes cases where the rectangles touch.
212f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri    */
213f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri    private static boolean intersectsClosed(Rect a, Rect b) {
214f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri         return a.left <= b.right && b.left <= a.right
215f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri                 && a.top <= b.bottom && b.top <= a.bottom;
216fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    }
217fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
218fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    @Override
2199e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki    public void hide(long duration) {
220fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
2219e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki
2229e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        if (duration == ActionMode.DEFAULT_HIDE_DURATION) {
2239e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            duration = ViewConfiguration.getDefaultActionModeHideDuration();
2249e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        }
2259e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        duration = Math.min(MAX_HIDE_DURATION, duration);
2269e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        mOriginatingView.removeCallbacks(mHideOff);
2279e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        if (duration <= 0) {
2289e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            mHideOff.run();
229fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        } else {
2309e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            mFloatingToolbarVisibilityHelper.setHideRequested(true);
231f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
2329e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            mOriginatingView.postDelayed(mHideOff, duration);
233fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
234fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    }
235fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
236838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
237972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki    public void onWindowFocusChanged(boolean hasWindowFocus) {
238972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        checkToolbarInitialized();
239972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus);
240972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
241972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki    }
242972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki
243972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki    @Override
244838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public void finish() {
245fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        checkToolbarInitialized();
246fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        reset();
247838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        mCallback.onDestroyActionMode(this);
248838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
249838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
250838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
251838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public Menu getMenu() {
252838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        return mMenu;
253838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
254838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
255838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
256838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public CharSequence getTitle() {
257838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        return null;
258838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
259838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
260838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
261838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public CharSequence getSubtitle() {
262838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        return null;
263838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
264838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
265838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
266838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public View getCustomView() {
267838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        return null;
268838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
269838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
270838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    @Override
271838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    public MenuInflater getMenuInflater() {
272838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri        return new MenuInflater(mContext);
273838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri    }
274838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri
275fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    /**
276f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki     * @throws IllegalStateException
277fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki     */
278fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private void checkToolbarInitialized() {
279fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        Preconditions.checkState(mFloatingToolbar != null);
280fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        Preconditions.checkState(mFloatingToolbarVisibilityHelper != null);
281fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    }
282fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
283fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private void reset() {
284972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        mFloatingToolbar.dismiss();
285f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        mFloatingToolbarVisibilityHelper.deactivate();
286fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        mOriginatingView.removeCallbacks(mMovingOff);
2879e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        mOriginatingView.removeCallbacks(mHideOff);
288fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    }
289fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
290fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    /**
291f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki     * A helper for showing/hiding the floating toolbar depending on certain states.
292fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki     */
293fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    private static final class FloatingToolbarVisibilityHelper {
294fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
295fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        private final FloatingToolbar mToolbar;
296fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
2979e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        private boolean mHideRequested;
298fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        private boolean mMoving;
299fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        private boolean mOutOfBounds;
300972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        private boolean mWindowFocused = true;
301fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
302f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        private boolean mActive;
303f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
304fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) {
305fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki            mToolbar = Preconditions.checkNotNull(toolbar);
306fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
307fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
308f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        public void activate() {
309f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mHideRequested = false;
310f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mMoving = false;
311f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mOutOfBounds = false;
312972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki            mWindowFocused = true;
313f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
314f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mActive = true;
315f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        }
316f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
317f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        public void deactivate() {
318f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mActive = false;
319f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            mToolbar.dismiss();
320f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        }
321f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
3229e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki        public void setHideRequested(boolean hide) {
3239e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki            mHideRequested = hide;
324fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
325fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
326fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        public void setMoving(boolean moving) {
327fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki            mMoving = moving;
328fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
329fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
330fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        public void setOutOfBounds(boolean outOfBounds) {
331fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki            mOutOfBounds = outOfBounds;
332fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
333fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki
334972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        public void setWindowFocused(boolean windowFocused) {
335972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki            mWindowFocused = windowFocused;
336972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki        }
337972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki
338f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki        public void updateToolbarVisibility() {
339f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            if (!mActive) {
340f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki                return;
341f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            }
342f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki
343972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki            if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) {
344fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki                mToolbar.hide();
345f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki            } else {
346fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki                mToolbar.show();
347fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki            }
348fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki        }
349fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki    }
350838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri}
351