blob: 11a3128414c5745105e0995064e5f0b72622e998 [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;
Panos Thomas752ce592014-10-16 13:00:35 -070025import android.graphics.Rect;
John Reck0f602f32011-07-07 15:38:43 -070026import android.view.LayoutInflater;
27import android.view.View;
28import android.view.ViewGroup;
Ben Murdochd51bb572011-08-17 20:42:02 +010029import android.view.ViewStub;
Kulanthaivel Palanichamy846bb0f2014-12-02 13:50:34 -080030import android.view.ViewTreeObserver;
John Reck1cc1d1d2012-09-04 18:13:51 -070031import android.view.accessibility.AccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070032import android.view.animation.DecelerateInterpolator;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080033import org.codeaurora.swe.WebView;
34
John Reck0f602f32011-07-07 15:38:43 -070035import android.widget.FrameLayout;
John Reck0f602f32011-07-07 15:38:43 -070036
37/**
38 * Base class for a title bar used by the browser.
39 */
Kulanthaivel Palanichamy846bb0f2014-12-02 13:50:34 -080040public class TitleBar extends FrameLayout implements ViewTreeObserver.OnPreDrawListener {
John Reck0f602f32011-07-07 15:38:43 -070041
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;
John Reck2711fab2012-05-18 21:38:59 -070047 private FrameLayout mContentView;
John Reck0f602f32011-07-07 15:38:43 -070048 private PageProgressView mProgress;
John Reck1cc1d1d2012-09-04 18:13:51 -070049 private AccessibilityManager mAccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070050
John Reck0f602f32011-07-07 15:38:43 -070051 private NavigationBarBase mNavBar;
John Reckef654f12011-07-12 16:42:08 -070052 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070053
54 //state
55 private boolean mShowing;
56 private boolean mInLoad;
57 private boolean mSkipTitleBarAnimations;
58 private Animator mTitleBarAnimator;
John Reck2711fab2012-05-18 21:38:59 -070059 private boolean mIsFixedTitleBar;
Kulanthaivel Palanichamy846bb0f2014-12-02 13:50:34 -080060 private float mCurrentTranslationY;
61 private boolean mUpdateTranslationY = false;
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 Reck1cc1d1d2012-09-04 18:13:51 -070069 mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
John Reck0f602f32011-07-07 15:38:43 -070070 initLayout(context);
John Reck0f9aaeb2012-05-23 14:40:19 -070071 setFixedTitleBar();
John Reck0f602f32011-07-07 15:38:43 -070072 }
73
74 private void initLayout(Context context) {
75 LayoutInflater factory = LayoutInflater.from(context);
76 factory.inflate(R.layout.title_bar, this);
77 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070078 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
79 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010080 }
81
Ben Murdochd51bb572011-08-17 20:42:02 +010082 private void inflateSnapshotBar() {
83 if (mSnapshotBar != null) {
84 return;
85 }
86
87 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
88 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -070089 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070090 }
91
Michael Kolb57059a82012-04-30 14:32:03 -070092 @Override
93 protected void onConfigurationChanged(Configuration config) {
94 super.onConfigurationChanged(config);
John Reck0f9aaeb2012-05-23 14:40:19 -070095 setFixedTitleBar();
John Reck2711fab2012-05-18 21:38:59 -070096 }
97
98 @Override
99 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
100 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Vivek Sekhar8a660782014-10-27 17:00:53 -0700101 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700102 }
103
Kulanthaivel Palanichamy846bb0f2014-12-02 13:50:34 -0800104 @Override
105 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
106 super.onLayout(changed, left, top, right, bottom);
107
108 mCurrentTranslationY = this.getTranslationY();
109 if (mCurrentTranslationY < 0) {
110 mUpdateTranslationY = true;
111 this.setTranslationY(0);
112
113 final ViewTreeObserver observer = this.getViewTreeObserver();
114 observer.addOnPreDrawListener(this);
115 }
116 }
117
118 @Override
119 public boolean onPreDraw() {
120 if (mUpdateTranslationY) {
121 this.setTranslationY(mCurrentTranslationY);
122 mUpdateTranslationY = false;
123 }
124 final ViewTreeObserver observer = this.getViewTreeObserver();
125 observer.removeOnPreDrawListener(this);
126 return true;
127 }
128
John Reck0f9aaeb2012-05-23 14:40:19 -0700129 private void setFixedTitleBar() {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700130 boolean isFixed = !getContext().getResources().getBoolean(R.bool.hide_title);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700131
Vivek Sekhar80572142014-12-01 10:54:22 -0800132 isFixed |= mAccessibilityManager.isEnabled() &&
133 mAccessibilityManager.isTouchExplorationEnabled();
John Reck2711fab2012-05-18 21:38:59 -0700134 // If getParent() returns null, we are initializing
135 ViewGroup parent = (ViewGroup)getParent();
136 if (mIsFixedTitleBar == isFixed && parent != null) return;
137 mIsFixedTitleBar = isFixed;
138 setSkipTitleBarAnimations(true);
139 show();
140 setSkipTitleBarAnimations(false);
141 if (parent != null) {
142 parent.removeView(this);
143 }
Vivek Sekhar8a660782014-10-27 17:00:53 -0700144 mContentView.addView(this, makeLayoutParams());
145 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700146 }
147
John Reck0f602f32011-07-07 15:38:43 -0700148 public BaseUi getUi() {
149 return mBaseUi;
150 }
151
152 public UiController getUiController() {
153 return mUiController;
154 }
155
John Reck0f602f32011-07-07 15:38:43 -0700156 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700157 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700158 mNavBar.setVisibility(View.GONE);
159 } else {
160 mNavBar.setVisibility(View.VISIBLE);
161 }
162 }
163
164 void setSkipTitleBarAnimations(boolean skip) {
165 mSkipTitleBarAnimations = skip;
166 }
167
168 void setupTitleBarAnimator(Animator animator) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800169 Resources res = getContext().getResources();
John Reck0f602f32011-07-07 15:38:43 -0700170 int duration = res.getInteger(R.integer.titlebar_animation_duration);
171 animator.setInterpolator(new DecelerateInterpolator(
172 ANIM_TITLEBAR_DECELERATE));
173 animator.setDuration(duration);
174 }
175
Tarun Nainani8eb00912014-07-17 12:28:32 -0700176 //Disable stock autohide behavior in favor of top controls
177 private static final boolean bOldStyleAutoHideDisabled = true;
John Reck0f602f32011-07-07 15:38:43 -0700178 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700179 cancelTitleBarAnimation(false);
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700180 if (mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700181 this.setVisibility(View.VISIBLE);
182 this.setTranslationY(0);
Vivek Sekhar8a660782014-10-27 17:00:53 -0700183 // reaffirm top-controls
184 if (isFixed() || isInLoad())
185 showTopControls();
186 else
187 enableTopControls();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700188 } else if (!bOldStyleAutoHideDisabled) {
John Reck2711fab2012-05-18 21:38:59 -0700189 int visibleHeight = getVisibleTitleHeight();
190 float startPos = (-getEmbeddedHeight() + visibleHeight);
191 if (getTranslationY() != 0) {
192 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700193 }
John Reck2711fab2012-05-18 21:38:59 -0700194 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
195 "translationY",
196 startPos, 0);
197 setupTitleBarAnimator(mTitleBarAnimator);
198 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700199 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700200
John Reck0f602f32011-07-07 15:38:43 -0700201 mShowing = true;
202 }
203
204 void hide() {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700205 if (mIsFixedTitleBar || bOldStyleAutoHideDisabled) return;
206 if (!mSkipTitleBarAnimations) {
207 cancelTitleBarAnimation(false);
208 int visibleHeight = getVisibleTitleHeight();
209 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
210 "translationY", getTranslationY(),
211 (-getEmbeddedHeight() + visibleHeight));
212 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
213 setupTitleBarAnimator(mTitleBarAnimator);
214 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700215 } else {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700216 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700217 }
218 mShowing = false;
219 }
220
221 boolean isShowing() {
222 return mShowing;
223 }
224
225 void cancelTitleBarAnimation(boolean reset) {
226 if (mTitleBarAnimator != null) {
227 mTitleBarAnimator.cancel();
228 mTitleBarAnimator = null;
229 }
230 if (reset) {
231 setTranslationY(0);
232 }
233 }
234
235 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
236
John Reck0f602f32011-07-07 15:38:43 -0700237 @Override
238 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700239 }
240
241 @Override
242 public void onAnimationRepeat(Animator animation) {
243 }
244
245 @Override
246 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700247 // update position
248 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700249 }
250
251 @Override
252 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700253 }
254 };
255
256 private int getVisibleTitleHeight() {
257 Tab tab = mBaseUi.getActiveTab();
258 WebView webview = tab != null ? tab.getWebView() : null;
259 return webview != null ? webview.getVisibleTitleHeight() : 0;
260 }
261
Tarun Nainani8eb00912014-07-17 12:28:32 -0700262 private void hideTopControls() {
263 Tab tab = mBaseUi.getActiveTab();
264 WebView view = tab != null ? tab.getWebView() : null;
265 if (view != null)
266 view.updateTopControls(true, false, true);
267 }
268
269 private void showTopControls() {
270 Tab tab = mBaseUi.getActiveTab();
271 WebView view = tab != null ? tab.getWebView() : null;
272 if (view != null)
Vivek Sekhar6497d3e2015-03-24 12:00:06 -0700273 view.updateTopControls(false, true, false);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700274 }
275
276 private void enableTopControls() {
277 Tab tab = mBaseUi.getActiveTab();
278 WebView view = tab != null ? tab.getWebView() : null;
279 if (view != null)
280 view.updateTopControls(true, true, true);
281 }
282
283
John Reck0f602f32011-07-07 15:38:43 -0700284 /**
285 * Update the progress, from 0 to 100.
286 */
287 public void setProgress(int newProgress) {
288 if (newProgress >= PROGRESS_MAX) {
289 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
290 mProgress.setVisibility(View.GONE);
291 mInLoad = false;
292 mNavBar.onProgressStopped();
293 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700294 if (!isEditingUrl() && !wantsToBeVisible()) {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700295 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700296 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700297
298 //onPageFinished
Vivek Sekhar6497d3e2015-03-24 12:00:06 -0700299 showTopControls();
300 if(!isFixed())
Vivek Sekhar8a660782014-10-27 17:00:53 -0700301 enableTopControls();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700302
John Reck0f602f32011-07-07 15:38:43 -0700303 } else {
304 if (!mInLoad) {
305 mProgress.setVisibility(View.VISIBLE);
306 mInLoad = true;
307 mNavBar.onProgressStarted();
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700308 mProgress.onProgressStarted();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700309 //onPageStarted
John Reck0f602f32011-07-07 15:38:43 -0700310 }
311 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
312 / PROGRESS_MAX);
313 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700314 show();
315 }
Vivek Sekhar6497d3e2015-03-24 12:00:06 -0700316 showTopControls();
John Reck0f602f32011-07-07 15:38:43 -0700317 }
318 }
319
320 public int getEmbeddedHeight() {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700321 if (mIsFixedTitleBar) return 0;
John Reck2711fab2012-05-18 21:38:59 -0700322 return calculateEmbeddedHeight();
323 }
324
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800325 public boolean isFixed() {
326 return mIsFixedTitleBar;
327 }
328
329 int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700330 int height = mNavBar.getHeight();
John Reck0f602f32011-07-07 15:38:43 -0700331 return height;
332 }
333
John Reckef654f12011-07-12 16:42:08 -0700334 public boolean wantsToBeVisible() {
Bijan Amirzada289e1e62014-04-15 11:53:48 -0700335 return (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700336 && mSnapshotBar.isAnimating());
337 }
338
John Reck0f602f32011-07-07 15:38:43 -0700339 public boolean isEditingUrl() {
340 return mNavBar.isEditingUrl();
341 }
342
343 public WebView getCurrentWebView() {
344 Tab t = mBaseUi.getActiveTab();
345 if (t != null) {
346 return t.getWebView();
347 } else {
348 return null;
349 }
350 }
351
352 public PageProgressView getProgressView() {
353 return mProgress;
354 }
355
356 public NavigationBarBase getNavigationBar() {
357 return mNavBar;
358 }
359
John Reck0f602f32011-07-07 15:38:43 -0700360 public boolean isInLoad() {
361 return mInLoad;
362 }
363
364 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700365 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
366 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700367 }
368
369 @Override
Panos Thomas752ce592014-10-16 13:00:35 -0700370 public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
371 return mBaseUi.isCustomViewShowing() ? false :
372 super.requestFocus(direction, previouslyFocusedRect);
373 }
374
375 @Override
John Reck0f602f32011-07-07 15:38:43 -0700376 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700377 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700378 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700379 && web.hasFocusable() && web.getParent() != null) {
380 return web;
John Reck0f602f32011-07-07 15:38:43 -0700381 }
382 return super.focusSearch(focused, dir);
383 }
384
John Reckef654f12011-07-12 16:42:08 -0700385 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100386 if (mSnapshotBar != null) {
387 mSnapshotBar.onTabDataChanged(tab);
388 }
389
John Reckef654f12011-07-12 16:42:08 -0700390 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100391 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700392 mSnapshotBar.setVisibility(VISIBLE);
393 mNavBar.setVisibility(GONE);
394 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100395 if (mSnapshotBar != null) {
396 mSnapshotBar.setVisibility(GONE);
397 }
John Reckef654f12011-07-12 16:42:08 -0700398 mNavBar.setVisibility(VISIBLE);
399 }
400 }
401
Michael Kolb4923c222012-04-02 16:18:36 -0700402 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700403 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700404 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
405 }
406 }
407
John Reck1cc1d1d2012-09-04 18:13:51 -0700408 public void onResume() {
409 setFixedTitleBar();
410 }
411
John Reck0f602f32011-07-07 15:38:43 -0700412}