blob: bb0eec56444e4525ecf1f997b755b106ca1fb3ee [file] [log] [blame]
John Reck0f602f32011-07-07 15:38:43 -07001/*
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.ObjectAnimator;
22import android.content.Context;
23import android.content.res.Resources;
John Reck0f602f32011-07-07 15:38:43 -070024import android.view.LayoutInflater;
25import android.view.View;
26import android.view.ViewGroup;
Ben Murdochd51bb572011-08-17 20:42:02 +010027import android.view.ViewStub;
John Reck0f602f32011-07-07 15:38:43 -070028import android.view.animation.Animation;
29import android.view.animation.Animation.AnimationListener;
30import android.view.animation.AnimationUtils;
31import android.view.animation.DecelerateInterpolator;
32import android.webkit.WebView;
John Reck0f602f32011-07-07 15:38:43 -070033import android.widget.FrameLayout;
34import android.widget.RelativeLayout;
35
36
37/**
38 * Base class for a title bar used by the browser.
39 */
40public class TitleBar extends RelativeLayout {
41
42 private static final int PROGRESS_MAX = 100;
43 private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
44
45 private UiController mUiController;
46 private BaseUi mBaseUi;
47 private FrameLayout mParent;
48 private PageProgressView mProgress;
49
50 private AutologinBar mAutoLogin;
51 private NavigationBarBase mNavBar;
52 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070053 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070054
55 //state
56 private boolean mShowing;
57 private boolean mInLoad;
58 private boolean mSkipTitleBarAnimations;
59 private Animator mTitleBarAnimator;
60
61 public TitleBar(Context context, UiController controller, BaseUi ui,
62 FrameLayout parent) {
63 super(context, null);
64 mUiController = controller;
65 mBaseUi = ui;
66 mParent = parent;
67 initLayout(context);
Michael Kolb4923c222012-04-02 16:18:36 -070068 mParent.addView(this, makeLayoutParams());
John Reck0f602f32011-07-07 15:38:43 -070069 }
70
71 private void initLayout(Context context) {
72 LayoutInflater factory = LayoutInflater.from(context);
73 factory.inflate(R.layout.title_bar, this);
74 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070075 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
76 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010077 }
78
79 private void inflateAutoLoginBar() {
80 if (mAutoLogin != null) {
81 return;
82 }
83
84 ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
85 mAutoLogin = (AutologinBar) stub.inflate();
86 mAutoLogin.setTitleBar(this);
87 }
88
89 private void inflateSnapshotBar() {
90 if (mSnapshotBar != null) {
91 return;
92 }
93
94 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
95 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -070096 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070097 }
98
99 public BaseUi getUi() {
100 return mBaseUi;
101 }
102
103 public UiController getUiController() {
104 return mUiController;
105 }
106
107 public void setUseQuickControls(boolean use) {
108 mUseQuickControls = use;
Michael Kolb4923c222012-04-02 16:18:36 -0700109 if (use) {
110 this.setVisibility(View.GONE);
111 } else {
112 this.setVisibility(View.VISIBLE);
113 }
John Reck0f602f32011-07-07 15:38:43 -0700114 }
115
116 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700117 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700118 mNavBar.setVisibility(View.GONE);
119 } else {
120 mNavBar.setVisibility(View.VISIBLE);
121 }
122 }
123
124 void setSkipTitleBarAnimations(boolean skip) {
125 mSkipTitleBarAnimations = skip;
126 }
127
128 void setupTitleBarAnimator(Animator animator) {
129 Resources res = mContext.getResources();
130 int duration = res.getInteger(R.integer.titlebar_animation_duration);
131 animator.setInterpolator(new DecelerateInterpolator(
132 ANIM_TITLEBAR_DECELERATE));
133 animator.setDuration(duration);
134 }
135
136 void show() {
137 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700138 this.setVisibility(View.VISIBLE);
139 this.setTranslationY(0);
John Reck0f602f32011-07-07 15:38:43 -0700140 } else {
141 if (!mSkipTitleBarAnimations) {
142 cancelTitleBarAnimation(false);
143 int visibleHeight = getVisibleTitleHeight();
144 float startPos = (-getEmbeddedHeight() + visibleHeight);
145 if (getTranslationY() != 0) {
146 startPos = Math.max(startPos, getTranslationY());
147 }
148 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
149 "translationY",
150 startPos, 0);
151 setupTitleBarAnimator(mTitleBarAnimator);
152 mTitleBarAnimator.start();
153 }
John Reck0f602f32011-07-07 15:38:43 -0700154 }
155 mShowing = true;
156 }
157
158 void hide() {
159 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700160 this.setVisibility(View.GONE);
John Reck0f602f32011-07-07 15:38:43 -0700161 } else {
162 if (!mSkipTitleBarAnimations) {
163 cancelTitleBarAnimation(false);
164 int visibleHeight = getVisibleTitleHeight();
165 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
166 "translationY", getTranslationY(),
167 (-getEmbeddedHeight() + visibleHeight));
168 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
169 setupTitleBarAnimator(mTitleBarAnimator);
170 mTitleBarAnimator.start();
171 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700172 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700173 }
174 }
175 mShowing = false;
176 }
177
178 boolean isShowing() {
179 return mShowing;
180 }
181
182 void cancelTitleBarAnimation(boolean reset) {
183 if (mTitleBarAnimator != null) {
184 mTitleBarAnimator.cancel();
185 mTitleBarAnimator = null;
186 }
187 if (reset) {
188 setTranslationY(0);
189 }
190 }
191
192 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
193
John Reck0f602f32011-07-07 15:38:43 -0700194 @Override
195 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700196 }
197
198 @Override
199 public void onAnimationRepeat(Animator animation) {
200 }
201
202 @Override
203 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700204 // update position
205 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700206 }
207
208 @Override
209 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700210 }
211 };
212
213 private int getVisibleTitleHeight() {
214 Tab tab = mBaseUi.getActiveTab();
215 WebView webview = tab != null ? tab.getWebView() : null;
216 return webview != null ? webview.getVisibleTitleHeight() : 0;
217 }
218
219 /**
220 * Update the progress, from 0 to 100.
221 */
222 public void setProgress(int newProgress) {
223 if (newProgress >= PROGRESS_MAX) {
224 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
225 mProgress.setVisibility(View.GONE);
226 mInLoad = false;
227 mNavBar.onProgressStopped();
228 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700229 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700230 hide();
231 if (mUseQuickControls) {
232 setShowProgressOnly(false);
233 }
234 }
235 } else {
236 if (!mInLoad) {
237 mProgress.setVisibility(View.VISIBLE);
238 mInLoad = true;
239 mNavBar.onProgressStarted();
240 }
241 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
242 / PROGRESS_MAX);
243 if (!mShowing) {
244 if (mUseQuickControls && !isEditingUrl()) {
245 setShowProgressOnly(true);
246 }
247 show();
248 }
249 }
250 }
251
252 public int getEmbeddedHeight() {
Michael Kolb4923c222012-04-02 16:18:36 -0700253 if (mUseQuickControls) return 0;
John Reck0f602f32011-07-07 15:38:43 -0700254 int height = mNavBar.getHeight();
Ben Murdochd51bb572011-08-17 20:42:02 +0100255 if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
John Reck0f602f32011-07-07 15:38:43 -0700256 height += mAutoLogin.getHeight();
257 }
258 return height;
259 }
260
261 public void updateAutoLogin(Tab tab, boolean animate) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100262 if (mAutoLogin == null) {
263 if (tab.getDeviceAccountLogin() == null) {
264 return;
265 }
266 inflateAutoLoginBar();
267 }
John Reck0f602f32011-07-07 15:38:43 -0700268 mAutoLogin.updateAutoLogin(tab, animate);
269 }
270
271 public void showAutoLogin(boolean animate) {
272 if (mUseQuickControls) {
273 mBaseUi.showTitleBar();
274 }
Ben Murdochd51bb572011-08-17 20:42:02 +0100275 if (mAutoLogin == null) {
276 inflateAutoLoginBar();
277 }
John Reck0f602f32011-07-07 15:38:43 -0700278 mAutoLogin.setVisibility(View.VISIBLE);
279 if (animate) {
280 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
281 getContext(), R.anim.autologin_enter));
282 }
283 }
284
285 public void hideAutoLogin(boolean animate) {
286 if (mUseQuickControls) {
287 mBaseUi.hideTitleBar();
288 mAutoLogin.setVisibility(View.GONE);
289 mBaseUi.refreshWebView();
290 } else {
291 if (animate) {
292 Animation anim = AnimationUtils.loadAnimation(getContext(),
293 R.anim.autologin_exit);
294 anim.setAnimationListener(new AnimationListener() {
295 @Override
296 public void onAnimationEnd(Animation a) {
297 mAutoLogin.setVisibility(View.GONE);
298 mBaseUi.refreshWebView();
299 }
300
301 @Override
302 public void onAnimationStart(Animation a) {
303 }
304
305 @Override
306 public void onAnimationRepeat(Animation a) {
307 }
308 });
309 mAutoLogin.startAnimation(anim);
310 } else if (mAutoLogin.getAnimation() == null) {
311 mAutoLogin.setVisibility(View.GONE);
312 mBaseUi.refreshWebView();
313 }
314 }
315 }
316
John Reckef654f12011-07-12 16:42:08 -0700317 public boolean wantsToBeVisible() {
318 return inAutoLogin()
Ben Murdochd51bb572011-08-17 20:42:02 +0100319 || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700320 && mSnapshotBar.isAnimating());
321 }
322
323 private boolean inAutoLogin() {
Ben Murdochd51bb572011-08-17 20:42:02 +0100324 return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
John Reck0f602f32011-07-07 15:38:43 -0700325 }
326
327 public boolean isEditingUrl() {
328 return mNavBar.isEditingUrl();
329 }
330
331 public WebView getCurrentWebView() {
332 Tab t = mBaseUi.getActiveTab();
333 if (t != null) {
334 return t.getWebView();
335 } else {
336 return null;
337 }
338 }
339
340 public PageProgressView getProgressView() {
341 return mProgress;
342 }
343
344 public NavigationBarBase getNavigationBar() {
345 return mNavBar;
346 }
347
348 public boolean useQuickControls() {
349 return mUseQuickControls;
350 }
351
352 public boolean isInLoad() {
353 return mInLoad;
354 }
355
356 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700357 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
358 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700359 }
360
361 @Override
362 public View focusSearch(View focused, int dir) {
363 if (FOCUS_DOWN == dir && hasFocus()) {
364 return getCurrentWebView();
365 }
366 return super.focusSearch(focused, dir);
367 }
368
John Reckef654f12011-07-12 16:42:08 -0700369 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100370 if (mSnapshotBar != null) {
371 mSnapshotBar.onTabDataChanged(tab);
372 }
373
John Reckef654f12011-07-12 16:42:08 -0700374 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100375 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700376 mSnapshotBar.setVisibility(VISIBLE);
377 mNavBar.setVisibility(GONE);
378 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100379 if (mSnapshotBar != null) {
380 mSnapshotBar.setVisibility(GONE);
381 }
John Reckef654f12011-07-12 16:42:08 -0700382 mNavBar.setVisibility(VISIBLE);
383 }
384 }
385
Michael Kolb4923c222012-04-02 16:18:36 -0700386 public void onScrollChanged() {
387 if (!mShowing) {
388 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
389 }
390 }
391
John Reck0f602f32011-07-07 15:38:43 -0700392}