blob: a0cc857d088232f49e5a197b2e9d41b2f12d72ca [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 Reck1cc1d1d2012-09-04 18:13:51 -070029import android.view.accessibility.AccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070030import android.view.animation.Animation;
31import android.view.animation.Animation.AnimationListener;
32import android.view.animation.AnimationUtils;
33import android.view.animation.DecelerateInterpolator;
34import android.webkit.WebView;
John Reck0f602f32011-07-07 15:38:43 -070035import android.widget.FrameLayout;
36import android.widget.RelativeLayout;
37
38
39/**
40 * Base class for a title bar used by the browser.
41 */
42public 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;
John Reck2711fab2012-05-18 21:38:59 -070049 private FrameLayout mContentView;
John Reck0f602f32011-07-07 15:38:43 -070050 private PageProgressView mProgress;
John Reck1cc1d1d2012-09-04 18:13:51 -070051 private AccessibilityManager mAccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070052
53 private AutologinBar mAutoLogin;
54 private NavigationBarBase mNavBar;
55 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070056 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070057
58 //state
59 private boolean mShowing;
60 private boolean mInLoad;
61 private boolean mSkipTitleBarAnimations;
62 private Animator mTitleBarAnimator;
John Reck2711fab2012-05-18 21:38:59 -070063 private boolean mIsFixedTitleBar;
John Reck0f602f32011-07-07 15:38:43 -070064
65 public TitleBar(Context context, UiController controller, BaseUi ui,
John Reck2711fab2012-05-18 21:38:59 -070066 FrameLayout contentView) {
John Reck0f602f32011-07-07 15:38:43 -070067 super(context, null);
68 mUiController = controller;
69 mBaseUi = ui;
John Reck2711fab2012-05-18 21:38:59 -070070 mContentView = contentView;
John Reck1cc1d1d2012-09-04 18:13:51 -070071 mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
John Reck0f602f32011-07-07 15:38:43 -070072 initLayout(context);
John Reck0f9aaeb2012-05-23 14:40:19 -070073 setFixedTitleBar();
John Reck0f602f32011-07-07 15:38:43 -070074 }
75
76 private void initLayout(Context context) {
77 LayoutInflater factory = LayoutInflater.from(context);
78 factory.inflate(R.layout.title_bar, this);
79 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070080 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
81 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010082 }
83
84 private void inflateAutoLoginBar() {
85 if (mAutoLogin != null) {
86 return;
87 }
88
89 ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
90 mAutoLogin = (AutologinBar) stub.inflate();
91 mAutoLogin.setTitleBar(this);
92 }
93
94 private void inflateSnapshotBar() {
95 if (mSnapshotBar != null) {
96 return;
97 }
98
99 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
100 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -0700101 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -0700102 }
103
Michael Kolb57059a82012-04-30 14:32:03 -0700104 @Override
105 protected void onConfigurationChanged(Configuration config) {
106 super.onConfigurationChanged(config);
John Reck0f9aaeb2012-05-23 14:40:19 -0700107 setFixedTitleBar();
John Reck2711fab2012-05-18 21:38:59 -0700108 }
109
110 @Override
111 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
112 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
113 if (mIsFixedTitleBar) {
114 int margin = getMeasuredHeight() - calculateEmbeddedHeight();
115 mBaseUi.setContentViewMarginTop(-margin);
John Reck0f9aaeb2012-05-23 14:40:19 -0700116 } else {
117 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700118 }
119 }
120
John Reck0f9aaeb2012-05-23 14:40:19 -0700121 private void setFixedTitleBar() {
122 boolean isFixed = !mUseQuickControls
123 && !mContext.getResources().getBoolean(R.bool.hide_title);
John Reck1cc1d1d2012-09-04 18:13:51 -0700124 isFixed |= mAccessibilityManager.isEnabled();
Jonathan Dixone1d6dfc2012-12-17 13:39:17 -0800125 isFixed |= !BrowserWebView.isClassic();
John Reck2711fab2012-05-18 21:38:59 -0700126 // If getParent() returns null, we are initializing
127 ViewGroup parent = (ViewGroup)getParent();
128 if (mIsFixedTitleBar == isFixed && parent != null) return;
129 mIsFixedTitleBar = isFixed;
130 setSkipTitleBarAnimations(true);
131 show();
132 setSkipTitleBarAnimations(false);
133 if (parent != null) {
134 parent.removeView(this);
135 }
136 if (mIsFixedTitleBar) {
137 mBaseUi.addFixedTitleBar(this);
138 } else {
139 mContentView.addView(this, makeLayoutParams());
140 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700141 }
142 }
143
John Reck0f602f32011-07-07 15:38:43 -0700144 public BaseUi getUi() {
145 return mBaseUi;
146 }
147
148 public UiController getUiController() {
149 return mUiController;
150 }
151
152 public void setUseQuickControls(boolean use) {
153 mUseQuickControls = use;
John Reck0f9aaeb2012-05-23 14:40:19 -0700154 setFixedTitleBar();
Michael Kolb4923c222012-04-02 16:18:36 -0700155 if (use) {
156 this.setVisibility(View.GONE);
157 } else {
158 this.setVisibility(View.VISIBLE);
159 }
John Reck0f602f32011-07-07 15:38:43 -0700160 }
161
162 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700163 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700164 mNavBar.setVisibility(View.GONE);
165 } else {
166 mNavBar.setVisibility(View.VISIBLE);
167 }
168 }
169
170 void setSkipTitleBarAnimations(boolean skip) {
171 mSkipTitleBarAnimations = skip;
172 }
173
174 void setupTitleBarAnimator(Animator animator) {
175 Resources res = mContext.getResources();
176 int duration = res.getInteger(R.integer.titlebar_animation_duration);
177 animator.setInterpolator(new DecelerateInterpolator(
178 ANIM_TITLEBAR_DECELERATE));
179 animator.setDuration(duration);
180 }
181
182 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700183 cancelTitleBarAnimation(false);
184 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700185 this.setVisibility(View.VISIBLE);
186 this.setTranslationY(0);
John Reck0f602f32011-07-07 15:38:43 -0700187 } else {
John Reck2711fab2012-05-18 21:38:59 -0700188 int visibleHeight = getVisibleTitleHeight();
189 float startPos = (-getEmbeddedHeight() + visibleHeight);
190 if (getTranslationY() != 0) {
191 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700192 }
John Reck2711fab2012-05-18 21:38:59 -0700193 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
194 "translationY",
195 startPos, 0);
196 setupTitleBarAnimator(mTitleBarAnimator);
197 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700198 }
199 mShowing = true;
200 }
201
202 void hide() {
203 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700204 this.setVisibility(View.GONE);
John Reck0f602f32011-07-07 15:38:43 -0700205 } else {
John Reck2711fab2012-05-18 21:38:59 -0700206 if (mIsFixedTitleBar) return;
John Reck0f602f32011-07-07 15:38:43 -0700207 if (!mSkipTitleBarAnimations) {
208 cancelTitleBarAnimation(false);
209 int visibleHeight = getVisibleTitleHeight();
210 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
211 "translationY", getTranslationY(),
212 (-getEmbeddedHeight() + visibleHeight));
213 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
214 setupTitleBarAnimator(mTitleBarAnimator);
215 mTitleBarAnimator.start();
216 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700217 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700218 }
219 }
220 mShowing = false;
221 }
222
223 boolean isShowing() {
224 return mShowing;
225 }
226
227 void cancelTitleBarAnimation(boolean reset) {
228 if (mTitleBarAnimator != null) {
229 mTitleBarAnimator.cancel();
230 mTitleBarAnimator = null;
231 }
232 if (reset) {
233 setTranslationY(0);
234 }
235 }
236
237 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
238
John Reck0f602f32011-07-07 15:38:43 -0700239 @Override
240 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700241 }
242
243 @Override
244 public void onAnimationRepeat(Animator animation) {
245 }
246
247 @Override
248 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700249 // update position
250 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700251 }
252
253 @Override
254 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700255 }
256 };
257
258 private int getVisibleTitleHeight() {
259 Tab tab = mBaseUi.getActiveTab();
260 WebView webview = tab != null ? tab.getWebView() : null;
261 return webview != null ? webview.getVisibleTitleHeight() : 0;
262 }
263
264 /**
265 * Update the progress, from 0 to 100.
266 */
267 public void setProgress(int newProgress) {
268 if (newProgress >= PROGRESS_MAX) {
269 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
270 mProgress.setVisibility(View.GONE);
271 mInLoad = false;
272 mNavBar.onProgressStopped();
273 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700274 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700275 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700276 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700277 } else {
278 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700279 }
280 }
281 } else {
282 if (!mInLoad) {
283 mProgress.setVisibility(View.VISIBLE);
284 mInLoad = true;
285 mNavBar.onProgressStarted();
286 }
287 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
288 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700289 if (mUseQuickControls && !isEditingUrl()) {
290 setShowProgressOnly(true);
291 }
John Reck0f602f32011-07-07 15:38:43 -0700292 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700293 show();
294 }
295 }
296 }
297
298 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700299 if (mUseQuickControls || mIsFixedTitleBar) return 0;
300 return calculateEmbeddedHeight();
301 }
302
303 private int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700304 int height = mNavBar.getHeight();
Ben Murdochd51bb572011-08-17 20:42:02 +0100305 if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
John Reck0f602f32011-07-07 15:38:43 -0700306 height += mAutoLogin.getHeight();
307 }
308 return height;
309 }
310
311 public void updateAutoLogin(Tab tab, boolean animate) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100312 if (mAutoLogin == null) {
313 if (tab.getDeviceAccountLogin() == null) {
314 return;
315 }
316 inflateAutoLoginBar();
317 }
John Reck0f602f32011-07-07 15:38:43 -0700318 mAutoLogin.updateAutoLogin(tab, animate);
319 }
320
321 public void showAutoLogin(boolean animate) {
322 if (mUseQuickControls) {
323 mBaseUi.showTitleBar();
324 }
Ben Murdochd51bb572011-08-17 20:42:02 +0100325 if (mAutoLogin == null) {
326 inflateAutoLoginBar();
327 }
John Reck0f602f32011-07-07 15:38:43 -0700328 mAutoLogin.setVisibility(View.VISIBLE);
329 if (animate) {
330 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
331 getContext(), R.anim.autologin_enter));
332 }
333 }
334
335 public void hideAutoLogin(boolean animate) {
336 if (mUseQuickControls) {
337 mBaseUi.hideTitleBar();
338 mAutoLogin.setVisibility(View.GONE);
339 mBaseUi.refreshWebView();
340 } else {
341 if (animate) {
342 Animation anim = AnimationUtils.loadAnimation(getContext(),
343 R.anim.autologin_exit);
344 anim.setAnimationListener(new AnimationListener() {
345 @Override
346 public void onAnimationEnd(Animation a) {
347 mAutoLogin.setVisibility(View.GONE);
348 mBaseUi.refreshWebView();
349 }
350
351 @Override
352 public void onAnimationStart(Animation a) {
353 }
354
355 @Override
356 public void onAnimationRepeat(Animation a) {
357 }
358 });
359 mAutoLogin.startAnimation(anim);
360 } else if (mAutoLogin.getAnimation() == null) {
361 mAutoLogin.setVisibility(View.GONE);
362 mBaseUi.refreshWebView();
363 }
364 }
365 }
366
John Reckef654f12011-07-12 16:42:08 -0700367 public boolean wantsToBeVisible() {
368 return inAutoLogin()
Ben Murdochd51bb572011-08-17 20:42:02 +0100369 || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700370 && mSnapshotBar.isAnimating());
371 }
372
373 private boolean inAutoLogin() {
Ben Murdochd51bb572011-08-17 20:42:02 +0100374 return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
John Reck0f602f32011-07-07 15:38:43 -0700375 }
376
377 public boolean isEditingUrl() {
378 return mNavBar.isEditingUrl();
379 }
380
381 public WebView getCurrentWebView() {
382 Tab t = mBaseUi.getActiveTab();
383 if (t != null) {
384 return t.getWebView();
385 } else {
386 return null;
387 }
388 }
389
390 public PageProgressView getProgressView() {
391 return mProgress;
392 }
393
394 public NavigationBarBase getNavigationBar() {
395 return mNavBar;
396 }
397
398 public boolean useQuickControls() {
399 return mUseQuickControls;
400 }
401
402 public boolean isInLoad() {
403 return mInLoad;
404 }
405
406 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700407 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
408 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700409 }
410
411 @Override
412 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700413 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700414 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700415 && web.hasFocusable() && web.getParent() != null) {
416 return web;
John Reck0f602f32011-07-07 15:38:43 -0700417 }
418 return super.focusSearch(focused, dir);
419 }
420
John Reckef654f12011-07-12 16:42:08 -0700421 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100422 if (mSnapshotBar != null) {
423 mSnapshotBar.onTabDataChanged(tab);
424 }
425
John Reckef654f12011-07-12 16:42:08 -0700426 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100427 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700428 mSnapshotBar.setVisibility(VISIBLE);
429 mNavBar.setVisibility(GONE);
430 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100431 if (mSnapshotBar != null) {
432 mSnapshotBar.setVisibility(GONE);
433 }
John Reckef654f12011-07-12 16:42:08 -0700434 mNavBar.setVisibility(VISIBLE);
435 }
436 }
437
Michael Kolb4923c222012-04-02 16:18:36 -0700438 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700439 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700440 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
441 }
442 }
443
John Reck1cc1d1d2012-09-04 18:13:51 -0700444 public void onResume() {
445 setFixedTitleBar();
446 }
447
John Reck0f602f32011-07-07 15:38:43 -0700448}