PhoneUi.java revision 8f11d06710c2c2be8e441ffe07c8fcd1195057be
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.animation.Animator;
20import android.animation.Animator.AnimatorListener;
21import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
23import android.app.Activity;
24import android.util.Log;
25import android.view.ActionMode;
26import android.view.Gravity;
27import android.view.KeyEvent;
28import android.view.Menu;
29import android.view.View;
30import android.webkit.WebView;
31import android.widget.FrameLayout;
32
33/**
34 * Ui for regular phone screen sizes
35 */
36public class PhoneUi extends BaseUi {
37
38    private static final String LOGTAG = "PhoneUi";
39    private static final float NAV_TAB_SCALE = 0.75f;
40
41    private TitleBarPhone mTitleBar;
42    private ActiveTabsPage mActiveTabsPage;
43    private boolean mUseQuickControls;
44    private PieControl mPieControl;
45    private NavScreen mNavScreen;
46
47    boolean mExtendedMenuOpen;
48    boolean mOptionsMenuOpen;
49
50    /**
51     * @param browser
52     * @param controller
53     */
54    public PhoneUi(Activity browser, UiController controller) {
55        super(browser, controller);
56        mTitleBar = new TitleBarPhone(mActivity, mUiController, this,
57                mContentView);
58        // mTitleBar will be always be shown in the fully loaded mode on
59        // phone
60        mTitleBar.setProgress(100);
61        mActivity.getActionBar().hide();
62        setUseQuickControls(BrowserSettings.getInstance().useQuickControls());
63    }
64
65    @Override
66    public void hideComboView() {
67        super.hideComboView();
68        mActivity.getActionBar().hide();
69    }
70
71    // lifecycle
72
73    @Override
74    public void onPause() {
75        // FIXME: This removes the active tabs page and resets the menu to
76        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
77        // but then we would need to save it in onSaveInstanceState and restore
78        // it in onCreate/onRestoreInstanceState
79        if (mActiveTabsPage != null) {
80            mUiController.removeActiveTabsPage(true);
81        }
82        super.onPause();
83    }
84
85    @Override
86    public void onDestroy() {
87        hideTitleBar();
88    }
89
90    @Override
91    public void editUrl(boolean clearInput) {
92        if (mUseQuickControls) {
93            getTitleBar().setShowProgressOnly(false);
94        }
95        super.editUrl(clearInput);
96    }
97
98    @Override
99    public boolean onBackKey() {
100        if (mActiveTabsPage != null) {
101            // if tab page is showing, hide it
102            mUiController.removeActiveTabsPage(true);
103            return true;
104        } else if (mNavScreen != null) {
105            mNavScreen.close();
106            return true;
107        }
108        return super.onBackKey();
109    }
110
111    @Override
112    public boolean dispatchKey(int code, KeyEvent event) {
113        if (!isComboViewShowing()) {
114            switch (code) {
115                case KeyEvent.KEYCODE_MENU:
116                    if (mNavScreen == null) {
117                        showNavScreen();
118                        return true;
119                    } else {
120                        mNavScreen.close();
121                        return true;
122                    }
123            }
124        }
125        return false;
126    }
127
128    @Override
129    public void onProgressChanged(Tab tab) {
130        if (tab.inForeground()) {
131            int progress = tab.getLoadProgress();
132            mTitleBar.setProgress(progress);
133            if (progress == 100) {
134                if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
135                    hideTitleBar();
136                    if (mUseQuickControls) {
137                        mTitleBar.setShowProgressOnly(false);
138                    }
139                }
140            } else {
141                if (!mOptionsMenuOpen || mExtendedMenuOpen) {
142                    if (mUseQuickControls && !mTitleBar.isEditingUrl()) {
143                        mTitleBar.setShowProgressOnly(true);
144                        setTitleGravity(Gravity.TOP);
145                    }
146                    showTitleBar();
147                }
148            }
149        }
150    }
151
152    @Override
153    public void setActiveTab(final Tab tab) {
154        captureTab(mActiveTab);
155        super.setActiveTab(tab, true);
156        setActiveTab(tab, true);
157    }
158
159    @Override
160    void setActiveTab(Tab tab, boolean needsAttaching) {
161        BrowserWebView view = (BrowserWebView) tab.getWebView();
162        // TabControl.setCurrentTab has been called before this,
163        // so the tab is guaranteed to have a webview
164        if (view == null) {
165            Log.e(LOGTAG, "active tab with no webview detected");
166            return;
167        }
168        // Request focus on the top window.
169        if (mUseQuickControls) {
170            mPieControl.forceToTop(mContentView);
171            view.setScrollListener(null);
172        } else {
173            // check if title bar is already attached by animation
174            if (mTitleBar.getParent() == null) {
175                view.setEmbeddedTitleBar(mTitleBar);
176            }
177        }
178        if (tab.isInVoiceSearchMode()) {
179            showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults());
180        } else {
181            revertVoiceTitleBar(tab);
182        }
183        updateLockIconToLatest(tab);
184        tab.getTopWindow().requestFocus();
185    }
186
187    @Override
188    protected TitleBarBase getTitleBar() {
189        return mTitleBar;
190    }
191
192    // active tabs page
193
194    @Override
195    public void showActiveTabsPage() {
196        captureTab(mActiveTab);
197        mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
198        mTitleBar.setVisibility(View.GONE);
199        hideTitleBar();
200        mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
201        mActiveTabsPage.requestFocus();
202    }
203
204    /**
205     * Remove the active tabs page.
206     */
207    @Override
208    public void removeActiveTabsPage() {
209        mContentView.removeView(mActiveTabsPage);
210        mTitleBar.setVisibility(View.VISIBLE);
211        mActiveTabsPage = null;
212    }
213
214    @Override
215    public boolean showsWeb() {
216        return super.showsWeb() && mActiveTabsPage == null;
217    }
218
219    // menu handling callbacks
220
221    @Override
222    public void onContextMenuCreated(Menu menu) {
223        hideTitleBar();
224    }
225
226    @Override
227    public void onContextMenuClosed(Menu menu, boolean inLoad) {
228        if (inLoad) {
229            showTitleBar();
230        }
231    }
232
233    // action mode callbacks
234
235    @Override
236    public void onActionModeStarted(ActionMode mode) {
237        hideTitleBar();
238    }
239
240    @Override
241    public void onActionModeFinished(boolean inLoad) {
242        if (inLoad) {
243            if (mUseQuickControls) {
244                mTitleBar.setShowProgressOnly(true);
245            }
246            showTitleBar();
247        }
248        mActivity.getActionBar().hide();
249    }
250
251    @Override
252    protected void setTitleGravity(int gravity) {
253        if (mUseQuickControls) {
254            FrameLayout.LayoutParams lp =
255                    (FrameLayout.LayoutParams) getTitleBar().getLayoutParams();
256            lp.gravity = gravity;
257            getTitleBar().setLayoutParams(lp);
258        } else {
259            super.setTitleGravity(gravity);
260        }
261    }
262
263    private void setUseQuickControls(boolean useQuickControls) {
264        mUseQuickControls = useQuickControls;
265        getTitleBar().setUseQuickControls(mUseQuickControls);
266        if (useQuickControls) {
267            mPieControl = new PieControl(mActivity, mUiController, this);
268            mPieControl.attachToContainer(mContentView);
269            WebView web = getWebView();
270            if (web != null) {
271                web.setEmbeddedTitleBar(null);
272            }
273        } else {
274            if (mPieControl != null) {
275                mPieControl.removeFromContainer(mContentView);
276            }
277            WebView web = getWebView();
278            if (web != null) {
279                web.setEmbeddedTitleBar(mTitleBar);
280            }
281            setTitleGravity(Gravity.NO_GRAVITY);
282        }
283    }
284
285    @Override
286    protected void captureTab(final Tab tab) {
287        if (mUseQuickControls) {
288            super.captureTab(tab);
289        } else {
290            captureTab(tab,
291                    mActivity.getWindowManager().getDefaultDisplay().getWidth(),
292                    mActivity.getWindowManager().getDefaultDisplay().getHeight());
293        }
294    }
295
296    void showNavScreen() {
297        captureTab(mActiveTab);
298        mNavScreen = new NavScreen(mActivity, mUiController, this);
299        WebView web = getWebView();
300        if (web != null) {
301            int w = web.getWidth();
302            int h = web.getHeight();
303            mNavScreen.setTabDimensions((int) (w * NAV_TAB_SCALE),
304                    (int) (h * NAV_TAB_SCALE));
305        }
306        // Add the custom view to its container.
307        mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_GRAVITY_CENTER);
308        ObjectAnimator animx = ObjectAnimator.ofFloat(mContentView,
309                "scaleX", 1.0f, 0.85f);
310        ObjectAnimator animy = ObjectAnimator.ofFloat(mContentView,
311                "scaleY", 1.0f, 0.85f);
312        AnimatorSet anims = new AnimatorSet();
313        anims.setDuration(200);
314        anims.addListener(new AnimatorListener() {
315
316            @Override
317            public void onAnimationCancel(Animator animation) {
318                finishShowNavScreen();
319            }
320
321            @Override
322            public void onAnimationEnd(Animator animation) {
323                finishShowNavScreen();
324            }
325
326            @Override
327            public void onAnimationRepeat(Animator animation) {
328            }
329
330            @Override
331            public void onAnimationStart(Animator animation) {
332            }
333        });
334        anims.playTogether(animx, animy);
335        anims.start();
336    }
337
338    private void finishShowNavScreen() {
339        // Hide the content view.
340        mContentView.setVisibility(View.GONE);
341        mContentView.setScaleX(1.0f);
342        mContentView.setScaleY(1.0f);
343        // Finally show the custom view container.
344        mCustomViewContainer.setVisibility(View.VISIBLE);
345        mCustomViewContainer.bringToFront();
346    }
347
348    void hideNavScreen(boolean animateToPage) {
349        if (mNavScreen == null) return;
350        if (animateToPage) {
351            ObjectAnimator animx = ObjectAnimator.ofFloat(mNavScreen, "scaleX",
352                    1.0f, 1.2f);
353            ObjectAnimator animy = ObjectAnimator.ofFloat(mNavScreen, "scaleY",
354                    1.0f, 1.2f);
355            AnimatorSet anims = new AnimatorSet();
356            anims.setDuration(200);
357            anims.addListener(new AnimatorListener() {
358
359                @Override
360                public void onAnimationCancel(Animator animation) {
361                    finishHideNavScreen();
362                }
363
364                @Override
365                public void onAnimationEnd(Animator animation) {
366                    finishHideNavScreen();
367                }
368
369                @Override
370                public void onAnimationRepeat(Animator animation) {
371                }
372
373                @Override
374                public void onAnimationStart(Animator animation) {
375                }
376            });
377            anims.playTogether(animx, animy);
378            anims.start();
379        } else {
380            finishHideNavScreen();
381        }
382
383    }
384
385    private void finishHideNavScreen() {
386        // Hide the custom view.
387        mNavScreen.setVisibility(View.GONE);
388        // Remove the custom view from its container.
389        mCustomViewContainer.removeView(mNavScreen);
390        mNavScreen = null;
391        mCustomViewContainer.setVisibility(View.GONE);
392        // Show the content view.
393        mContentView.setVisibility(View.VISIBLE);
394    }
395
396}
397