blob: 6c9130a24325866856ac6532afbf744cdc838c86 [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;
John Reck1cc1d1d2012-09-04 18:13:51 -070030import android.view.accessibility.AccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070031import android.view.animation.Animation;
32import android.view.animation.Animation.AnimationListener;
33import android.view.animation.AnimationUtils;
34import android.view.animation.DecelerateInterpolator;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080035import org.codeaurora.swe.WebView;
36
Bijan Amirzada41242f22014-03-21 12:12:18 -070037import com.android.browser.R;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080038
John Reck0f602f32011-07-07 15:38:43 -070039import android.widget.FrameLayout;
40import android.widget.RelativeLayout;
41
42
43/**
44 * Base class for a title bar used by the browser.
45 */
46public class TitleBar extends RelativeLayout {
47
48 private static final int PROGRESS_MAX = 100;
49 private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
50
51 private UiController mUiController;
52 private BaseUi mBaseUi;
John Reck2711fab2012-05-18 21:38:59 -070053 private FrameLayout mContentView;
John Reck0f602f32011-07-07 15:38:43 -070054 private PageProgressView mProgress;
John Reck1cc1d1d2012-09-04 18:13:51 -070055 private AccessibilityManager mAccessibilityManager;
John Reck0f602f32011-07-07 15:38:43 -070056
John Reck0f602f32011-07-07 15:38:43 -070057 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
Ben Murdochd51bb572011-08-17 20:42:02 +010087 private void inflateSnapshotBar() {
88 if (mSnapshotBar != null) {
89 return;
90 }
91
92 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
93 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -070094 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070095 }
96
Michael Kolb57059a82012-04-30 14:32:03 -070097 @Override
98 protected void onConfigurationChanged(Configuration config) {
99 super.onConfigurationChanged(config);
John Reck0f9aaeb2012-05-23 14:40:19 -0700100 setFixedTitleBar();
John Reck2711fab2012-05-18 21:38:59 -0700101 }
102
103 @Override
104 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
105 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Vivek Sekhar60eb9802014-07-21 19:13:33 -0700106 if (mIsFixedTitleBar) {
John Reck2711fab2012-05-18 21:38:59 -0700107 int margin = getMeasuredHeight() - calculateEmbeddedHeight();
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700108 if (!isEditingUrl())
109 mBaseUi.setContentViewMarginTop(-margin);
John Reck0f9aaeb2012-05-23 14:40:19 -0700110 } else {
111 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700112 }
113 }
114
John Reck0f9aaeb2012-05-23 14:40:19 -0700115 private void setFixedTitleBar() {
116 boolean isFixed = !mUseQuickControls
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800117 && !getContext().getResources().getBoolean(R.bool.hide_title);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700118
John Reck1cc1d1d2012-09-04 18:13:51 -0700119 isFixed |= mAccessibilityManager.isEnabled();
John Reck2711fab2012-05-18 21:38:59 -0700120 // If getParent() returns null, we are initializing
121 ViewGroup parent = (ViewGroup)getParent();
122 if (mIsFixedTitleBar == isFixed && parent != null) return;
123 mIsFixedTitleBar = isFixed;
124 setSkipTitleBarAnimations(true);
125 show();
126 setSkipTitleBarAnimations(false);
127 if (parent != null) {
128 parent.removeView(this);
129 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700130 if (mIsFixedTitleBar) {
John Reck2711fab2012-05-18 21:38:59 -0700131 mBaseUi.addFixedTitleBar(this);
132 } else {
133 mContentView.addView(this, makeLayoutParams());
134 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700135 }
136 }
137
John Reck0f602f32011-07-07 15:38:43 -0700138 public BaseUi getUi() {
139 return mBaseUi;
140 }
141
142 public UiController getUiController() {
143 return mUiController;
144 }
145
146 public void setUseQuickControls(boolean use) {
147 mUseQuickControls = use;
John Reck0f9aaeb2012-05-23 14:40:19 -0700148 setFixedTitleBar();
Michael Kolb4923c222012-04-02 16:18:36 -0700149 if (use) {
150 this.setVisibility(View.GONE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700151 hideTopControls();
Michael Kolb4923c222012-04-02 16:18:36 -0700152 } else {
153 this.setVisibility(View.VISIBLE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700154 enableTopControls();
Michael Kolb4923c222012-04-02 16:18:36 -0700155 }
John Reck0f602f32011-07-07 15:38:43 -0700156 }
157
158 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700159 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700160 mNavBar.setVisibility(View.GONE);
161 } else {
162 mNavBar.setVisibility(View.VISIBLE);
163 }
164 }
165
166 void setSkipTitleBarAnimations(boolean skip) {
167 mSkipTitleBarAnimations = skip;
168 }
169
170 void setupTitleBarAnimator(Animator animator) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800171 Resources res = getContext().getResources();
John Reck0f602f32011-07-07 15:38:43 -0700172 int duration = res.getInteger(R.integer.titlebar_animation_duration);
173 animator.setInterpolator(new DecelerateInterpolator(
174 ANIM_TITLEBAR_DECELERATE));
175 animator.setDuration(duration);
176 }
177
Tarun Nainani8eb00912014-07-17 12:28:32 -0700178 //Disable stock autohide behavior in favor of top controls
179 private static final boolean bOldStyleAutoHideDisabled = true;
John Reck0f602f32011-07-07 15:38:43 -0700180 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700181 cancelTitleBarAnimation(false);
182 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700183 this.setVisibility(View.VISIBLE);
184 this.setTranslationY(0);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700185 hideTopControls();
186 } else if (!bOldStyleAutoHideDisabled) {
John Reck2711fab2012-05-18 21:38:59 -0700187 int visibleHeight = getVisibleTitleHeight();
188 float startPos = (-getEmbeddedHeight() + visibleHeight);
189 if (getTranslationY() != 0) {
190 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700191 }
John Reck2711fab2012-05-18 21:38:59 -0700192 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
193 "translationY",
194 startPos, 0);
195 setupTitleBarAnimator(mTitleBarAnimator);
196 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700197 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700198
John Reck0f602f32011-07-07 15:38:43 -0700199 mShowing = true;
200 }
201
202 void hide() {
203 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700204 this.setVisibility(View.GONE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700205 hideTopControls();
John Reck0f602f32011-07-07 15:38:43 -0700206 } else {
Tarun Nainani8eb00912014-07-17 12:28:32 -0700207 if (mIsFixedTitleBar || bOldStyleAutoHideDisabled) return;
John Reck0f602f32011-07-07 15:38:43 -0700208 if (!mSkipTitleBarAnimations) {
209 cancelTitleBarAnimation(false);
210 int visibleHeight = getVisibleTitleHeight();
211 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
212 "translationY", getTranslationY(),
213 (-getEmbeddedHeight() + visibleHeight));
214 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
215 setupTitleBarAnimator(mTitleBarAnimator);
216 mTitleBarAnimator.start();
217 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700218 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700219 }
220 }
221 mShowing = false;
222 }
223
224 boolean isShowing() {
225 return mShowing;
226 }
227
228 void cancelTitleBarAnimation(boolean reset) {
229 if (mTitleBarAnimator != null) {
230 mTitleBarAnimator.cancel();
231 mTitleBarAnimator = null;
232 }
233 if (reset) {
234 setTranslationY(0);
235 }
236 }
237
238 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
239
John Reck0f602f32011-07-07 15:38:43 -0700240 @Override
241 public void onAnimationStart(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700242 }
243
244 @Override
245 public void onAnimationRepeat(Animator animation) {
246 }
247
248 @Override
249 public void onAnimationEnd(Animator animation) {
Michael Kolb4923c222012-04-02 16:18:36 -0700250 // update position
251 onScrollChanged();
John Reck0f602f32011-07-07 15:38:43 -0700252 }
253
254 @Override
255 public void onAnimationCancel(Animator animation) {
John Reck0f602f32011-07-07 15:38:43 -0700256 }
257 };
258
259 private int getVisibleTitleHeight() {
260 Tab tab = mBaseUi.getActiveTab();
261 WebView webview = tab != null ? tab.getWebView() : null;
262 return webview != null ? webview.getVisibleTitleHeight() : 0;
263 }
264
Tarun Nainani8eb00912014-07-17 12:28:32 -0700265 private void hideTopControls() {
266 Tab tab = mBaseUi.getActiveTab();
267 WebView view = tab != null ? tab.getWebView() : null;
268 if (view != null)
269 view.updateTopControls(true, false, true);
270 }
271
272 private void showTopControls() {
273 Tab tab = mBaseUi.getActiveTab();
274 WebView view = tab != null ? tab.getWebView() : null;
275 if (view != null)
276 view.updateTopControls(false, true, true);
277 }
278
279 private void enableTopControls() {
280 Tab tab = mBaseUi.getActiveTab();
281 WebView view = tab != null ? tab.getWebView() : null;
282 if (view != null)
283 view.updateTopControls(true, true, true);
284 }
285
286
John Reck0f602f32011-07-07 15:38:43 -0700287 /**
288 * Update the progress, from 0 to 100.
289 */
290 public void setProgress(int newProgress) {
Tarun Nainani8eb00912014-07-17 12:28:32 -0700291 Tab tab = mBaseUi.getActiveTab();
292 WebView view = tab != null ? tab.getWebView() : null;
293
John Reck0f602f32011-07-07 15:38:43 -0700294 if (newProgress >= PROGRESS_MAX) {
295 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
296 mProgress.setVisibility(View.GONE);
297 mInLoad = false;
298 mNavBar.onProgressStopped();
299 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700300 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700301 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700302 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700303 } else {
304 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700305 }
306 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700307
308 //onPageFinished
309 if (mUseQuickControls) {
310 hideTopControls();
311 } else {
312 enableTopControls();
313 }
314
John Reck0f602f32011-07-07 15:38:43 -0700315 } else {
316 if (!mInLoad) {
317 mProgress.setVisibility(View.VISIBLE);
318 mInLoad = true;
319 mNavBar.onProgressStarted();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700320
321 //onPageStarted
322 if (mUseQuickControls) {
323 hideTopControls();
324 } else {
325 showTopControls();
326 }
John Reck0f602f32011-07-07 15:38:43 -0700327 }
328 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
329 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700330 if (mUseQuickControls && !isEditingUrl()) {
331 setShowProgressOnly(true);
332 }
John Reck0f602f32011-07-07 15:38:43 -0700333 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700334 show();
335 }
336 }
337 }
338
339 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700340 if (mUseQuickControls || mIsFixedTitleBar) return 0;
341 return calculateEmbeddedHeight();
342 }
343
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800344 public boolean isFixed() {
345 return mIsFixedTitleBar;
346 }
347
348 int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700349 int height = mNavBar.getHeight();
John Reck0f602f32011-07-07 15:38:43 -0700350 return height;
351 }
352
John Reckef654f12011-07-12 16:42:08 -0700353 public boolean wantsToBeVisible() {
Bijan Amirzada289e1e62014-04-15 11:53:48 -0700354 return (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700355 && mSnapshotBar.isAnimating());
356 }
357
John Reck0f602f32011-07-07 15:38:43 -0700358 public boolean isEditingUrl() {
359 return mNavBar.isEditingUrl();
360 }
361
362 public WebView getCurrentWebView() {
363 Tab t = mBaseUi.getActiveTab();
364 if (t != null) {
365 return t.getWebView();
366 } else {
367 return null;
368 }
369 }
370
371 public PageProgressView getProgressView() {
372 return mProgress;
373 }
374
375 public NavigationBarBase getNavigationBar() {
376 return mNavBar;
377 }
378
379 public boolean useQuickControls() {
380 return mUseQuickControls;
381 }
382
383 public boolean isInLoad() {
384 return mInLoad;
385 }
386
387 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700388 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
389 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700390 }
391
392 @Override
Panos Thomas752ce592014-10-16 13:00:35 -0700393 public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
394 return mBaseUi.isCustomViewShowing() ? false :
395 super.requestFocus(direction, previouslyFocusedRect);
396 }
397
398 @Override
John Reck0f602f32011-07-07 15:38:43 -0700399 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700400 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700401 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700402 && web.hasFocusable() && web.getParent() != null) {
403 return web;
John Reck0f602f32011-07-07 15:38:43 -0700404 }
405 return super.focusSearch(focused, dir);
406 }
407
John Reckef654f12011-07-12 16:42:08 -0700408 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100409 if (mSnapshotBar != null) {
410 mSnapshotBar.onTabDataChanged(tab);
411 }
412
John Reckef654f12011-07-12 16:42:08 -0700413 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100414 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700415 mSnapshotBar.setVisibility(VISIBLE);
416 mNavBar.setVisibility(GONE);
417 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100418 if (mSnapshotBar != null) {
419 mSnapshotBar.setVisibility(GONE);
420 }
John Reckef654f12011-07-12 16:42:08 -0700421 mNavBar.setVisibility(VISIBLE);
422 }
423 }
424
Michael Kolb4923c222012-04-02 16:18:36 -0700425 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700426 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700427 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
428 }
429 }
430
John Reck1cc1d1d2012-09-04 18:13:51 -0700431 public void onResume() {
432 setFixedTitleBar();
433 }
434
John Reck0f602f32011-07-07 15:38:43 -0700435}