1785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung/*
2785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Copyright (C) 2011 The Android Open Source Project
3785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
4785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * you may not use this file except in compliance with the License.
6785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * You may obtain a copy of the License at
7785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
8785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
10785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Unless required by applicable law or agreed to in writing, software
11785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * See the License for the specific language governing permissions and
14785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * limitations under the License.
15785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */
16785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
18785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
19f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chungimport android.animation.Animator;
20b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.animation.AnimatorListenerAdapter;
21f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chungimport android.animation.AnimatorSet;
22b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.animation.ObjectAnimator;
23785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.Context;
24785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.res.Resources;
252d75f125f4e8bb5358dfdb63096d0493488ac2e5Winson Chungimport android.graphics.Color;
2677e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlockimport android.graphics.Rect;
27785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.util.AttributeSet;
28785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.LayoutInflater;
294179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chungimport android.view.MotionEvent;
30785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.View;
31785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.ViewGroup;
32141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurkaimport android.widget.FrameLayout;
331899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurkaimport android.widget.LinearLayout;
34785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.widget.TabHost;
35faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chungimport android.widget.TabWidget;
36785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.widget.TextView;
37785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
38141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurkaimport java.util.ArrayList;
39141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
40785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungpublic class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable,
4177e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        TabHost.OnTabChangeListener, Insettable  {
42785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    static final String LOG_TAG = "AppsCustomizeTabHost";
43785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
44785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private static final String APPS_TAB_TAG = "APPS";
45785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private static final String WIDGETS_TAB_TAG = "WIDGETS";
46785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
47785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private final LayoutInflater mLayoutInflater;
48f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    private ViewGroup mTabs;
49fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung    private ViewGroup mTabsContainer;
504179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    private AppsCustomizePagedView mAppsCustomizePane;
51141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka    private FrameLayout mAnimationBuffer;
521899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    private LinearLayout mContent;
53785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
54c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    private boolean mInTransition;
557044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    private boolean mTransitioningToWorkspace;
56c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    private boolean mResetAfterTransition;
576cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka    private Runnable mRelayoutAndMakeVisible;
5877e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock    private final Rect mInsets = new Rect();
59c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung
60785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
61785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        super(context, attrs);
62785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        mLayoutInflater = LayoutInflater.from(context);
636cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        mRelayoutAndMakeVisible = new Runnable() {
646cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                public void run() {
656cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                    mTabs.requestLayout();
666cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                    mTabsContainer.setAlpha(1f);
676cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                }
686cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka            };
69785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
70785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
71f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    /**
725a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * Convenience methods to select specific tabs.  We want to set the content type immediately
735a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * in these cases, but we note that we still call setCurrentTabByTag() so that the tab view
745a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * reflects the new content (but doesn't do the animation and logic associated with changing
755a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * tabs manually).
76f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung     */
77c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung    void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) {
78fa4086ddd7ab9dd98e3ffef798a655ec07e37e14Winson Chung        setOnTabChangedListener(null);
795a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        onTabChangedStart();
805a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        onTabChangedEnd(type);
81fa4086ddd7ab9dd98e3ffef798a655ec07e37e14Winson Chung        setCurrentTabByTag(getTabTagForContentType(type));
82fa4086ddd7ab9dd98e3ffef798a655ec07e37e14Winson Chung        setOnTabChangedListener(this);
835a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
84947dc5431981e40ffc8d687604f7777d35915034Adam Cohen
8577e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock    @Override
8677e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock    public void setInsets(Rect insets) {
8777e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        mInsets.set(insets);
8877e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        FrameLayout.LayoutParams flp = (LayoutParams) mContent.getLayoutParams();
8977e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        flp.topMargin = insets.top;
9077e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        flp.bottomMargin = insets.bottom;
9177e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        flp.leftMargin = insets.left;
9277e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        flp.rightMargin = insets.right;
9377e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock        mContent.setLayoutParams(flp);
9477e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock    }
9577e1f47520958edd7ec04e203db65b932537bd1cJohn Spurlock
96785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
97785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Setup the tab host and create all necessary tabs.
98785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
99785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
100785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    protected void onFinishInflate() {
101785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Setup the tab host
102785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        setup();
103785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
104fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        final ViewGroup tabsContainer = (ViewGroup) findViewById(R.id.tabs_container);
1058b805b17158886035b38261eb611d8641701ae43Michael Jurka        final TabWidget tabs = getTabWidget();
1064179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView)
107785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                findViewById(R.id.apps_customize_pane_content);
108f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        mTabs = tabs;
109fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        mTabsContainer = tabsContainer;
1104179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        mAppsCustomizePane = appsCustomizePane;
111141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka        mAnimationBuffer = (FrameLayout) findViewById(R.id.animation_buffer);
1121899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        mContent = (LinearLayout) findViewById(R.id.apps_customize_content);
1134179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException();
114785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
115785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Configure the tabs content factory to return the same paged view (that we change the
116785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // content filter on)
117785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        TabContentFactory contentFactory = new TabContentFactory() {
118785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            public View createTabContent(String tag) {
1194179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung                return appsCustomizePane;
120785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            }
121785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        };
122785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
123785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Create the tabs
124785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        TextView tabView;
125d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        String label;
1268b805b17158886035b38261eb611d8641701ae43Michael Jurka        label = getContext().getString(R.string.all_apps_button_label);
127785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
128d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setText(label);
129d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setContentDescription(label);
130c58497ee619416c4949b16eb43486c11618b69e5Winson Chung        addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
1318b805b17158886035b38261eb611d8641701ae43Michael Jurka        label = getContext().getString(R.string.widgets_tab_label);
132785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
133d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setText(label);
134d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setContentDescription(label);
135785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
136785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        setOnTabChangedListener(this);
137faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung
138faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        // Setup the key listener to jump between the last tab view and the market icon
139faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        AppsCustomizeTabKeyEventListener keyListener = new AppsCustomizeTabKeyEventListener();
140faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        View lastTab = tabs.getChildTabViewAt(tabs.getTabCount() - 1);
141faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        lastTab.setOnKeyListener(keyListener);
142faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        View shopButton = findViewById(R.id.market_button);
143faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        shopButton.setOnKeyListener(keyListener);
144fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung
145fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        // Hide the tab bar until we measure
146fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        mTabsContainer.setAlpha(0f);
147f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    }
148785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
149f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    @Override
150f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
151f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        boolean remeasureTabWidth = (mTabs.getLayoutParams().width <= 0);
152f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
153f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
154f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // Set the width of the tab list to the content width
155f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        if (remeasureTabWidth) {
156fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung            int contentWidth = mAppsCustomizePane.getPageContentWidth();
157141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka            if (contentWidth > 0 && mTabs.getLayoutParams().width != contentWidth) {
158141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // Set the width and show the tab bar
159fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung                mTabs.getLayoutParams().width = contentWidth;
160c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung                mRelayoutAndMakeVisible.run();
161fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung            }
162c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung
163c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
164f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
1654179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    }
1664179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung
1677044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung     public boolean onInterceptTouchEvent(MotionEvent ev) {
168ac08f4b93e075fd90c8689509ad3108284a717d8Winson Chung         // If we are mid transitioning to the workspace, then intercept touch events here so we
169ac08f4b93e075fd90c8689509ad3108284a717d8Winson Chung         // can ignore them, otherwise we just let all apps handle the touch events.
170ac08f4b93e075fd90c8689509ad3108284a717d8Winson Chung         if (mInTransition && mTransitioningToWorkspace) {
1717044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung             return true;
1727044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         }
1737044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         return super.onInterceptTouchEvent(ev);
1747044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung     };
1757044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
1764179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    @Override
1774179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    public boolean onTouchEvent(MotionEvent event) {
178ac08f4b93e075fd90c8689509ad3108284a717d8Winson Chung        // Allow touch events to fall through to the workspace if we are transitioning there
179ac08f4b93e075fd90c8689509ad3108284a717d8Winson Chung        if (mInTransition && mTransitioningToWorkspace) {
18021fadeaad1f5a662df425085551c6f54e8c28f52Winson Chung            return super.onTouchEvent(event);
1817044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        }
1827044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
1834179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        // Intercept all touch events up to the bottom of the AppsCustomizePane so they do not fall
1844179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        // through to the workspace and trigger showWorkspace()
1854179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        if (event.getY() < mAppsCustomizePane.getBottom()) {
1864179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung            return true;
1874179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        }
1884179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        return super.onTouchEvent(event);
189785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
190785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
1915a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    private void onTabChangedStart() {
1925a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
1930cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
194097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung    private void reloadCurrentPage() {
195097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
196097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        mAppsCustomizePane.requestFocus();
197097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung    }
198097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung
1995a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    private void onTabChangedEnd(AppsCustomizePagedView.ContentType type) {
2002d75f125f4e8bb5358dfdb63096d0493488ac2e5Winson Chung        int bgAlpha = (int) (255 * (getResources().getInteger(
2012d75f125f4e8bb5358dfdb63096d0493488ac2e5Winson Chung            R.integer.config_appsCustomizeSpringLoadedBgAlpha) / 100f));
2022d75f125f4e8bb5358dfdb63096d0493488ac2e5Winson Chung        setBackgroundColor(Color.argb(bgAlpha, 0, 0, 0));
2035a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        mAppsCustomizePane.setContentType(type);
2045a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
2055a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung
206785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
207785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public void onTabChanged(String tabId) {
208b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung        final AppsCustomizePagedView.ContentType type = getContentTypeForTabTag(tabId);
209b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung
2100cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // Animate the changing of the tab content by fading pages in and out
2110cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        final Resources res = getResources();
2120cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
213f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung
2140cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // We post a runnable here because there is a delay while the first page is loading and
2150cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // the feedback from having changed the tab almost feels better than having it stick
2160cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        post(new Runnable() {
2170cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            @Override
2180cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            public void run() {
219097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                if (mAppsCustomizePane.getMeasuredWidth() <= 0 ||
220097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                        mAppsCustomizePane.getMeasuredHeight() <= 0) {
221097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                    reloadCurrentPage();
222097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                    return;
223097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                }
224097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung
225141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
226141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // and then cross fade to the new pages
227c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                int[] visiblePageRange = new int[2];
228c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                mAppsCustomizePane.getVisiblePages(visiblePageRange);
229c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) {
230c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    // If we can't get the visible page ranges, then just skip the animation
231c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    reloadCurrentPage();
232c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    return;
233c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                }
234c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                ArrayList<View> visiblePages = new ArrayList<View>();
235c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
236c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    visiblePages.add(mAppsCustomizePane.getPageAt(i));
237c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                }
238141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
239141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // We want the pages to be rendered in exactly the same way as they were when
240141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
241141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // to be exactly the same as mAppsCustomizePane, and below, set the left/top
242141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // parameters to be correct for each of the pages
243141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
244141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
245141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // mAppsCustomizePane renders its children in reverse order, so
246141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // add the pages to mAnimationBuffer in reverse order to match that behavior
247141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                for (int i = visiblePages.size() - 1; i >= 0; i--) {
248141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    View child = visiblePages.get(i);
249c58497ee619416c4949b16eb43486c11618b69e5Winson Chung                    if (child instanceof AppsCustomizeCellLayout) {
250c58497ee619416c4949b16eb43486c11618b69e5Winson Chung                        ((AppsCustomizeCellLayout) child).resetChildrenOnKeyListeners();
251c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    } else if (child instanceof PagedViewGridLayout) {
252c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                        ((PagedViewGridLayout) child).resetChildrenOnKeyListeners();
253c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    }
254141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
255141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAppsCustomizePane.removeView(child);
256141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
257141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.setAlpha(1f);
258141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.setVisibility(View.VISIBLE);
2596e3cf9001e2cd5df1b9850831a6ce21497bd1202Winson Chung                    LayoutParams p = new FrameLayout.LayoutParams(child.getMeasuredWidth(),
2606e3cf9001e2cd5df1b9850831a6ce21497bd1202Winson Chung                            child.getMeasuredHeight());
261141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    p.setMargins((int) child.getLeft(), (int) child.getTop(), 0, 0);
262141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.addView(child, p);
263141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                }
264b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung
2650cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                // Toggle the new content
2660cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                onTabChangedStart();
2670cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                onTabChangedEnd(type);
2680cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
2690cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                // Animate the transition
2702ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka                ObjectAnimator outAnim = LauncherAnimUtils.ofFloat(mAnimationBuffer, "alpha", 0f);
2710cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                outAnim.addListener(new AnimatorListenerAdapter() {
272ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                    private void clearAnimationBuffer() {
2730cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                        mAnimationBuffer.setVisibility(View.GONE);
274ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                        PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(false);
275141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                        mAnimationBuffer.removeAllViews();
276ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                        PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(true);
277ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                    }
278ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                    @Override
279ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                    public void onAnimationEnd(Animator animation) {
280ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                        clearAnimationBuffer();
281141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    }
282141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    @Override
283141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    public void onAnimationCancel(Animator animation) {
284ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka                        clearAnimationBuffer();
2850cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    }
2860cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                });
2872ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka                ObjectAnimator inAnim = LauncherAnimUtils.ofFloat(mAppsCustomizePane, "alpha", 1f);
2880cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                inAnim.addListener(new AnimatorListenerAdapter() {
2890cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    @Override
2900cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    public void onAnimationEnd(Animator animation) {
291097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                        reloadCurrentPage();
2920cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    }
2930cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                });
2947f9ddd84353451e72f48f34a8d280d5e873b2f45Michael Jurka
2957f9ddd84353451e72f48f34a8d280d5e873b2f45Michael Jurka                final AnimatorSet animSet = LauncherAnimUtils.createAnimatorSet();
2960cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                animSet.playTogether(outAnim, inAnim);
2970cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                animSet.setDuration(duration);
298f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                animSet.start();
2990cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            }
3000cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        });
3010cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen    }
3020cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
3030cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen    public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) {
304fa4086ddd7ab9dd98e3ffef798a655ec07e37e14Winson Chung        setOnTabChangedListener(null);
3050cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        setCurrentTabByTag(getTabTagForContentType(type));
306fa4086ddd7ab9dd98e3ffef798a655ec07e37e14Winson Chung        setOnTabChangedListener(this);
307785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
308785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
309785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
310785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Returns the content type for the specified tab tag.
311785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
312785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
313785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        if (tag.equals(APPS_TAB_TAG)) {
314785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return AppsCustomizePagedView.ContentType.Applications;
315785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        } else if (tag.equals(WIDGETS_TAB_TAG)) {
316785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return AppsCustomizePagedView.ContentType.Widgets;
317785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        }
318785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        return AppsCustomizePagedView.ContentType.Applications;
319785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
320785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
321785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
322fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung     * Returns the tab tag for a given content type.
323fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung     */
324fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
325fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        if (type == AppsCustomizePagedView.ContentType.Applications) {
326fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung            return APPS_TAB_TAG;
327fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        } else if (type == AppsCustomizePagedView.ContentType.Widgets) {
328fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung            return WIDGETS_TAB_TAG;
329fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        }
330fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        return APPS_TAB_TAG;
331fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    }
332fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung
333fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    /**
334785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Disable focus on anything under this view in the hierarchy if we are not visible.
335785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
336785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
337785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public int getDescendantFocusability() {
338785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        if (getVisibility() != View.VISIBLE) {
339785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
340785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        }
341785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        return super.getDescendantFocusability();
342785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
343785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
344c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    void reset() {
345c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        if (mInTransition) {
346c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            // Defer to after the transition to reset
347c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mResetAfterTransition = true;
348c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        } else {
349c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            // Reset immediately
350c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mAppsCustomizePane.reset();
351c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        }
352c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    }
353c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung
3541899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    private void enableAndBuildHardwareLayer() {
35519e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // isHardwareAccelerated() checks if we're attached to a window and if that
35619e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // window is HW accelerated-- we were sometimes not attached to a window
35719e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // and buildLayer was throwing an IllegalStateException
3581899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        if (isHardwareAccelerated()) {
359f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            // Turn on hardware layers for performance
360f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            setLayerType(LAYER_TYPE_HARDWARE, null);
361f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
3621899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka            // force building the layer, so you don't get a blip early in an animation
3631899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka            // when the layer is created layer
364f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            buildLayer();
365f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
3661899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    }
3671899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
3682a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    @Override
3692a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    public View getContent() {
3702a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka        return mContent;
3711899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    }
3721899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
3731899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    /* LauncherTransitionable overrides */
3741899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    @Override
375a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka    public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
376a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka        mAppsCustomizePane.onLauncherTransitionPrepare(l, animated, toWorkspace);
3771899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        mInTransition = true;
3787044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        mTransitioningToWorkspace = toWorkspace;
3791899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
380bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (toWorkspace) {
381bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            // Going from All Apps -> Workspace
382bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            setVisibilityOfSiblingsWithLowerZOrder(VISIBLE);
383bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        } else {
384bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            // Going from Workspace -> All Apps
385bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            mContent.setVisibility(VISIBLE);
3863d845e8d8921eebe0b072b7856b660b4350921e1Michael Jurka
387e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Make sure the current page is loaded (we start loading the side pages after the
388e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // transition to prevent slowing down the animation)
389e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true);
390430e8a5f5b06181addfd37223518fc21c5c41b69Michael Jurka        }
391bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
392c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        if (mResetAfterTransition) {
393c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mAppsCustomizePane.reset();
394c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mResetAfterTransition = false;
395c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        }
396a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka    }
397bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
398a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka    @Override
399a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka    public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
400bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (animated) {
401bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            enableAndBuildHardwareLayer();
402bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        }
403af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung
404af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung        // Dismiss the workspace cling
405af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung        l.dismissWorkspaceCling(null);
406785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
407f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
408785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
4097044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    public void onLauncherTransitionStep(Launcher l, float t) {
4107044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        // Do nothing
4117044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    }
4127044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
4137044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    @Override
414bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
41539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka        mAppsCustomizePane.onLauncherTransitionEnd(l, animated, toWorkspace);
416c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        mInTransition = false;
417bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (animated) {
418f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            setLayerType(LAYER_TYPE_NONE, null);
419f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
4203ac74c55cf8baef29db80e8c67ab4ab033b04417Winson Chung
4217d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung        if (!toWorkspace) {
4227819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung            // Show the all apps cling (if not already shown)
4233f4e1423804d64a38cb69e4511d7b80783564827Winson Chung            mAppsCustomizePane.showAllAppsCling();
424e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Make sure adjacent pages are loaded (we wait until after the transition to
425e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // prevent slowing down the animation)
426e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
4277d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung
4287819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung            // Going from Workspace -> All Apps
4297819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung            // NOTE: We should do this at the end since we check visibility state in some of the
4307819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung            // cling initialization/dismiss code above.
4317819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung            setVisibilityOfSiblingsWithLowerZOrder(INVISIBLE);
4325a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        }
433785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
43470d721061536e0634f6cfa8cd219759a83befceeWinson Chung
435bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    private void setVisibilityOfSiblingsWithLowerZOrder(int visibility) {
436bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        ViewGroup parent = (ViewGroup) getParent();
437aea1ce51bcb218960d9a95495c3c22bc492351bfMichael Jurka        if (parent == null) return;
438aea1ce51bcb218960d9a95495c3c22bc492351bfMichael Jurka
4393d41198024fd5f27f84c9966683ca12333e370aeAdam Cohen        View overviewPanel = ((Launcher) getContext()).getOverviewPanel();
440bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        final int count = parent.getChildCount();
441bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (!isChildrenDrawingOrderEnabled()) {
442bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            for (int i = 0; i < count; i++) {
443bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                final View child = parent.getChildAt(i);
444bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                if (child == this) {
445bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    break;
446bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                } else {
4473d41198024fd5f27f84c9966683ca12333e370aeAdam Cohen                    if (child.getVisibility() == GONE || child == overviewPanel) {
448bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                        continue;
449bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    }
450bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    child.setVisibility(visibility);
451bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                }
452bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            }
453bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        } else {
454bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            throw new RuntimeException("Failed; can't get z-order of views");
455bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        }
456bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    }
457bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
4582a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    public void onWindowVisible() {
459e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        if (getVisibility() == VISIBLE) {
460e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mContent.setVisibility(VISIBLE);
461e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // We unload the widget previews when the UI is hidden, so need to reload pages
462e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Load the current page synchronously, and the neighboring pages asynchronously
463e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true);
464e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
465e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        }
466e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    }
467e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka
468e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    public void onTrimMemory() {
469e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        mContent.setVisibility(GONE);
470e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        // Clear the widget pages of all their subviews - this will trigger the widget previews
471e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        // to delete their bitmaps
472e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        mAppsCustomizePane.clearAllWidgetPages();
473e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    }
474e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka
47570d721061536e0634f6cfa8cd219759a83befceeWinson Chung    boolean isTransitioning() {
47670d721061536e0634f6cfa8cd219759a83befceeWinson Chung        return mInTransition;
47770d721061536e0634f6cfa8cd219759a83befceeWinson Chung    }
478785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung}
479