• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.browser;
18 
19 import android.animation.Animator;
20 import android.animation.Animator.AnimatorListener;
21 import android.animation.ObjectAnimator;
22 import android.content.Context;
23 import android.content.res.Resources;
24 import android.view.Gravity;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.view.ViewStub;
29 import android.view.animation.Animation;
30 import android.view.animation.Animation.AnimationListener;
31 import android.view.animation.AnimationUtils;
32 import android.view.animation.DecelerateInterpolator;
33 import android.webkit.WebView;
34 import android.widget.AbsoluteLayout;
35 import android.widget.FrameLayout;
36 import android.widget.RelativeLayout;
37 
38 
39 /**
40  * Base class for a title bar used by the browser.
41  */
42 public class TitleBar extends RelativeLayout {
43 
44     private static final int PROGRESS_MAX = 100;
45     private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
46 
47     private UiController mUiController;
48     private BaseUi mBaseUi;
49     private FrameLayout mParent;
50     private PageProgressView mProgress;
51 
52     private AutologinBar mAutoLogin;
53     private NavigationBarBase mNavBar;
54     private boolean mUseQuickControls;
55     private SnapshotBar mSnapshotBar;
56 
57     //state
58     private boolean mShowing;
59     private boolean mInLoad;
60     private boolean mSkipTitleBarAnimations;
61     private Animator mTitleBarAnimator;
62 
TitleBar(Context context, UiController controller, BaseUi ui, FrameLayout parent)63     public TitleBar(Context context, UiController controller, BaseUi ui,
64             FrameLayout parent) {
65         super(context, null);
66         mUiController = controller;
67         mBaseUi = ui;
68         mParent = parent;
69         initLayout(context);
70     }
71 
initLayout(Context context)72     private void initLayout(Context context) {
73         LayoutInflater factory = LayoutInflater.from(context);
74         factory.inflate(R.layout.title_bar, this);
75         mProgress = (PageProgressView) findViewById(R.id.progress);
76         mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
77         mNavBar.setTitleBar(this);
78     }
79 
inflateAutoLoginBar()80     private void inflateAutoLoginBar() {
81         if (mAutoLogin != null) {
82             return;
83         }
84 
85         ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
86         mAutoLogin = (AutologinBar) stub.inflate();
87         mAutoLogin.setTitleBar(this);
88     }
89 
inflateSnapshotBar()90     private void inflateSnapshotBar() {
91         if (mSnapshotBar != null) {
92             return;
93         }
94 
95         ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
96         mSnapshotBar = (SnapshotBar) stub.inflate();
97         mSnapshotBar.setTitleBar(this);
98     }
99 
getUi()100     public BaseUi getUi() {
101         return mBaseUi;
102     }
103 
getUiController()104     public UiController getUiController() {
105         return mUiController;
106     }
107 
setUseQuickControls(boolean use)108     public void setUseQuickControls(boolean use) {
109         mUseQuickControls = use;
110         setLayoutParams(makeLayoutParams());
111     }
112 
setShowProgressOnly(boolean progress)113     void setShowProgressOnly(boolean progress) {
114         if (progress && !wantsToBeVisible()) {
115             mNavBar.setVisibility(View.GONE);
116         } else {
117             mNavBar.setVisibility(View.VISIBLE);
118         }
119     }
120 
setSkipTitleBarAnimations(boolean skip)121     void setSkipTitleBarAnimations(boolean skip) {
122         mSkipTitleBarAnimations = skip;
123     }
124 
setupTitleBarAnimator(Animator animator)125     void setupTitleBarAnimator(Animator animator) {
126         Resources res = mContext.getResources();
127         int duration = res.getInteger(R.integer.titlebar_animation_duration);
128         animator.setInterpolator(new DecelerateInterpolator(
129                 ANIM_TITLEBAR_DECELERATE));
130         animator.setDuration(duration);
131     }
132 
show()133     void show() {
134         if (mUseQuickControls) {
135             mParent.addView(this);
136         } else {
137             if (!mSkipTitleBarAnimations) {
138                 cancelTitleBarAnimation(false);
139                 int visibleHeight = getVisibleTitleHeight();
140                 float startPos = (-getEmbeddedHeight() + visibleHeight);
141                 if (getTranslationY() != 0) {
142                     startPos = Math.max(startPos, getTranslationY());
143                 }
144                 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
145                         "translationY",
146                         startPos, 0);
147                 setupTitleBarAnimator(mTitleBarAnimator);
148                 mTitleBarAnimator.start();
149             }
150             mBaseUi.setTitleGravity(Gravity.TOP);
151         }
152         mShowing = true;
153     }
154 
hide()155     void hide() {
156         if (mUseQuickControls) {
157             mParent.removeView(this);
158         } else {
159             if (!mSkipTitleBarAnimations) {
160                 cancelTitleBarAnimation(false);
161                 int visibleHeight = getVisibleTitleHeight();
162                 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
163                         "translationY", getTranslationY(),
164                         (-getEmbeddedHeight() + visibleHeight));
165                 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
166                 setupTitleBarAnimator(mTitleBarAnimator);
167                 mTitleBarAnimator.start();
168             } else {
169                 mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
170             }
171         }
172         mShowing = false;
173     }
174 
isShowing()175     boolean isShowing() {
176         return mShowing;
177     }
178 
cancelTitleBarAnimation(boolean reset)179     void cancelTitleBarAnimation(boolean reset) {
180         if (mTitleBarAnimator != null) {
181             mTitleBarAnimator.cancel();
182             mTitleBarAnimator = null;
183         }
184         if (reset) {
185             setTranslationY(0);
186         }
187     }
188 
189     private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
190 
191         boolean mWasCanceled;
192         @Override
193         public void onAnimationStart(Animator animation) {
194             mWasCanceled = false;
195         }
196 
197         @Override
198         public void onAnimationRepeat(Animator animation) {
199         }
200 
201         @Override
202         public void onAnimationEnd(Animator animation) {
203             if (!mWasCanceled) {
204                 setTranslationY(0);
205             }
206             mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
207         }
208 
209         @Override
210         public void onAnimationCancel(Animator animation) {
211             mWasCanceled = true;
212         }
213     };
214 
getVisibleTitleHeight()215     private int getVisibleTitleHeight() {
216         Tab tab = mBaseUi.getActiveTab();
217         WebView webview = tab != null ? tab.getWebView() : null;
218         return webview != null ? webview.getVisibleTitleHeight() : 0;
219     }
220 
221     /**
222      * Update the progress, from 0 to 100.
223      */
setProgress(int newProgress)224     public void setProgress(int newProgress) {
225         if (newProgress >= PROGRESS_MAX) {
226             mProgress.setProgress(PageProgressView.MAX_PROGRESS);
227             mProgress.setVisibility(View.GONE);
228             mInLoad = false;
229             mNavBar.onProgressStopped();
230             // check if needs to be hidden
231             if (!isEditingUrl() && !wantsToBeVisible()) {
232                 hide();
233                 if (mUseQuickControls) {
234                     setShowProgressOnly(false);
235                 }
236             }
237         } else {
238             if (!mInLoad) {
239                 mProgress.setVisibility(View.VISIBLE);
240                 mInLoad = true;
241                 mNavBar.onProgressStarted();
242             }
243             mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
244                     / PROGRESS_MAX);
245             if (!mShowing) {
246                 if (mUseQuickControls && !isEditingUrl()) {
247                     setShowProgressOnly(true);
248                 }
249                 show();
250             }
251         }
252     }
253 
getEmbeddedHeight()254     public int getEmbeddedHeight() {
255         int height = mNavBar.getHeight();
256         if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
257             height += mAutoLogin.getHeight();
258         }
259         return height;
260     }
261 
updateAutoLogin(Tab tab, boolean animate)262     public void updateAutoLogin(Tab tab, boolean animate) {
263         if (mAutoLogin == null) {
264             if  (tab.getDeviceAccountLogin() == null) {
265                 return;
266             }
267             inflateAutoLoginBar();
268         }
269         mAutoLogin.updateAutoLogin(tab, animate);
270     }
271 
showAutoLogin(boolean animate)272     public void showAutoLogin(boolean animate) {
273         if (mUseQuickControls) {
274             mBaseUi.showTitleBar();
275         }
276         if (mAutoLogin == null) {
277             inflateAutoLoginBar();
278         }
279         mAutoLogin.setVisibility(View.VISIBLE);
280         if (animate) {
281             mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
282                     getContext(), R.anim.autologin_enter));
283         }
284     }
285 
hideAutoLogin(boolean animate)286     public void hideAutoLogin(boolean animate) {
287         if (mUseQuickControls) {
288             mBaseUi.hideTitleBar();
289             mAutoLogin.setVisibility(View.GONE);
290             mBaseUi.refreshWebView();
291         } else {
292             if (animate) {
293                 Animation anim = AnimationUtils.loadAnimation(getContext(),
294                         R.anim.autologin_exit);
295                 anim.setAnimationListener(new AnimationListener() {
296                     @Override
297                     public void onAnimationEnd(Animation a) {
298                         mAutoLogin.setVisibility(View.GONE);
299                         mBaseUi.refreshWebView();
300                     }
301 
302                     @Override
303                     public void onAnimationStart(Animation a) {
304                     }
305 
306                     @Override
307                     public void onAnimationRepeat(Animation a) {
308                     }
309                 });
310                 mAutoLogin.startAnimation(anim);
311             } else if (mAutoLogin.getAnimation() == null) {
312                 mAutoLogin.setVisibility(View.GONE);
313                 mBaseUi.refreshWebView();
314             }
315         }
316     }
317 
wantsToBeVisible()318     public boolean wantsToBeVisible() {
319         return inAutoLogin()
320             || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
321                     && mSnapshotBar.isAnimating());
322     }
323 
inAutoLogin()324     private boolean inAutoLogin() {
325         return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
326     }
327 
isEditingUrl()328     public boolean isEditingUrl() {
329         return mNavBar.isEditingUrl();
330     }
331 
getCurrentWebView()332     public WebView getCurrentWebView() {
333         Tab t = mBaseUi.getActiveTab();
334         if (t != null) {
335             return t.getWebView();
336         } else {
337             return null;
338         }
339     }
340 
getProgressView()341     public PageProgressView getProgressView() {
342         return mProgress;
343     }
344 
getNavigationBar()345     public NavigationBarBase getNavigationBar() {
346         return mNavBar;
347     }
348 
useQuickControls()349     public boolean useQuickControls() {
350         return mUseQuickControls;
351     }
352 
isInLoad()353     public boolean isInLoad() {
354         return mInLoad;
355     }
356 
makeLayoutParams()357     private ViewGroup.LayoutParams makeLayoutParams() {
358         if (mUseQuickControls) {
359             return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
360                     LayoutParams.WRAP_CONTENT);
361         } else {
362             return new AbsoluteLayout.LayoutParams(
363                     LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
364                     0, 0);
365         }
366     }
367 
368     @Override
focusSearch(View focused, int dir)369     public View focusSearch(View focused, int dir) {
370         if (FOCUS_DOWN == dir && hasFocus()) {
371             return getCurrentWebView();
372         }
373         return super.focusSearch(focused, dir);
374     }
375 
onTabDataChanged(Tab tab)376     public void onTabDataChanged(Tab tab) {
377         if (mSnapshotBar != null) {
378             mSnapshotBar.onTabDataChanged(tab);
379         }
380 
381         if (tab.isSnapshot()) {
382             inflateSnapshotBar();
383             mSnapshotBar.setVisibility(VISIBLE);
384             mNavBar.setVisibility(GONE);
385         } else {
386             if (mSnapshotBar != null) {
387                 mSnapshotBar.setVisibility(GONE);
388             }
389             mNavBar.setVisibility(VISIBLE);
390         }
391     }
392 
393 }
394