blob: 9b2a947544e03f1034620c6af6e1ff07753cdb05 [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;
Michael Kolb57059a82012-04-30 14:32:03 -070023import android.content.res.Configuration;
John Reck0f602f32011-07-07 15:38:43 -070024import android.content.res.Resources;
John Reck0f602f32011-07-07 15:38:43 -070025import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
Ben Murdochd51bb572011-08-17 20:42:02 +010028import android.view.ViewStub;
John Reck0f602f32011-07-07 15:38:43 -070029import android.view.animation.Animation;
30import android.view.animation.Animation.AnimationListener;
31import android.view.animation.AnimationUtils;
32import android.view.animation.DecelerateInterpolator;
33import android.webkit.WebView;
John Reck0f602f32011-07-07 15:38:43 -070034import android.widget.FrameLayout;
35import android.widget.RelativeLayout;
36
37
38/**
39 * Base class for a title bar used by the browser.
40 */
41public class TitleBar extends RelativeLayout {
42
43 private static final int PROGRESS_MAX = 100;
44 private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
45
46 private UiController mUiController;
47 private BaseUi mBaseUi;
John Reck2711fab2012-05-18 21:38:59 -070048 private FrameLayout mContentView;
John Reck0f602f32011-07-07 15:38:43 -070049 private PageProgressView mProgress;
50
51 private AutologinBar mAutoLogin;
52 private NavigationBarBase mNavBar;
53 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070054 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070055
56 //state
57 private boolean mShowing;
58 private boolean mInLoad;
59 private boolean mSkipTitleBarAnimations;
60 private Animator mTitleBarAnimator;
John Reck2711fab2012-05-18 21:38:59 -070061 private boolean mIsFixedTitleBar;
John Reck0f602f32011-07-07 15:38:43 -070062
63 public TitleBar(Context context, UiController controller, BaseUi ui,
John Reck2711fab2012-05-18 21:38:59 -070064 FrameLayout contentView) {
John Reck0f602f32011-07-07 15:38:43 -070065 super(context, null);
66 mUiController = controller;
67 mBaseUi = ui;
John Reck2711fab2012-05-18 21:38:59 -070068 mContentView = contentView;
John Reck0f602f32011-07-07 15:38:43 -070069 initLayout(context);
John Reck2711fab2012-05-18 21:38:59 -070070 setFixedTitleBar(!mContext.getResources().getBoolean(R.bool.hide_title));
John Reck0f602f32011-07-07 15:38:43 -070071 }
72
73 private void initLayout(Context context) {
74 LayoutInflater factory = LayoutInflater.from(context);
75 factory.inflate(R.layout.title_bar, this);
76 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070077 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
78 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010079 }
80
81 private void inflateAutoLoginBar() {
82 if (mAutoLogin != null) {
83 return;
84 }
85
86 ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
87 mAutoLogin = (AutologinBar) stub.inflate();
88 mAutoLogin.setTitleBar(this);
89 }
90
91 private void inflateSnapshotBar() {
92 if (mSnapshotBar != null) {
93 return;
94 }
95
96 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
97 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -070098 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070099 }
100
Michael Kolb57059a82012-04-30 14:32:03 -0700101 @Override
102 protected void onConfigurationChanged(Configuration config) {
103 super.onConfigurationChanged(config);
John Reck2711fab2012-05-18 21:38:59 -0700104 setFixedTitleBar(!mContext.getResources().getBoolean(R.bool.hide_title));
105 }
106
107 @Override
108 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
109 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
110 if (mIsFixedTitleBar) {
111 int margin = getMeasuredHeight() - calculateEmbeddedHeight();
112 mBaseUi.setContentViewMarginTop(-margin);
113 }
114 }
115
116 private void setFixedTitleBar(boolean isFixed) {
117 // If getParent() returns null, we are initializing
118 ViewGroup parent = (ViewGroup)getParent();
119 if (mIsFixedTitleBar == isFixed && parent != null) return;
120 mIsFixedTitleBar = isFixed;
121 setSkipTitleBarAnimations(true);
122 show();
123 setSkipTitleBarAnimations(false);
124 if (parent != null) {
125 parent.removeView(this);
126 }
127 if (mIsFixedTitleBar) {
128 mBaseUi.addFixedTitleBar(this);
129 } else {
130 mContentView.addView(this, makeLayoutParams());
131 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700132 }
133 }
134
John Reck0f602f32011-07-07 15:38:43 -0700135 public BaseUi getUi() {
136 return mBaseUi;
137 }
138
139 public UiController getUiController() {
140 return mUiController;
141 }
142
143 public void setUseQuickControls(boolean use) {
144 mUseQuickControls = use;
Michael Kolb4923c222012-04-02 16:18:36 -0700145 if (use) {
146 this.setVisibility(View.GONE);
147 } else {
148 this.setVisibility(View.VISIBLE);
149 }
John Reck0f602f32011-07-07 15:38:43 -0700150 }
151
152 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700153 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700154 mNavBar.setVisibility(View.GONE);
155 } else {
156 mNavBar.setVisibility(View.VISIBLE);
157 }
158 }
159
160 void setSkipTitleBarAnimations(boolean skip) {
161 mSkipTitleBarAnimations = skip;
162 }
163
164 void setupTitleBarAnimator(Animator animator) {
165 Resources res = mContext.getResources();
166 int duration = res.getInteger(R.integer.titlebar_animation_duration);
167 animator.setInterpolator(new DecelerateInterpolator(
168 ANIM_TITLEBAR_DECELERATE));
169 animator.setDuration(duration);
170 }
171
172 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700173 cancelTitleBarAnimation(false);
174 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700175 this.setVisibility(View.VISIBLE);
176 this.setTranslationY(0);
John Reck0f602f32011-07-07 15:38:43 -0700177 } else {
John Reck2711fab2012-05-18 21:38:59 -0700178 int visibleHeight = getVisibleTitleHeight();
179 float startPos = (-getEmbeddedHeight() + visibleHeight);
180 if (getTranslationY() != 0) {
181 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700182 }
John Reck2711fab2012-05-18 21:38:59 -0700183 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
184 "translationY",
185 startPos, 0);
186 setupTitleBarAnimator(mTitleBarAnimator);
187 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700188 }
189 mShowing = true;
190 }
191
192 void hide() {
193 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700194 this.setVisibility(View.GONE);
John Reck0f602f32011-07-07 15:38:43 -0700195 } else {
John Reck2711fab2012-05-18 21:38:59 -0700196 if (mIsFixedTitleBar) return;
John Reck0f602f32011-07-07 15:38:43 -0700197 if (!mSkipTitleBarAnimations) {
198 cancelTitleBarAnimation(false);
199 int visibleHeight = getVisibleTitleHeight();
200 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
201 "translationY", getTranslationY(),
202 (-getEmbeddedHeight() + visibleHeight));
203 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
204 setupTitleBarAnimator(mTitleBarAnimator);
205 mTitleBarAnimator.start();
206 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700207 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700208 }
209 }
210 mShowing = false;
211 }
212
213 boolean isShowing() {
214 return mShowing;
215 }
216
217 void cancelTitleBarAnimation(boolean reset) {
218 if (mTitleBarAnimator != null) {
219 mTitleBarAnimator.cancel();
220 mTitleBarAnimator = null;
221 }
222 if (reset) {
223 setTranslationY(0);
224 }
225 }
226
227 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
228
John Reck0f602f32011-07-07 15:38:43 -0700229 @Override
230 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700231 }
232
233 @Override
234 public void onAnimationRepeat(Animator animation) {
235 }
236
237 @Override
238 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700239 // update position
240 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700241 }
242
243 @Override
244 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700245 }
246 };
247
248 private int getVisibleTitleHeight() {
249 Tab tab = mBaseUi.getActiveTab();
250 WebView webview = tab != null ? tab.getWebView() : null;
251 return webview != null ? webview.getVisibleTitleHeight() : 0;
252 }
253
254 /**
255 * Update the progress, from 0 to 100.
256 */
257 public void setProgress(int newProgress) {
258 if (newProgress >= PROGRESS_MAX) {
259 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
260 mProgress.setVisibility(View.GONE);
261 mInLoad = false;
262 mNavBar.onProgressStopped();
263 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700264 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700265 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700266 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700267 } else {
268 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700269 }
270 }
271 } else {
272 if (!mInLoad) {
273 mProgress.setVisibility(View.VISIBLE);
274 mInLoad = true;
275 mNavBar.onProgressStarted();
276 }
277 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
278 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700279 if (mUseQuickControls && !isEditingUrl()) {
280 setShowProgressOnly(true);
281 }
John Reck0f602f32011-07-07 15:38:43 -0700282 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700283 show();
284 }
285 }
286 }
287
288 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700289 if (mUseQuickControls || mIsFixedTitleBar) return 0;
290 return calculateEmbeddedHeight();
291 }
292
293 private int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700294 int height = mNavBar.getHeight();
Ben Murdochd51bb572011-08-17 20:42:02 +0100295 if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
John Reck0f602f32011-07-07 15:38:43 -0700296 height += mAutoLogin.getHeight();
297 }
298 return height;
299 }
300
301 public void updateAutoLogin(Tab tab, boolean animate) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100302 if (mAutoLogin == null) {
303 if (tab.getDeviceAccountLogin() == null) {
304 return;
305 }
306 inflateAutoLoginBar();
307 }
John Reck0f602f32011-07-07 15:38:43 -0700308 mAutoLogin.updateAutoLogin(tab, animate);
309 }
310
311 public void showAutoLogin(boolean animate) {
312 if (mUseQuickControls) {
313 mBaseUi.showTitleBar();
314 }
Ben Murdochd51bb572011-08-17 20:42:02 +0100315 if (mAutoLogin == null) {
316 inflateAutoLoginBar();
317 }
John Reck0f602f32011-07-07 15:38:43 -0700318 mAutoLogin.setVisibility(View.VISIBLE);
319 if (animate) {
320 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
321 getContext(), R.anim.autologin_enter));
322 }
323 }
324
325 public void hideAutoLogin(boolean animate) {
326 if (mUseQuickControls) {
327 mBaseUi.hideTitleBar();
328 mAutoLogin.setVisibility(View.GONE);
329 mBaseUi.refreshWebView();
330 } else {
331 if (animate) {
332 Animation anim = AnimationUtils.loadAnimation(getContext(),
333 R.anim.autologin_exit);
334 anim.setAnimationListener(new AnimationListener() {
335 @Override
336 public void onAnimationEnd(Animation a) {
337 mAutoLogin.setVisibility(View.GONE);
338 mBaseUi.refreshWebView();
339 }
340
341 @Override
342 public void onAnimationStart(Animation a) {
343 }
344
345 @Override
346 public void onAnimationRepeat(Animation a) {
347 }
348 });
349 mAutoLogin.startAnimation(anim);
350 } else if (mAutoLogin.getAnimation() == null) {
351 mAutoLogin.setVisibility(View.GONE);
352 mBaseUi.refreshWebView();
353 }
354 }
355 }
356
John Reckef654f12011-07-12 16:42:08 -0700357 public boolean wantsToBeVisible() {
358 return inAutoLogin()
Ben Murdochd51bb572011-08-17 20:42:02 +0100359 || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700360 && mSnapshotBar.isAnimating());
361 }
362
363 private boolean inAutoLogin() {
Ben Murdochd51bb572011-08-17 20:42:02 +0100364 return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
John Reck0f602f32011-07-07 15:38:43 -0700365 }
366
367 public boolean isEditingUrl() {
368 return mNavBar.isEditingUrl();
369 }
370
371 public WebView getCurrentWebView() {
372 Tab t = mBaseUi.getActiveTab();
373 if (t != null) {
374 return t.getWebView();
375 } else {
376 return null;
377 }
378 }
379
380 public PageProgressView getProgressView() {
381 return mProgress;
382 }
383
384 public NavigationBarBase getNavigationBar() {
385 return mNavBar;
386 }
387
388 public boolean useQuickControls() {
389 return mUseQuickControls;
390 }
391
392 public boolean isInLoad() {
393 return mInLoad;
394 }
395
396 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700397 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
398 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700399 }
400
401 @Override
402 public View focusSearch(View focused, int dir) {
403 if (FOCUS_DOWN == dir && hasFocus()) {
404 return getCurrentWebView();
405 }
406 return super.focusSearch(focused, dir);
407 }
408
John Reckef654f12011-07-12 16:42:08 -0700409 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100410 if (mSnapshotBar != null) {
411 mSnapshotBar.onTabDataChanged(tab);
412 }
413
John Reckef654f12011-07-12 16:42:08 -0700414 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100415 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700416 mSnapshotBar.setVisibility(VISIBLE);
417 mNavBar.setVisibility(GONE);
418 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100419 if (mSnapshotBar != null) {
420 mSnapshotBar.setVisibility(GONE);
421 }
John Reckef654f12011-07-12 16:42:08 -0700422 mNavBar.setVisibility(VISIBLE);
423 }
424 }
425
Michael Kolb4923c222012-04-02 16:18:36 -0700426 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700427 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700428 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
429 }
430 }
431
John Reck0f602f32011-07-07 15:38:43 -0700432}