blob: 9848a3956989be6ab2c24c34f74793a83c1a402a [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
17package com.android.browser;
18
19import android.animation.Animator;
20import android.animation.Animator.AnimatorListener;
21import android.animation.ObjectAnimator;
22import android.content.Context;
23import android.content.res.Resources;
24import android.view.Gravity;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
28import android.view.animation.Animation;
29import android.view.animation.Animation.AnimationListener;
30import android.view.animation.AnimationUtils;
31import android.view.animation.DecelerateInterpolator;
32import android.webkit.WebView;
33import android.widget.AbsoluteLayout;
34import android.widget.FrameLayout;
35import android.widget.RelativeLayout;
36
37
38/**
39 * Base class for a title bar used by the browser.
40 */
41public class TitleBar extends RelativeLayout {
42
43 private static final int PROGRESS_MAX = 100;
44 private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
45
46 private UiController mUiController;
47 private BaseUi mBaseUi;
48 private FrameLayout mParent;
49 private PageProgressView mProgress;
50
51 private AutologinBar mAutoLogin;
52 private NavigationBarBase mNavBar;
53 private boolean mUseQuickControls;
John Reckef654f12011-07-12 16:42:08 -070054 private SnapshotBar mSnapshotBar;
John Reck0f602f32011-07-07 15:38:43 -070055
56 //state
57 private boolean mShowing;
58 private boolean mInLoad;
59 private boolean mSkipTitleBarAnimations;
60 private Animator mTitleBarAnimator;
61
62 public TitleBar(Context context, UiController controller, BaseUi ui,
63 FrameLayout parent) {
64 super(context, null);
65 mUiController = controller;
66 mBaseUi = ui;
67 mParent = parent;
68 initLayout(context);
69 }
70
71 private void initLayout(Context context) {
72 LayoutInflater factory = LayoutInflater.from(context);
73 factory.inflate(R.layout.title_bar, this);
74 mProgress = (PageProgressView) findViewById(R.id.progress);
75 mAutoLogin = (AutologinBar) findViewById(R.id.autologin);
76 mAutoLogin.setTitleBar(this);
77 mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
78 mNavBar.setTitleBar(this);
John Reckef654f12011-07-12 16:42:08 -070079 mSnapshotBar = (SnapshotBar) findViewById(R.id.snapshotbar);
80 mSnapshotBar.setTitleBar(this);
John Reck0f602f32011-07-07 15:38:43 -070081 }
82
83 public BaseUi getUi() {
84 return mBaseUi;
85 }
86
87 public UiController getUiController() {
88 return mUiController;
89 }
90
91 public void setUseQuickControls(boolean use) {
92 mUseQuickControls = use;
93 setLayoutParams(makeLayoutParams());
94 }
95
96 void setShowProgressOnly(boolean progress) {
John Reckef654f12011-07-12 16:42:08 -070097 if (progress && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -070098 mNavBar.setVisibility(View.GONE);
99 } else {
100 mNavBar.setVisibility(View.VISIBLE);
101 }
102 }
103
104 void setSkipTitleBarAnimations(boolean skip) {
105 mSkipTitleBarAnimations = skip;
106 }
107
108 void setupTitleBarAnimator(Animator animator) {
109 Resources res = mContext.getResources();
110 int duration = res.getInteger(R.integer.titlebar_animation_duration);
111 animator.setInterpolator(new DecelerateInterpolator(
112 ANIM_TITLEBAR_DECELERATE));
113 animator.setDuration(duration);
114 }
115
116 void show() {
117 if (mUseQuickControls) {
118 mParent.addView(this);
119 } else {
120 if (!mSkipTitleBarAnimations) {
121 cancelTitleBarAnimation(false);
122 int visibleHeight = getVisibleTitleHeight();
123 float startPos = (-getEmbeddedHeight() + visibleHeight);
124 if (getTranslationY() != 0) {
125 startPos = Math.max(startPos, getTranslationY());
126 }
127 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
128 "translationY",
129 startPos, 0);
130 setupTitleBarAnimator(mTitleBarAnimator);
131 mTitleBarAnimator.start();
132 }
133 mBaseUi.setTitleGravity(Gravity.TOP);
134 }
135 mShowing = true;
136 }
137
138 void hide() {
139 if (mUseQuickControls) {
140 mParent.removeView(this);
141 } else {
142 if (!mSkipTitleBarAnimations) {
143 cancelTitleBarAnimation(false);
144 int visibleHeight = getVisibleTitleHeight();
145 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
146 "translationY", getTranslationY(),
147 (-getEmbeddedHeight() + visibleHeight));
148 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
149 setupTitleBarAnimator(mTitleBarAnimator);
150 mTitleBarAnimator.start();
151 } else {
152 mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
153 }
154 }
155 mShowing = false;
156 }
157
158 boolean isShowing() {
159 return mShowing;
160 }
161
162 void cancelTitleBarAnimation(boolean reset) {
163 if (mTitleBarAnimator != null) {
164 mTitleBarAnimator.cancel();
165 mTitleBarAnimator = null;
166 }
167 if (reset) {
168 setTranslationY(0);
169 }
170 }
171
172 private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
173
174 boolean mWasCanceled;
175 @Override
176 public void onAnimationStart(Animator animation) {
177 mWasCanceled = false;
178 }
179
180 @Override
181 public void onAnimationRepeat(Animator animation) {
182 }
183
184 @Override
185 public void onAnimationEnd(Animator animation) {
186 if (!mWasCanceled) {
187 setTranslationY(0);
188 }
189 mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
190 }
191
192 @Override
193 public void onAnimationCancel(Animator animation) {
194 mWasCanceled = true;
195 }
196 };
197
198 private int getVisibleTitleHeight() {
199 Tab tab = mBaseUi.getActiveTab();
200 WebView webview = tab != null ? tab.getWebView() : null;
201 return webview != null ? webview.getVisibleTitleHeight() : 0;
202 }
203
204 /**
205 * Update the progress, from 0 to 100.
206 */
207 public void setProgress(int newProgress) {
208 if (newProgress >= PROGRESS_MAX) {
209 mProgress.setProgress(PageProgressView.MAX_PROGRESS);
210 mProgress.setVisibility(View.GONE);
211 mInLoad = false;
212 mNavBar.onProgressStopped();
213 // check if needs to be hidden
John Reckef654f12011-07-12 16:42:08 -0700214 if (!isEditingUrl() && !wantsToBeVisible()) {
John Reck0f602f32011-07-07 15:38:43 -0700215 hide();
216 if (mUseQuickControls) {
217 setShowProgressOnly(false);
218 }
219 }
220 } else {
221 if (!mInLoad) {
222 mProgress.setVisibility(View.VISIBLE);
223 mInLoad = true;
224 mNavBar.onProgressStarted();
225 }
226 mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
227 / PROGRESS_MAX);
228 if (!mShowing) {
229 if (mUseQuickControls && !isEditingUrl()) {
230 setShowProgressOnly(true);
231 }
232 show();
233 }
234 }
235 }
236
237 public int getEmbeddedHeight() {
238 int height = mNavBar.getHeight();
239 if (mAutoLogin.getVisibility() == View.VISIBLE) {
240 height += mAutoLogin.getHeight();
241 }
242 return height;
243 }
244
245 public void updateAutoLogin(Tab tab, boolean animate) {
246 mAutoLogin.updateAutoLogin(tab, animate);
247 }
248
249 public void showAutoLogin(boolean animate) {
250 if (mUseQuickControls) {
251 mBaseUi.showTitleBar();
252 }
253 mAutoLogin.setVisibility(View.VISIBLE);
254 if (animate) {
255 mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
256 getContext(), R.anim.autologin_enter));
257 }
258 }
259
260 public void hideAutoLogin(boolean animate) {
261 if (mUseQuickControls) {
262 mBaseUi.hideTitleBar();
263 mAutoLogin.setVisibility(View.GONE);
264 mBaseUi.refreshWebView();
265 } else {
266 if (animate) {
267 Animation anim = AnimationUtils.loadAnimation(getContext(),
268 R.anim.autologin_exit);
269 anim.setAnimationListener(new AnimationListener() {
270 @Override
271 public void onAnimationEnd(Animation a) {
272 mAutoLogin.setVisibility(View.GONE);
273 mBaseUi.refreshWebView();
274 }
275
276 @Override
277 public void onAnimationStart(Animation a) {
278 }
279
280 @Override
281 public void onAnimationRepeat(Animation a) {
282 }
283 });
284 mAutoLogin.startAnimation(anim);
285 } else if (mAutoLogin.getAnimation() == null) {
286 mAutoLogin.setVisibility(View.GONE);
287 mBaseUi.refreshWebView();
288 }
289 }
290 }
291
John Reckef654f12011-07-12 16:42:08 -0700292 public boolean wantsToBeVisible() {
293 return inAutoLogin()
294 || (mSnapshotBar.getVisibility() == View.VISIBLE
295 && mSnapshotBar.isAnimating());
296 }
297
298 private boolean inAutoLogin() {
John Reck0f602f32011-07-07 15:38:43 -0700299 return mAutoLogin.getVisibility() == View.VISIBLE;
300 }
301
302 public boolean isEditingUrl() {
303 return mNavBar.isEditingUrl();
304 }
305
306 public WebView getCurrentWebView() {
307 Tab t = mBaseUi.getActiveTab();
308 if (t != null) {
309 return t.getWebView();
310 } else {
311 return null;
312 }
313 }
314
315 public PageProgressView getProgressView() {
316 return mProgress;
317 }
318
319 public NavigationBarBase getNavigationBar() {
320 return mNavBar;
321 }
322
323 public boolean useQuickControls() {
324 return mUseQuickControls;
325 }
326
327 public boolean isInLoad() {
328 return mInLoad;
329 }
330
331 private ViewGroup.LayoutParams makeLayoutParams() {
332 if (mUseQuickControls) {
333 return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
334 LayoutParams.WRAP_CONTENT);
335 } else {
336 return new AbsoluteLayout.LayoutParams(
337 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
338 0, 0);
339 }
340 }
341
342 @Override
343 public View focusSearch(View focused, int dir) {
344 if (FOCUS_DOWN == dir && hasFocus()) {
345 return getCurrentWebView();
346 }
347 return super.focusSearch(focused, dir);
348 }
349
John Reckef654f12011-07-12 16:42:08 -0700350 public void onTabDataChanged(Tab tab) {
351 mSnapshotBar.onTabDataChanged(tab);
352 if (tab.isSnapshot()) {
353 mSnapshotBar.setVisibility(VISIBLE);
354 mNavBar.setVisibility(GONE);
355 } else {
356 mSnapshotBar.setVisibility(GONE);
357 mNavBar.setVisibility(VISIBLE);
358 }
359 }
360
John Reck0f602f32011-07-07 15:38:43 -0700361}