blob: 1f9ec231312275a51c6765b8bbc13629a46e6273 [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
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
John Reck0f602f32011-07-07 15:38:43 -070018
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;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080034import org.codeaurora.swe.WebView;
35
Bijan Amirzada41242f22014-03-21 12:12:18 -070036import com.android.browser.R;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080037
John Reck0f602f32011-07-07 15:38:43 -070038import android.widget.FrameLayout;
39import android.widget.RelativeLayout;
40
41
42/**
43 * Base class for a title bar used by the browser.
44 */
45public class TitleBar extends RelativeLayout {
46
47 private static final int PROGRESS_MAX = 100;
48 private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
49
50 private UiController mUiController;
51 private BaseUi mBaseUi;
John Reck2711fab2012-05-18 21:38:59 -070052 private FrameLayout mContentView;
John Reck0f602f32011-07-07 15:38:43 -070053 private PageProgressView mProgress;
John Reck1cc1d1d2012-09-04 18:13:51 -070054 private AccessibilityManager mAccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070055
56 private AutologinBar mAutoLogin;
57 private NavigationBarBase mNavBar;
58 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070059 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070060
61 //state
62 private boolean mShowing;
63 private boolean mInLoad;
64 private boolean mSkipTitleBarAnimations;
65 private Animator mTitleBarAnimator;
John Reck2711fab2012-05-18 21:38:59 -070066 private boolean mIsFixedTitleBar;
John Reck0f602f32011-07-07 15:38:43 -070067
68 public TitleBar(Context context, UiController controller, BaseUi ui,
John Reck2711fab2012-05-18 21:38:59 -070069 FrameLayout contentView) {
John Reck0f602f32011-07-07 15:38:43 -070070 super(context, null);
71 mUiController = controller;
72 mBaseUi = ui;
John Reck2711fab2012-05-18 21:38:59 -070073 mContentView = contentView;
John Reck1cc1d1d2012-09-04 18:13:51 -070074 mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
John Reck0f602f32011-07-07 15:38:43 -070075 initLayout(context);
John Reck0f9aaeb2012-05-23 14:40:19 -070076 setFixedTitleBar();
John Reck0f602f32011-07-07 15:38:43 -070077 }
78
79 private void initLayout(Context context) {
80 LayoutInflater factory = LayoutInflater.from(context);
81 factory.inflate(R.layout.title_bar, this);
82 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070083 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
84 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010085 }
86
87 private void inflateAutoLoginBar() {
88 if (mAutoLogin != null) {
89 return;
90 }
91
92 ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
93 mAutoLogin = (AutologinBar) stub.inflate();
94 mAutoLogin.setTitleBar(this);
95 }
96
97 private void inflateSnapshotBar() {
98 if (mSnapshotBar != null) {
99 return;
100 }
101
102 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
103 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -0700104 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -0700105 }
106
Michael Kolb57059a82012-04-30 14:32:03 -0700107 @Override
108 protected void onConfigurationChanged(Configuration config) {
109 super.onConfigurationChanged(config);
John Reck0f9aaeb2012-05-23 14:40:19 -0700110 setFixedTitleBar();
John Reck2711fab2012-05-18 21:38:59 -0700111 }
112
113 @Override
114 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
115 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
116 if (mIsFixedTitleBar) {
117 int margin = getMeasuredHeight() - calculateEmbeddedHeight();
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700118 if (!isEditingUrl())
119 mBaseUi.setContentViewMarginTop(-margin);
John Reck0f9aaeb2012-05-23 14:40:19 -0700120 } else {
121 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700122 }
123 }
124
John Reck0f9aaeb2012-05-23 14:40:19 -0700125 private void setFixedTitleBar() {
126 boolean isFixed = !mUseQuickControls
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800127 && !getContext().getResources().getBoolean(R.bool.hide_title);
John Reck1cc1d1d2012-09-04 18:13:51 -0700128 isFixed |= mAccessibilityManager.isEnabled();
John Reck2711fab2012-05-18 21:38:59 -0700129 // If getParent() returns null, we are initializing
130 ViewGroup parent = (ViewGroup)getParent();
131 if (mIsFixedTitleBar == isFixed && parent != null) return;
132 mIsFixedTitleBar = isFixed;
133 setSkipTitleBarAnimations(true);
134 show();
135 setSkipTitleBarAnimations(false);
136 if (parent != null) {
137 parent.removeView(this);
138 }
139 if (mIsFixedTitleBar) {
140 mBaseUi.addFixedTitleBar(this);
141 } else {
142 mContentView.addView(this, makeLayoutParams());
143 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700144 }
145 }
146
John Reck0f602f32011-07-07 15:38:43 -0700147 public BaseUi getUi() {
148 return mBaseUi;
149 }
150
151 public UiController getUiController() {
152 return mUiController;
153 }
154
155 public void setUseQuickControls(boolean use) {
156 mUseQuickControls = use;
John Reck0f9aaeb2012-05-23 14:40:19 -0700157 setFixedTitleBar();
Michael Kolb4923c222012-04-02 16:18:36 -0700158 if (use) {
159 this.setVisibility(View.GONE);
160 } else {
161 this.setVisibility(View.VISIBLE);
162 }
John Reck0f602f32011-07-07 15:38:43 -0700163 }
164
165 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700166 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700167 mNavBar.setVisibility(View.GONE);
168 } else {
169 mNavBar.setVisibility(View.VISIBLE);
170 }
171 }
172
173 void setSkipTitleBarAnimations(boolean skip) {
174 mSkipTitleBarAnimations = skip;
175 }
176
177 void setupTitleBarAnimator(Animator animator) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800178 Resources res = getContext().getResources();
John Reck0f602f32011-07-07 15:38:43 -0700179 int duration = res.getInteger(R.integer.titlebar_animation_duration);
180 animator.setInterpolator(new DecelerateInterpolator(
181 ANIM_TITLEBAR_DECELERATE));
182 animator.setDuration(duration);
183 }
184
185 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700186 cancelTitleBarAnimation(false);
187 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700188 this.setVisibility(View.VISIBLE);
189 this.setTranslationY(0);
John Reck0f602f32011-07-07 15:38:43 -0700190 } else {
John Reck2711fab2012-05-18 21:38:59 -0700191 int visibleHeight = getVisibleTitleHeight();
192 float startPos = (-getEmbeddedHeight() + visibleHeight);
193 if (getTranslationY() != 0) {
194 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700195 }
John Reck2711fab2012-05-18 21:38:59 -0700196 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
197 "translationY",
198 startPos, 0);
199 setupTitleBarAnimator(mTitleBarAnimator);
200 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700201 }
202 mShowing = true;
203 }
204
205 void hide() {
206 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700207 this.setVisibility(View.GONE);
John Reck0f602f32011-07-07 15:38:43 -0700208 } else {
John Reck2711fab2012-05-18 21:38:59 -0700209 if (mIsFixedTitleBar) return;
John Reck0f602f32011-07-07 15:38:43 -0700210 if (!mSkipTitleBarAnimations) {
211 cancelTitleBarAnimation(false);
212 int visibleHeight = getVisibleTitleHeight();
213 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
214 "translationY", getTranslationY(),
215 (-getEmbeddedHeight() + visibleHeight));
216 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
217 setupTitleBarAnimator(mTitleBarAnimator);
218 mTitleBarAnimator.start();
219 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700220 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700221 }
222 }
223 mShowing = false;
224 }
225
226 boolean isShowing() {
227 return mShowing;
228 }
229
230 void cancelTitleBarAnimation(boolean reset) {
231 if (mTitleBarAnimator != null) {
232 mTitleBarAnimator.cancel();
233 mTitleBarAnimator = null;
234 }
235 if (reset) {
236 setTranslationY(0);
237 }
238 }
239
240 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
241
John Reck0f602f32011-07-07 15:38:43 -0700242 @Override
243 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700244 }
245
246 @Override
247 public void onAnimationRepeat(Animator animation) {
248 }
249
250 @Override
251 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700252 // update position
253 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700254 }
255
256 @Override
257 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700258 }
259 };
260
261 private int getVisibleTitleHeight() {
262 Tab tab = mBaseUi.getActiveTab();
263 WebView webview = tab != null ? tab.getWebView() : null;
264 return webview != null ? webview.getVisibleTitleHeight() : 0;
265 }
266
267 /**
268 * Update the progress, from 0 to 100.
269 */
270 public void setProgress(int newProgress) {
271 if (newProgress >= PROGRESS_MAX) {
272 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
273 mProgress.setVisibility(View.GONE);
274 mInLoad = false;
275 mNavBar.onProgressStopped();
276 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700277 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700278 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700279 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700280 } else {
281 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700282 }
283 }
284 } else {
285 if (!mInLoad) {
286 mProgress.setVisibility(View.VISIBLE);
287 mInLoad = true;
288 mNavBar.onProgressStarted();
289 }
290 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
291 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700292 if (mUseQuickControls && !isEditingUrl()) {
293 setShowProgressOnly(true);
294 }
John Reck0f602f32011-07-07 15:38:43 -0700295 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700296 show();
297 }
298 }
299 }
300
301 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700302 if (mUseQuickControls || mIsFixedTitleBar) return 0;
303 return calculateEmbeddedHeight();
304 }
305
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800306 public boolean isFixed() {
307 return mIsFixedTitleBar;
308 }
309
310 int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700311 int height = mNavBar.getHeight();
Ben Murdochd51bb572011-08-17 20:42:02 +0100312 if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
John Reck0f602f32011-07-07 15:38:43 -0700313 height += mAutoLogin.getHeight();
314 }
315 return height;
316 }
317
318 public void updateAutoLogin(Tab tab, boolean animate) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100319 if (mAutoLogin == null) {
320 if (tab.getDeviceAccountLogin() == null) {
321 return;
322 }
323 inflateAutoLoginBar();
324 }
John Reck0f602f32011-07-07 15:38:43 -0700325 mAutoLogin.updateAutoLogin(tab, animate);
326 }
327
328 public void showAutoLogin(boolean animate) {
329 if (mUseQuickControls) {
330 mBaseUi.showTitleBar();
331 }
Ben Murdochd51bb572011-08-17 20:42:02 +0100332 if (mAutoLogin == null) {
333 inflateAutoLoginBar();
334 }
John Reck0f602f32011-07-07 15:38:43 -0700335 mAutoLogin.setVisibility(View.VISIBLE);
336 if (animate) {
337 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
338 getContext(), R.anim.autologin_enter));
339 }
340 }
341
342 public void hideAutoLogin(boolean animate) {
343 if (mUseQuickControls) {
344 mBaseUi.hideTitleBar();
345 mAutoLogin.setVisibility(View.GONE);
346 mBaseUi.refreshWebView();
347 } else {
348 if (animate) {
349 Animation anim = AnimationUtils.loadAnimation(getContext(),
350 R.anim.autologin_exit);
351 anim.setAnimationListener(new AnimationListener() {
352 @Override
353 public void onAnimationEnd(Animation a) {
354 mAutoLogin.setVisibility(View.GONE);
355 mBaseUi.refreshWebView();
356 }
357
358 @Override
359 public void onAnimationStart(Animation a) {
360 }
361
362 @Override
363 public void onAnimationRepeat(Animation a) {
364 }
365 });
366 mAutoLogin.startAnimation(anim);
367 } else if (mAutoLogin.getAnimation() == null) {
368 mAutoLogin.setVisibility(View.GONE);
369 mBaseUi.refreshWebView();
370 }
371 }
372 }
373
John Reckef654f12011-07-12 16:42:08 -0700374 public boolean wantsToBeVisible() {
375 return inAutoLogin()
Ben Murdochd51bb572011-08-17 20:42:02 +0100376 || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700377 && mSnapshotBar.isAnimating());
378 }
379
380 private boolean inAutoLogin() {
Ben Murdochd51bb572011-08-17 20:42:02 +0100381 return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
John Reck0f602f32011-07-07 15:38:43 -0700382 }
383
384 public boolean isEditingUrl() {
385 return mNavBar.isEditingUrl();
386 }
387
388 public WebView getCurrentWebView() {
389 Tab t = mBaseUi.getActiveTab();
390 if (t != null) {
391 return t.getWebView();
392 } else {
393 return null;
394 }
395 }
396
397 public PageProgressView getProgressView() {
398 return mProgress;
399 }
400
401 public NavigationBarBase getNavigationBar() {
402 return mNavBar;
403 }
404
405 public boolean useQuickControls() {
406 return mUseQuickControls;
407 }
408
409 public boolean isInLoad() {
410 return mInLoad;
411 }
412
413 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700414 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
415 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700416 }
417
418 @Override
419 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700420 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700421 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700422 && web.hasFocusable() && web.getParent() != null) {
423 return web;
John Reck0f602f32011-07-07 15:38:43 -0700424 }
425 return super.focusSearch(focused, dir);
426 }
427
John Reckef654f12011-07-12 16:42:08 -0700428 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100429 if (mSnapshotBar != null) {
430 mSnapshotBar.onTabDataChanged(tab);
431 }
432
John Reckef654f12011-07-12 16:42:08 -0700433 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100434 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700435 mSnapshotBar.setVisibility(VISIBLE);
436 mNavBar.setVisibility(GONE);
437 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100438 if (mSnapshotBar != null) {
439 mSnapshotBar.setVisibility(GONE);
440 }
John Reckef654f12011-07-12 16:42:08 -0700441 mNavBar.setVisibility(VISIBLE);
442 }
443 }
444
Michael Kolb4923c222012-04-02 16:18:36 -0700445 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700446 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700447 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
448 }
449 }
450
John Reck1cc1d1d2012-09-04 18:13:51 -0700451 public void onResume() {
452 setFixedTitleBar();
453 }
454
John Reck0f602f32011-07-07 15:38:43 -0700455}