blob: fa22213c1e0f2390deae0a71c034b0a705947b81 [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
John Reck0f602f32011-07-07 15:38:43 -070056 private NavigationBarBase mNavBar;
57 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070058 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070059
60 //state
61 private boolean mShowing;
62 private boolean mInLoad;
63 private boolean mSkipTitleBarAnimations;
64 private Animator mTitleBarAnimator;
John Reck2711fab2012-05-18 21:38:59 -070065 private boolean mIsFixedTitleBar;
John Reck0f602f32011-07-07 15:38:43 -070066
67 public TitleBar(Context context, UiController controller, BaseUi ui,
John Reck2711fab2012-05-18 21:38:59 -070068 FrameLayout contentView) {
John Reck0f602f32011-07-07 15:38:43 -070069 super(context, null);
70 mUiController = controller;
71 mBaseUi = ui;
John Reck2711fab2012-05-18 21:38:59 -070072 mContentView = contentView;
John Reck1cc1d1d2012-09-04 18:13:51 -070073 mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
John Reck0f602f32011-07-07 15:38:43 -070074 initLayout(context);
John Reck0f9aaeb2012-05-23 14:40:19 -070075 setFixedTitleBar();
John Reck0f602f32011-07-07 15:38:43 -070076 }
77
78 private void initLayout(Context context) {
79 LayoutInflater factory = LayoutInflater.from(context);
80 factory.inflate(R.layout.title_bar, this);
81 mProgress = (PageProgressView) findViewById(R.id.progress);
John Reck0f602f32011-07-07 15:38:43 -070082 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
83 mNavBar.setTitleBar(this);
Ben Murdochd51bb572011-08-17 20:42:02 +010084 }
85
Ben Murdochd51bb572011-08-17 20:42:02 +010086 private void inflateSnapshotBar() {
87 if (mSnapshotBar != null) {
88 return;
89 }
90
91 ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
92 mSnapshotBar = (SnapshotBar) stub.inflate();
John Reckef654f12011-07-12 16:42:08 -070093 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070094 }
95
Michael Kolb57059a82012-04-30 14:32:03 -070096 @Override
97 protected void onConfigurationChanged(Configuration config) {
98 super.onConfigurationChanged(config);
John Reck0f9aaeb2012-05-23 14:40:19 -070099 setFixedTitleBar();
John Reck2711fab2012-05-18 21:38:59 -0700100 }
101
102 @Override
103 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
104 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Vivek Sekhar60eb9802014-07-21 19:13:33 -0700105 if (mIsFixedTitleBar) {
John Reck2711fab2012-05-18 21:38:59 -0700106 int margin = getMeasuredHeight() - calculateEmbeddedHeight();
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700107 if (!isEditingUrl())
108 mBaseUi.setContentViewMarginTop(-margin);
John Reck0f9aaeb2012-05-23 14:40:19 -0700109 } else {
110 mBaseUi.setContentViewMarginTop(0);
John Reck2711fab2012-05-18 21:38:59 -0700111 }
112 }
113
John Reck0f9aaeb2012-05-23 14:40:19 -0700114 private void setFixedTitleBar() {
115 boolean isFixed = !mUseQuickControls
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800116 && !getContext().getResources().getBoolean(R.bool.hide_title);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700117
John Reck1cc1d1d2012-09-04 18:13:51 -0700118 isFixed |= mAccessibilityManager.isEnabled();
John Reck2711fab2012-05-18 21:38:59 -0700119 // If getParent() returns null, we are initializing
120 ViewGroup parent = (ViewGroup)getParent();
121 if (mIsFixedTitleBar == isFixed && parent != null) return;
122 mIsFixedTitleBar = isFixed;
123 setSkipTitleBarAnimations(true);
124 show();
125 setSkipTitleBarAnimations(false);
126 if (parent != null) {
127 parent.removeView(this);
128 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700129 if (mIsFixedTitleBar) {
John Reck2711fab2012-05-18 21:38:59 -0700130 mBaseUi.addFixedTitleBar(this);
131 } else {
132 mContentView.addView(this, makeLayoutParams());
133 mBaseUi.setContentViewMarginTop(0);
Michael Kolb57059a82012-04-30 14:32:03 -0700134 }
135 }
136
John Reck0f602f32011-07-07 15:38:43 -0700137 public BaseUi getUi() {
138 return mBaseUi;
139 }
140
141 public UiController getUiController() {
142 return mUiController;
143 }
144
145 public void setUseQuickControls(boolean use) {
146 mUseQuickControls = use;
John Reck0f9aaeb2012-05-23 14:40:19 -0700147 setFixedTitleBar();
Michael Kolb4923c222012-04-02 16:18:36 -0700148 if (use) {
149 this.setVisibility(View.GONE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700150 hideTopControls();
Michael Kolb4923c222012-04-02 16:18:36 -0700151 } else {
152 this.setVisibility(View.VISIBLE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700153 enableTopControls();
Michael Kolb4923c222012-04-02 16:18:36 -0700154 }
John Reck0f602f32011-07-07 15:38:43 -0700155 }
156
157 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -0700158 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700159 mNavBar.setVisibility(View.GONE);
160 } else {
161 mNavBar.setVisibility(View.VISIBLE);
162 }
163 }
164
165 void setSkipTitleBarAnimations(boolean skip) {
166 mSkipTitleBarAnimations = skip;
167 }
168
169 void setupTitleBarAnimator(Animator animator) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800170 Resources res = getContext().getResources();
John Reck0f602f32011-07-07 15:38:43 -0700171 int duration = res.getInteger(R.integer.titlebar_animation_duration);
172 animator.setInterpolator(new DecelerateInterpolator(
173 ANIM_TITLEBAR_DECELERATE));
174 animator.setDuration(duration);
175 }
176
Tarun Nainani8eb00912014-07-17 12:28:32 -0700177 //Disable stock autohide behavior in favor of top controls
178 private static final boolean bOldStyleAutoHideDisabled = true;
John Reck0f602f32011-07-07 15:38:43 -0700179 void show() {
John Reck2711fab2012-05-18 21:38:59 -0700180 cancelTitleBarAnimation(false);
181 if (mUseQuickControls || mSkipTitleBarAnimations) {
Michael Kolb4923c222012-04-02 16:18:36 -0700182 this.setVisibility(View.VISIBLE);
183 this.setTranslationY(0);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700184 hideTopControls();
185 } else if (!bOldStyleAutoHideDisabled) {
John Reck2711fab2012-05-18 21:38:59 -0700186 int visibleHeight = getVisibleTitleHeight();
187 float startPos = (-getEmbeddedHeight() + visibleHeight);
188 if (getTranslationY() != 0) {
189 startPos = Math.max(startPos, getTranslationY());
John Reck0f602f32011-07-07 15:38:43 -0700190 }
John Reck2711fab2012-05-18 21:38:59 -0700191 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
192 "translationY",
193 startPos, 0);
194 setupTitleBarAnimator(mTitleBarAnimator);
195 mTitleBarAnimator.start();
John Reck0f602f32011-07-07 15:38:43 -0700196 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700197
John Reck0f602f32011-07-07 15:38:43 -0700198 mShowing = true;
199 }
200
201 void hide() {
202 if (mUseQuickControls) {
Michael Kolb4923c222012-04-02 16:18:36 -0700203 this.setVisibility(View.GONE);
Tarun Nainani8eb00912014-07-17 12:28:32 -0700204 hideTopControls();
John Reck0f602f32011-07-07 15:38:43 -0700205 } else {
Tarun Nainani8eb00912014-07-17 12:28:32 -0700206 if (mIsFixedTitleBar || bOldStyleAutoHideDisabled) 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
Tarun Nainani8eb00912014-07-17 12:28:32 -0700264 private void hideTopControls() {
265 Tab tab = mBaseUi.getActiveTab();
266 WebView view = tab != null ? tab.getWebView() : null;
267 if (view != null)
268 view.updateTopControls(true, false, true);
269 }
270
271 private void showTopControls() {
272 Tab tab = mBaseUi.getActiveTab();
273 WebView view = tab != null ? tab.getWebView() : null;
274 if (view != null)
275 view.updateTopControls(false, true, true);
276 }
277
278 private void enableTopControls() {
279 Tab tab = mBaseUi.getActiveTab();
280 WebView view = tab != null ? tab.getWebView() : null;
281 if (view != null)
282 view.updateTopControls(true, true, true);
283 }
284
285
John Reck0f602f32011-07-07 15:38:43 -0700286 /**
287 * Update the progress, from 0 to 100.
288 */
289 public void setProgress(int newProgress) {
Tarun Nainani8eb00912014-07-17 12:28:32 -0700290 Tab tab = mBaseUi.getActiveTab();
291 WebView view = tab != null ? tab.getWebView() : null;
292
John Reck0f602f32011-07-07 15:38:43 -0700293 if (newProgress >= PROGRESS_MAX) {
294 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
295 mProgress.setVisibility(View.GONE);
296 mInLoad = false;
297 mNavBar.onProgressStopped();
298 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700299 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700300 if (mUseQuickControls) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700301 hide();
John Reckbc82ec92012-04-19 13:12:35 -0700302 } else {
303 mBaseUi.showTitleBarForDuration();
John Reck0f602f32011-07-07 15:38:43 -0700304 }
305 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700306
307 //onPageFinished
308 if (mUseQuickControls) {
309 hideTopControls();
310 } else {
311 enableTopControls();
312 }
313
John Reck0f602f32011-07-07 15:38:43 -0700314 } else {
315 if (!mInLoad) {
316 mProgress.setVisibility(View.VISIBLE);
317 mInLoad = true;
318 mNavBar.onProgressStarted();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700319
320 //onPageStarted
321 if (mUseQuickControls) {
322 hideTopControls();
323 } else {
324 showTopControls();
325 }
John Reck0f602f32011-07-07 15:38:43 -0700326 }
327 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
328 / PROGRESS_MAX);
Michael Kolbe8a82332012-04-25 14:14:26 -0700329 if (mUseQuickControls && !isEditingUrl()) {
330 setShowProgressOnly(true);
331 }
John Reck0f602f32011-07-07 15:38:43 -0700332 if (!mShowing) {
John Reck0f602f32011-07-07 15:38:43 -0700333 show();
334 }
335 }
336 }
337
338 public int getEmbeddedHeight() {
John Reck2711fab2012-05-18 21:38:59 -0700339 if (mUseQuickControls || mIsFixedTitleBar) return 0;
340 return calculateEmbeddedHeight();
341 }
342
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800343 public boolean isFixed() {
344 return mIsFixedTitleBar;
345 }
346
347 int calculateEmbeddedHeight() {
John Reck0f602f32011-07-07 15:38:43 -0700348 int height = mNavBar.getHeight();
John Reck0f602f32011-07-07 15:38:43 -0700349 return height;
350 }
351
John Reckef654f12011-07-12 16:42:08 -0700352 public boolean wantsToBeVisible() {
Bijan Amirzada289e1e62014-04-15 11:53:48 -0700353 return (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
John Reckef654f12011-07-12 16:42:08 -0700354 && mSnapshotBar.isAnimating());
355 }
356
John Reck0f602f32011-07-07 15:38:43 -0700357 public boolean isEditingUrl() {
358 return mNavBar.isEditingUrl();
359 }
360
361 public WebView getCurrentWebView() {
362 Tab t = mBaseUi.getActiveTab();
363 if (t != null) {
364 return t.getWebView();
365 } else {
366 return null;
367 }
368 }
369
370 public PageProgressView getProgressView() {
371 return mProgress;
372 }
373
374 public NavigationBarBase getNavigationBar() {
375 return mNavBar;
376 }
377
378 public boolean useQuickControls() {
379 return mUseQuickControls;
380 }
381
382 public boolean isInLoad() {
383 return mInLoad;
384 }
385
386 private ViewGroup.LayoutParams makeLayoutParams() {
Michael Kolb4923c222012-04-02 16:18:36 -0700387 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
388 LayoutParams.WRAP_CONTENT);
John Reck0f602f32011-07-07 15:38:43 -0700389 }
390
391 @Override
392 public View focusSearch(View focused, int dir) {
John Reckfcb60952012-05-30 09:45:28 -0700393 WebView web = getCurrentWebView();
John Reckd70419a2012-05-30 16:09:17 -0700394 if (FOCUS_DOWN == dir && hasFocus() && web != null
John Reckfcb60952012-05-30 09:45:28 -0700395 && web.hasFocusable() && web.getParent() != null) {
396 return web;
John Reck0f602f32011-07-07 15:38:43 -0700397 }
398 return super.focusSearch(focused, dir);
399 }
400
John Reckef654f12011-07-12 16:42:08 -0700401 public void onTabDataChanged(Tab tab) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100402 if (mSnapshotBar != null) {
403 mSnapshotBar.onTabDataChanged(tab);
404 }
405
John Reckef654f12011-07-12 16:42:08 -0700406 if (tab.isSnapshot()) {
Ben Murdochd51bb572011-08-17 20:42:02 +0100407 inflateSnapshotBar();
John Reckef654f12011-07-12 16:42:08 -0700408 mSnapshotBar.setVisibility(VISIBLE);
409 mNavBar.setVisibility(GONE);
410 } else {
Ben Murdochd51bb572011-08-17 20:42:02 +0100411 if (mSnapshotBar != null) {
412 mSnapshotBar.setVisibility(GONE);
413 }
John Reckef654f12011-07-12 16:42:08 -0700414 mNavBar.setVisibility(VISIBLE);
415 }
416 }
417
Michael Kolb4923c222012-04-02 16:18:36 -0700418 public void onScrollChanged() {
John Reck2711fab2012-05-18 21:38:59 -0700419 if (!mShowing && !mIsFixedTitleBar) {
Michael Kolb4923c222012-04-02 16:18:36 -0700420 setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
421 }
422 }
423
John Reck1cc1d1d2012-09-04 18:13:51 -0700424 public void onResume() {
425 setFixedTitleBar();
426 }
427
John Reck0f602f32011-07-07 15:38:43 -0700428}