blob: e33a05c1d925ece237fec8e26b58469aacd18647 [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();
118 mBaseUi.setContentViewMarginTop(-margin);
John Reck0f9aaeb2012-05-23 14:40:19 -0700119 } else {
120 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700121 }
122 }
123
John Reck0f9aaeb2012-05-23 14:40:19 -0700124 private void setFixedTitleBar() {
125 boolean isFixed = !mUseQuickControls
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800126 && !getContext().getResources().getBoolean(R.bool.hide_title);
John Reck1cc1d1d2012-09-04 18:13:51 -0700127 isFixed |= mAccessibilityManager.isEnabled();
John Reck2711fab2012-05-18 21:38:59 -0700128 // If getParent() returns null, we are initializing
129 ViewGroup parent = (ViewGroup)getParent();
130 if (mIsFixedTitleBar == isFixed && parent != null) return;
131 mIsFixedTitleBar = isFixed;
132 setSkipTitleBarAnimations(true);
133 show();
134 setSkipTitleBarAnimations(false);
135 if (parent != null) {
136 parent.removeView(this);
137 }
138 if (mIsFixedTitleBar) {
139 mBaseUi.addFixedTitleBar(this);
140 } else {
141 mContentView.addView(this, makeLayoutParams());
142 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700143 }
144 }
145
John Reck0f602f32011-07-07 15:38:43 -0700146 public BaseUi getUi() {
147 return mBaseUi;
148 }
149
150 public UiController getUiController() {
151 return mUiController;
152 }
153
154 public void setUseQuickControls(boolean use) {
155 mUseQuickControls = use;
John Reck0f9aaeb2012-05-23 14:40:19 -0700156 setFixedTitleBar();
Michael Kolb4923c222012-04-02 16:18:36 -0700157 if (use) {
158 this.setVisibility(View.GONE);
159 } else {
160 this.setVisibility(View.VISIBLE);
161 }
John Reck0f602f32011-07-07 15:38:43 -0700162 }
163
164 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700165 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700166 mNavBar.setVisibility(View.GONE);
167 } else {
168 mNavBar.setVisibility(View.VISIBLE);
169 }
170 }
171
172 void setSkipTitleBarAnimations(boolean skip) {
173 mSkipTitleBarAnimations = skip;
174 }
175
176 void setupTitleBarAnimator(Animator animator) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800177 Resources res = getContext().getResources();
John Reck0f602f32011-07-07 15:38:43 -0700178 int duration = res.getInteger(R.integer.titlebar_animation_duration);
179 animator.setInterpolator(new DecelerateInterpolator(
180 ANIM_TITLEBAR_DECELERATE));
181 animator.setDuration(duration);
182 }
183
184 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700185 cancelTitleBarAnimation(false);
186 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700187 this.setVisibility(View.VISIBLE);
188 this.setTranslationY(0);
John Reck0f602f32011-07-07 15:38:43 -0700189 } else {
John Reck2711fab2012-05-18 21:38:59 -0700190 int visibleHeight = getVisibleTitleHeight();
191 float startPos = (-getEmbeddedHeight() + visibleHeight);
192 if (getTranslationY() != 0) {
193 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700194 }
John Reck2711fab2012-05-18 21:38:59 -0700195 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
196 "translationY",
197 startPos, 0);
198 setupTitleBarAnimator(mTitleBarAnimator);
199 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700200 }
201 mShowing = true;
202 }
203
204 void hide() {
205 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700206 this.setVisibility(View.GONE);
John Reck0f602f32011-07-07 15:38:43 -0700207 } else {
John Reck2711fab2012-05-18 21:38:59 -0700208 if (mIsFixedTitleBar) return;
John Reck0f602f32011-07-07 15:38:43 -0700209 if (!mSkipTitleBarAnimations) {
210 cancelTitleBarAnimation(false);
211 int visibleHeight = getVisibleTitleHeight();
212 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
213 "translationY", getTranslationY(),
214 (-getEmbeddedHeight() + visibleHeight));
215 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
216 setupTitleBarAnimator(mTitleBarAnimator);
217 mTitleBarAnimator.start();
218 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700219 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700220 }
221 }
222 mShowing = false;
223 }
224
225 boolean isShowing() {
226 return mShowing;
227 }
228
229 void cancelTitleBarAnimation(boolean reset) {
230 if (mTitleBarAnimator != null) {
231 mTitleBarAnimator.cancel();
232 mTitleBarAnimator = null;
233 }
234 if (reset) {
235 setTranslationY(0);
236 }
237 }
238
239 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
240
John Reck0f602f32011-07-07 15:38:43 -0700241 @Override
242 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700243 }
244
245 @Override
246 public void onAnimationRepeat(Animator animation) {
247 }
248
249 @Override
250 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700251 // update position
252 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700253 }
254
255 @Override
256 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700257 }
258 };
259
260 private int getVisibleTitleHeight() {
261 Tab tab = mBaseUi.getActiveTab();
262 WebView webview = tab != null ? tab.getWebView() : null;
263 return webview != null ? webview.getVisibleTitleHeight() : 0;
264 }
265
266 /**
267 * Update the progress, from 0 to 100.
268 */
269 public void setProgress(int newProgress) {
270 if (newProgress >= PROGRESS_MAX) {
271 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
272 mProgress.setVisibility(View.GONE);
273 mInLoad = false;
274 mNavBar.onProgressStopped();
275 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700276 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700277 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700278 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700279 } else {
280 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700281 }
282 }
283 } else {
284 if (!mInLoad) {
285 mProgress.setVisibility(View.VISIBLE);
286 mInLoad = true;
287 mNavBar.onProgressStarted();
288 }
289 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
290 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700291 if (mUseQuickControls && !isEditingUrl()) {
292 setShowProgressOnly(true);
293 }
John Reck0f602f32011-07-07 15:38:43 -0700294 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700295 show();
296 }
297 }
298 }
299
300 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700301 if (mUseQuickControls || mIsFixedTitleBar) return 0;
302 return calculateEmbeddedHeight();
303 }
304
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800305 public boolean isFixed() {
306 return mIsFixedTitleBar;
307 }
308
309 int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700310 int height = mNavBar.getHeight();
Ben Murdochd51bb572011-08-17 20:42:02 +0100311 if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
John Reck0f602f32011-07-07 15:38:43 -0700312 height += mAutoLogin.getHeight();
313 }
314 return height;
315 }
316
317 public void updateAutoLogin(Tab tab, boolean animate) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100318 if (mAutoLogin == null) {
319 if (tab.getDeviceAccountLogin() == null) {
320 return;
321 }
322 inflateAutoLoginBar();
323 }
John Reck0f602f32011-07-07 15:38:43 -0700324 mAutoLogin.updateAutoLogin(tab, animate);
325 }
326
327 public void showAutoLogin(boolean animate) {
328 if (mUseQuickControls) {
329 mBaseUi.showTitleBar();
330 }
Ben Murdochd51bb572011-08-17 20:42:02 +0100331 if (mAutoLogin == null) {
332 inflateAutoLoginBar();
333 }
John Reck0f602f32011-07-07 15:38:43 -0700334 mAutoLogin.setVisibility(View.VISIBLE);
335 if (animate) {
336 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
337 getContext(), R.anim.autologin_enter));
338 }
339 }
340
341 public void hideAutoLogin(boolean animate) {
342 if (mUseQuickControls) {
343 mBaseUi.hideTitleBar();
344 mAutoLogin.setVisibility(View.GONE);
345 mBaseUi.refreshWebView();
346 } else {
347 if (animate) {
348 Animation anim = AnimationUtils.loadAnimation(getContext(),
349 R.anim.autologin_exit);
350 anim.setAnimationListener(new AnimationListener() {
351 @Override
352 public void onAnimationEnd(Animation a) {
353 mAutoLogin.setVisibility(View.GONE);
354 mBaseUi.refreshWebView();
355 }
356
357 @Override
358 public void onAnimationStart(Animation a) {
359 }
360
361 @Override
362 public void onAnimationRepeat(Animation a) {
363 }
364 });
365 mAutoLogin.startAnimation(anim);
366 } else if (mAutoLogin.getAnimation() == null) {
367 mAutoLogin.setVisibility(View.GONE);
368 mBaseUi.refreshWebView();
369 }
370 }
371 }
372
John Reckef654f12011-07-12 16:42:08 -0700373 public boolean wantsToBeVisible() {
374 return inAutoLogin()
Ben Murdochd51bb572011-08-17 20:42:02 +0100375 || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700376 && mSnapshotBar.isAnimating());
377 }
378
379 private boolean inAutoLogin() {
Ben Murdochd51bb572011-08-17 20:42:02 +0100380 return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
John Reck0f602f32011-07-07 15:38:43 -0700381 }
382
383 public boolean isEditingUrl() {
384 return mNavBar.isEditingUrl();
385 }
386
387 public WebView getCurrentWebView() {
388 Tab t = mBaseUi.getActiveTab();
389 if (t != null) {
390 return t.getWebView();
391 } else {
392 return null;
393 }
394 }
395
396 public PageProgressView getProgressView() {
397 return mProgress;
398 }
399
400 public NavigationBarBase getNavigationBar() {
401 return mNavBar;
402 }
403
404 public boolean useQuickControls() {
405 return mUseQuickControls;
406 }
407
408 public boolean isInLoad() {
409 return mInLoad;
410 }
411
412 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700413 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
414 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700415 }
416
417 @Override
418 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700419 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700420 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700421 && web.hasFocusable() && web.getParent() != null) {
422 return web;
John Reck0f602f32011-07-07 15:38:43 -0700423 }
424 return super.focusSearch(focused, dir);
425 }
426
John Reckef654f12011-07-12 16:42:08 -0700427 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100428 if (mSnapshotBar != null) {
429 mSnapshotBar.onTabDataChanged(tab);
430 }
431
John Reckef654f12011-07-12 16:42:08 -0700432 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100433 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700434 mSnapshotBar.setVisibility(VISIBLE);
435 mNavBar.setVisibility(GONE);
436 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100437 if (mSnapshotBar != null) {
438 mSnapshotBar.setVisibility(GONE);
439 }
John Reckef654f12011-07-12 16:42:08 -0700440 mNavBar.setVisibility(VISIBLE);
441 }
442 }
443
Michael Kolb4923c222012-04-02 16:18:36 -0700444 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700445 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700446 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
447 }
448 }
449
John Reck1cc1d1d2012-09-04 18:13:51 -0700450 public void onResume() {
451 setFixedTitleBar();
452 }
453
John Reck0f602f32011-07-07 15:38:43 -0700454}