blob: 5afb9c447c8d470106b67f921e9e0e1c81a97aab [file] [log] [blame]
Michael Kolb66706532010-12-12 19:50:22 -08001/*
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
Michael Kolbc3af0672011-08-09 10:24:41 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
Michael Kolb66706532010-12-12 19:50:22 -080023import android.app.Activity;
Michael Kolbc3af0672011-08-09 10:24:41 -070024import android.content.Context;
25import android.graphics.Bitmap;
26import android.graphics.Canvas;
27import android.graphics.Matrix;
John Reck9c5004e2011-10-07 16:00:12 -070028import android.os.Message;
Michael Kolb376b5412010-12-15 11:52:57 -080029import android.util.Log;
John Reckaae029c2011-09-16 14:36:39 -070030import android.util.TypedValue;
Michael Kolb66706532010-12-12 19:50:22 -080031import android.view.ActionMode;
32import android.view.Gravity;
Michael Kolba4183062011-01-16 10:43:21 -080033import android.view.KeyEvent;
Michael Kolbc3af0672011-08-09 10:24:41 -070034import android.view.LayoutInflater;
Michael Kolb66706532010-12-12 19:50:22 -080035import android.view.Menu;
Michael Kolb3ca12752011-07-20 13:52:25 -070036import android.view.MenuItem;
Michael Kolb66706532010-12-12 19:50:22 -080037import android.view.View;
Michael Kolb199e43c2011-08-17 10:45:45 -070038import android.view.ViewGroup;
Michael Kolb30adae62011-07-29 13:37:05 -070039import android.view.accessibility.AccessibilityEvent;
Michael Kolb66706532010-12-12 19:50:22 -080040import android.webkit.WebView;
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +000041import android.webkit.WebViewClassic;
Michael Kolbfdb70242011-03-24 09:41:11 -070042import android.widget.FrameLayout;
Michael Kolbc3af0672011-08-09 10:24:41 -070043import android.widget.ImageView;
Michael Kolb66706532010-12-12 19:50:22 -080044
Michael Kolb629b22c2011-07-13 16:26:47 -070045import com.android.browser.UrlInputView.StateListener;
46
Michael Kolb66706532010-12-12 19:50:22 -080047/**
48 * Ui for regular phone screen sizes
49 */
50public class PhoneUi extends BaseUi {
51
52 private static final String LOGTAG = "PhoneUi";
John Reck9c5004e2011-10-07 16:00:12 -070053 private static final int MSG_INIT_NAVSCREEN = 100;
Michael Kolb66706532010-12-12 19:50:22 -080054
Michael Kolb0241e752011-07-07 14:58:50 -070055 private PieControlPhone mPieControl;
Michael Kolbf2055602011-04-09 17:20:03 -070056 private NavScreen mNavScreen;
John Reckcc0059c2011-10-07 13:53:13 -070057 private AnimScreen mAnimScreen;
John Reck0f602f32011-07-07 15:38:43 -070058 private NavigationBarPhone mNavigationBar;
John Reckaae029c2011-09-16 14:36:39 -070059 private int mActionBarHeight;
Michael Kolb66706532010-12-12 19:50:22 -080060
61 boolean mExtendedMenuOpen;
62 boolean mOptionsMenuOpen;
Michael Kolb08a687a2011-04-22 16:13:02 -070063 boolean mAnimating;
Michael Kolb66706532010-12-12 19:50:22 -080064
65 /**
66 * @param browser
67 * @param controller
68 */
69 public PhoneUi(Activity browser, UiController controller) {
70 super(browser, controller);
Michael Kolbfdb70242011-03-24 09:41:11 -070071 setUseQuickControls(BrowserSettings.getInstance().useQuickControls());
John Reck0f602f32011-07-07 15:38:43 -070072 mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar();
John Reckaae029c2011-09-16 14:36:39 -070073 TypedValue heightValue = new TypedValue();
74 browser.getTheme().resolveAttribute(
75 com.android.internal.R.attr.actionBarSize, heightValue, true);
76 mActionBarHeight = TypedValue.complexToDimensionPixelSize(heightValue.data,
77 browser.getResources().getDisplayMetrics());
John Reck285ef042011-02-11 15:44:17 -080078 }
Michael Kolb66706532010-12-12 19:50:22 -080079
John Reck285ef042011-02-11 15:44:17 -080080 @Override
Michael Kolb66706532010-12-12 19:50:22 -080081 public void onDestroy() {
Michael Kolb7cdc4902011-02-03 17:54:40 -080082 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -080083 }
84
85 @Override
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080086 public void editUrl(boolean clearInput) {
Michael Kolb46f987e2011-04-05 10:39:10 -070087 if (mUseQuickControls) {
John Reck0f602f32011-07-07 15:38:43 -070088 mTitleBar.setShowProgressOnly(false);
Michael Kolb46f987e2011-04-05 10:39:10 -070089 }
90 super.editUrl(clearInput);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080091 }
92
93 @Override
Michael Kolb66706532010-12-12 19:50:22 -080094 public boolean onBackKey() {
John Reckcc0059c2011-10-07 13:53:13 -070095 if (showingNavScreen()) {
Michael Kolba3194d02011-09-07 11:23:51 -070096 mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
Michael Kolbf2055602011-04-09 17:20:03 -070097 return true;
Michael Kolb66706532010-12-12 19:50:22 -080098 }
99 return super.onBackKey();
100 }
101
John Reckcc0059c2011-10-07 13:53:13 -0700102 private boolean showingNavScreen() {
103 return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
104 }
105
Michael Kolb66706532010-12-12 19:50:22 -0800106 @Override
Michael Kolbf2055602011-04-09 17:20:03 -0700107 public boolean dispatchKey(int code, KeyEvent event) {
Michael Kolbf2055602011-04-09 17:20:03 -0700108 return false;
109 }
110
111 @Override
John Reck30c714c2010-12-16 17:30:34 -0800112 public void onProgressChanged(Tab tab) {
Michael Kolb66706532010-12-12 19:50:22 -0800113 if (tab.inForeground()) {
John Reck30c714c2010-12-16 17:30:34 -0800114 int progress = tab.getLoadProgress();
Michael Kolb7cdc4902011-02-03 17:54:40 -0800115 mTitleBar.setProgress(progress);
Michael Kolb66706532010-12-12 19:50:22 -0800116 if (progress == 100) {
117 if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
John Reck5d43ce82011-06-21 17:16:51 -0700118 suggestHideTitleBar();
Michael Kolbc16c5952011-03-29 15:37:03 -0700119 if (mUseQuickControls) {
120 mTitleBar.setShowProgressOnly(false);
121 }
Michael Kolb66706532010-12-12 19:50:22 -0800122 }
123 } else {
124 if (!mOptionsMenuOpen || mExtendedMenuOpen) {
Michael Kolbc16c5952011-03-29 15:37:03 -0700125 if (mUseQuickControls && !mTitleBar.isEditingUrl()) {
126 mTitleBar.setShowProgressOnly(true);
127 setTitleGravity(Gravity.TOP);
128 }
Michael Kolb7cdc4902011-02-03 17:54:40 -0800129 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800130 }
131 }
132 }
John Reck9c5004e2011-10-07 16:00:12 -0700133 if (mNavScreen == null && getTitleBar().getHeight() > 0) {
134 mHandler.sendEmptyMessage(MSG_INIT_NAVSCREEN);
135 }
136 }
137
138 @Override
139 protected void handleMessage(Message msg) {
140 super.handleMessage(msg);
141 if (msg.what == MSG_INIT_NAVSCREEN) {
142 if (mNavScreen == null) {
143 mNavScreen = new NavScreen(mActivity, mUiController, this);
144 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
145 mNavScreen.setVisibility(View.GONE);
146 }
147 if (mAnimScreen == null) {
148 mAnimScreen = new AnimScreen(mActivity);
149 // initialize bitmaps
150 mAnimScreen.set(getTitleBar(), getWebView());
151 }
152 }
Michael Kolb66706532010-12-12 19:50:22 -0800153 }
154
155 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700156 public void setActiveTab(final Tab tab) {
John Reck8ee633f2011-08-09 16:00:35 -0700157 mTitleBar.cancelTitleBarAnimation(true);
158 mTitleBar.setSkipTitleBarAnimations(true);
John Reck5d43ce82011-06-21 17:16:51 -0700159 super.setActiveTab(tab);
Michael Kolbfdb70242011-03-24 09:41:11 -0700160 BrowserWebView view = (BrowserWebView) tab.getWebView();
Michael Kolb376b5412010-12-15 11:52:57 -0800161 // TabControl.setCurrentTab has been called before this,
162 // so the tab is guaranteed to have a webview
163 if (view == null) {
164 Log.e(LOGTAG, "active tab with no webview detected");
165 return;
166 }
Michael Kolbfdb70242011-03-24 09:41:11 -0700167 // Request focus on the top window.
168 if (mUseQuickControls) {
169 mPieControl.forceToTop(mContentView);
Michael Kolbfdb70242011-03-24 09:41:11 -0700170 } else {
171 // check if title bar is already attached by animation
172 if (mTitleBar.getParent() == null) {
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +0000173 WebViewClassic.fromWebView(view).setEmbeddedTitleBar(mTitleBar);
Michael Kolbfdb70242011-03-24 09:41:11 -0700174 }
175 }
Michael Kolb376b5412010-12-15 11:52:57 -0800176 if (tab.isInVoiceSearchMode()) {
Michael Kolbfdb70242011-03-24 09:41:11 -0700177 showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults());
Michael Kolb376b5412010-12-15 11:52:57 -0800178 } else {
179 revertVoiceTitleBar(tab);
180 }
Michael Kolb629b22c2011-07-13 16:26:47 -0700181 // update nav bar state
182 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
Michael Kolbfdb70242011-03-24 09:41:11 -0700183 updateLockIconToLatest(tab);
Michael Kolb376b5412010-12-15 11:52:57 -0800184 tab.getTopWindow().requestFocus();
John Reck8ee633f2011-08-09 16:00:35 -0700185 mTitleBar.setSkipTitleBarAnimations(false);
Michael Kolb376b5412010-12-15 11:52:57 -0800186 }
187
Michael Kolb66706532010-12-12 19:50:22 -0800188 // menu handling callbacks
189
190 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700191 public boolean onPrepareOptionsMenu(Menu menu) {
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700192 updateMenuState(mActiveTab, menu);
Michael Kolb3ca12752011-07-20 13:52:25 -0700193 return true;
194 }
195
196 @Override
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700197 public void updateMenuState(Tab tab, Menu menu) {
Michael Kolb0d0245f2011-12-05 16:36:05 -0800198 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
199 if (bm != null) {
200 bm.setVisible(!showingNavScreen());
201 }
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700202 MenuItem abm = menu.findItem(R.id.add_bookmark_menu_id);
203 if (abm != null) {
John Reckcc0059c2011-10-07 13:53:13 -0700204 abm.setVisible((tab != null) && !tab.isSnapshot() && !showingNavScreen());
John Recke1a03a32011-09-14 17:04:16 -0700205 }
Michael Kolb315d5022011-10-13 12:47:11 -0700206 MenuItem info = menu.findItem(R.id.page_info_menu_id);
207 if (info != null) {
208 info.setVisible(false);
209 }
210 MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
211 if (newtab != null && !mUseQuickControls) {
212 newtab.setVisible(false);
213 }
214 MenuItem incognito = menu.findItem(R.id.incognito_menu_id);
215 if (incognito != null) {
216 incognito.setVisible(showingNavScreen() || mUseQuickControls);
217 }
John Reckcc0059c2011-10-07 13:53:13 -0700218 if (showingNavScreen()) {
John Recke1a03a32011-09-14 17:04:16 -0700219 menu.setGroupVisible(R.id.LIVE_MENU, false);
220 menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
John Recke1a03a32011-09-14 17:04:16 -0700221 menu.setGroupVisible(R.id.NAV_MENU, false);
Michael Kolb315d5022011-10-13 12:47:11 -0700222 menu.setGroupVisible(R.id.COMBO_MENU, true);
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700223 }
224 }
225
226 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700227 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb315d5022011-10-13 12:47:11 -0700228 if (showingNavScreen()
229 && (item.getItemId() != R.id.history_menu_id)
230 && (item.getItemId() != R.id.snapshots_menu_id)) {
Michael Kolba3194d02011-09-07 11:23:51 -0700231 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb3ca12752011-07-20 13:52:25 -0700232 }
233 return false;
234 }
235
236 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800237 public void onContextMenuCreated(Menu menu) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800238 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800239 }
240
241 @Override
242 public void onContextMenuClosed(Menu menu, boolean inLoad) {
243 if (inLoad) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800244 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800245 }
246 }
247
248 // action mode callbacks
249
250 @Override
251 public void onActionModeStarted(ActionMode mode) {
Michael Kolb42c0c062011-08-02 12:56:06 -0700252 if (!isEditingUrl()) {
253 hideTitleBar();
John Reckaae029c2011-09-16 14:36:39 -0700254 } else {
255 mTitleBar.animate().translationY(mActionBarHeight);
Michael Kolb42c0c062011-08-02 12:56:06 -0700256 }
Michael Kolb66706532010-12-12 19:50:22 -0800257 }
258
Michael Kolba4183062011-01-16 10:43:21 -0800259 @Override
John Reck6cda7b12011-03-18 15:57:13 -0700260 public void onActionModeFinished(boolean inLoad) {
John Reckaae029c2011-09-16 14:36:39 -0700261 mTitleBar.animate().translationY(0);
Michael Kolbc16c5952011-03-29 15:37:03 -0700262 if (inLoad) {
263 if (mUseQuickControls) {
264 mTitleBar.setShowProgressOnly(true);
John Reck6cda7b12011-03-18 15:57:13 -0700265 }
Michael Kolbc16c5952011-03-29 15:37:03 -0700266 showTitleBar();
267 }
John Reck6cda7b12011-03-18 15:57:13 -0700268 }
269
270 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700271 protected void setTitleGravity(int gravity) {
272 if (mUseQuickControls) {
273 FrameLayout.LayoutParams lp =
John Reck0f602f32011-07-07 15:38:43 -0700274 (FrameLayout.LayoutParams) mTitleBar.getLayoutParams();
Michael Kolbfdb70242011-03-24 09:41:11 -0700275 lp.gravity = gravity;
John Reck0f602f32011-07-07 15:38:43 -0700276 mTitleBar.setLayoutParams(lp);
Michael Kolbfdb70242011-03-24 09:41:11 -0700277 } else {
278 super.setTitleGravity(gravity);
279 }
280 }
281
Michael Kolb0241e752011-07-07 14:58:50 -0700282 @Override
283 public void setUseQuickControls(boolean useQuickControls) {
Michael Kolbfdb70242011-03-24 09:41:11 -0700284 mUseQuickControls = useQuickControls;
John Reck0f602f32011-07-07 15:38:43 -0700285 mTitleBar.setUseQuickControls(mUseQuickControls);
Michael Kolbfdb70242011-03-24 09:41:11 -0700286 if (useQuickControls) {
Michael Kolb0241e752011-07-07 14:58:50 -0700287 mPieControl = new PieControlPhone(mActivity, mUiController, this);
Michael Kolbfdb70242011-03-24 09:41:11 -0700288 mPieControl.attachToContainer(mContentView);
Michael Kolb46f987e2011-04-05 10:39:10 -0700289 WebView web = getWebView();
290 if (web != null) {
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +0000291 WebViewClassic.fromWebView(web).setEmbeddedTitleBar(null);
Michael Kolbfdb70242011-03-24 09:41:11 -0700292 }
293 } else {
Michael Kolbfdb70242011-03-24 09:41:11 -0700294 if (mPieControl != null) {
295 mPieControl.removeFromContainer(mContentView);
296 }
Michael Kolb46f987e2011-04-05 10:39:10 -0700297 WebView web = getWebView();
Michael Kolbfdb70242011-03-24 09:41:11 -0700298 if (web != null) {
Michael Kolb199e43c2011-08-17 10:45:45 -0700299 // make sure we can re-parent titlebar
300 if ((mTitleBar != null) && (mTitleBar.getParent() != null)) {
301 ((ViewGroup) mTitleBar.getParent()).removeView(mTitleBar);
302 }
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +0000303 WebViewClassic.fromWebView(web).setEmbeddedTitleBar(mTitleBar);
Michael Kolbfdb70242011-03-24 09:41:11 -0700304 }
305 setTitleGravity(Gravity.NO_GRAVITY);
306 }
John Reck718a24d2011-08-12 11:08:30 -0700307 updateUrlBarAutoShowManagerTarget();
Michael Kolbfdb70242011-03-24 09:41:11 -0700308 }
309
Michael Kolbc3af0672011-08-09 10:24:41 -0700310 @Override
311 public boolean isWebShowing() {
John Reckcc0059c2011-10-07 13:53:13 -0700312 return super.isWebShowing() && !showingNavScreen();
Michael Kolbc3af0672011-08-09 10:24:41 -0700313 }
314
315 @Override
316 public void showWeb(boolean animate) {
317 super.showWeb(animate);
Michael Kolba3194d02011-09-07 11:23:51 -0700318 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
Michael Kolbc3af0672011-08-09 10:24:41 -0700319 }
320
Michael Kolbf2055602011-04-09 17:20:03 -0700321 void showNavScreen() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700322 mUiController.setBlockEvents(true);
John Reckcc0059c2011-10-07 13:53:13 -0700323 if (mNavScreen == null) {
324 mNavScreen = new NavScreen(mActivity, mUiController, this);
325 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
326 } else {
327 mNavScreen.setVisibility(View.VISIBLE);
328 mNavScreen.setAlpha(1f);
John Reck9c5004e2011-10-07 16:00:12 -0700329 mNavScreen.refreshAdapter();
John Reckcc0059c2011-10-07 13:53:13 -0700330 }
Michael Kolbc3af0672011-08-09 10:24:41 -0700331 mActiveTab.capture();
John Reckcc0059c2011-10-07 13:53:13 -0700332 if (mAnimScreen == null) {
333 mAnimScreen = new AnimScreen(mActivity);
John Reckce8bcb02011-10-11 13:45:29 -0700334 } else {
335 mAnimScreen.mMain.setAlpha(1f);
336 mAnimScreen.mTitle.setAlpha(1f);
337 mAnimScreen.setScaleFactor(1f);
John Reckcc0059c2011-10-07 13:53:13 -0700338 }
339 mAnimScreen.set(getTitleBar(), getWebView());
Michael Kolba30e4fb2011-11-07 17:32:01 -0800340 if (mAnimScreen.mMain.getParent() == null) {
341 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
342 }
Michael Kolbf2055602011-04-09 17:20:03 -0700343 mCustomViewContainer.setVisibility(View.VISIBLE);
344 mCustomViewContainer.bringToFront();
John Reckce8bcb02011-10-11 13:45:29 -0700345 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
346 mContentView.getHeight());
Michael Kolbc3af0672011-08-09 10:24:41 -0700347 int fromLeft = 0;
348 int fromTop = getTitleBar().getHeight();
349 int fromRight = mContentView.getWidth();
350 int fromBottom = mContentView.getHeight();
Michael Kolba3194d02011-09-07 11:23:51 -0700351 int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
352 int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
Michael Kolb7a321d62011-09-23 15:54:22 -0700353 int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
Michael Kolbc3af0672011-08-09 10:24:41 -0700354 int toLeft = (mContentView.getWidth() - width) / 2;
Michael Kolb7a321d62011-09-23 15:54:22 -0700355 int toTop = ((fromBottom - (ntth + height)) / 2 + ntth);
Michael Kolbc3af0672011-08-09 10:24:41 -0700356 int toRight = toLeft + width;
357 int toBottom = toTop + height;
358 float scaleFactor = width / (float) mContentView.getWidth();
359 detachTab(mActiveTab);
360 mContentView.setVisibility(View.GONE);
Michael Kolba3194d02011-09-07 11:23:51 -0700361 AnimatorSet set1 = new AnimatorSet();
Michael Kolbc3af0672011-08-09 10:24:41 -0700362 AnimatorSet inanim = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700363 ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
Michael Kolbc3af0672011-08-09 10:24:41 -0700364 fromLeft, toLeft);
John Reckcc0059c2011-10-07 13:53:13 -0700365 ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
Michael Kolbc3af0672011-08-09 10:24:41 -0700366 fromTop, toTop);
John Reckcc0059c2011-10-07 13:53:13 -0700367 ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
Michael Kolbc3af0672011-08-09 10:24:41 -0700368 fromRight, toRight);
John Reckcc0059c2011-10-07 13:53:13 -0700369 ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
Michael Kolbc3af0672011-08-09 10:24:41 -0700370 fromBottom, toBottom);
John Reckcc0059c2011-10-07 13:53:13 -0700371 ObjectAnimator title = ObjectAnimator.ofFloat(mAnimScreen.mTitle, "alpha",
Michael Kolbc3af0672011-08-09 10:24:41 -0700372 1f, 0f);
John Reckcc0059c2011-10-07 13:53:13 -0700373 ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
Michael Kolbc3af0672011-08-09 10:24:41 -0700374 1f, scaleFactor);
John Reck1adf0302011-10-11 10:58:12 -0700375 ObjectAnimator blend1 = ObjectAnimator.ofFloat(mAnimScreen.mMain,
376 "alpha", 1f, 0f);
Michael Kolba3194d02011-09-07 11:23:51 -0700377 blend1.setDuration(100);
378
379 inanim.playTogether(tx, ty, tr, tb, sx, title);
380 inanim.setDuration(200);
381 set1.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700382 @Override
383 public void onAnimationEnd(Animator anim) {
John Reck1adf0302011-10-11 10:58:12 -0700384 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbc3af0672011-08-09 10:24:41 -0700385 finishAnimationIn();
386 mUiController.setBlockEvents(false);
387 }
388 });
Michael Kolba3194d02011-09-07 11:23:51 -0700389 set1.playSequentially(inanim, blend1);
390 set1.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700391 }
392
393 private void finishAnimationIn() {
John Reckcc0059c2011-10-07 13:53:13 -0700394 if (showingNavScreen()) {
Michael Kolbb43f2f62011-08-17 10:39:31 -0700395 // notify accessibility manager about the screen change
396 mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
397 mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
398 }
Michael Kolbf2055602011-04-09 17:20:03 -0700399 }
400
Michael Kolba3194d02011-09-07 11:23:51 -0700401 void hideNavScreen(int position, boolean animate) {
John Reckcc0059c2011-10-07 13:53:13 -0700402 if (!showingNavScreen()) return;
Michael Kolba3194d02011-09-07 11:23:51 -0700403 final Tab tab = mUiController.getTabControl().getTab(position);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700404 if ((tab == null) || !animate) {
Michael Kolb365561d2011-08-18 09:56:25 -0700405 if (tab != null) {
406 setActiveTab(tab);
407 } else if (mTabControl.getTabCount() > 0) {
408 // use a fallback tab
409 setActiveTab(mTabControl.getCurrentTab());
410 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700411 mContentView.setVisibility(View.VISIBLE);
412 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700413 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700414 }
Michael Kolba3194d02011-09-07 11:23:51 -0700415 NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
Michael Kolbc3af0672011-08-09 10:24:41 -0700416 if (tabview == null) {
Michael Kolb365561d2011-08-18 09:56:25 -0700417 if (mTabControl.getTabCount() > 0) {
418 // use a fallback tab
419 setActiveTab(mTabControl.getCurrentTab());
420 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700421 mContentView.setVisibility(View.VISIBLE);
422 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700423 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700424 }
425 mUiController.setBlockEvents(true);
426 mUiController.setActiveTab(tab);
427 mContentView.setVisibility(View.VISIBLE);
John Reckcc0059c2011-10-07 13:53:13 -0700428 if (mAnimScreen == null) {
429 mAnimScreen = new AnimScreen(mActivity);
430 }
431 mAnimScreen.set(tab.getScreenshot());
Michael Kolb0755fcd2012-01-10 10:19:50 -0800432 if (mAnimScreen.mMain.getParent() == null) {
433 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
434 }
John Reckcc0059c2011-10-07 13:53:13 -0700435 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
Michael Kolba3194d02011-09-07 11:23:51 -0700436 mContentView.getHeight());
437 mNavScreen.mScroller.finishScroller();
438 ImageView target = tabview.mImage;
Michael Kolbc3af0672011-08-09 10:24:41 -0700439 int toLeft = 0;
Michael Kolbb7e16702011-12-15 11:59:40 -0800440 int toTop = (tab.getWebView() != null) ? tab.getWebView().getVisibleTitleHeight() : 0;
Michael Kolbc3af0672011-08-09 10:24:41 -0700441 int toRight = mContentView.getWidth();
Michael Kolba3194d02011-09-07 11:23:51 -0700442 int width = target.getDrawable().getIntrinsicWidth();
443 int height = target.getDrawable().getIntrinsicHeight();
444 int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.mScroller.getScrollX();
445 int fromTop = tabview.getTop() + target.getTop() - mNavScreen.mScroller.getScrollY();
Michael Kolbc3af0672011-08-09 10:24:41 -0700446 int fromRight = fromLeft + width;
447 int fromBottom = fromTop + height;
448 float scaleFactor = mContentView.getWidth() / (float) width;
Michael Kolba3194d02011-09-07 11:23:51 -0700449 int toBottom = toTop + (int) (height * scaleFactor);
John Reck9c5004e2011-10-07 16:00:12 -0700450 mAnimScreen.mContent.setLeft(fromLeft);
451 mAnimScreen.mContent.setTop(fromTop);
452 mAnimScreen.mContent.setRight(fromRight);
453 mAnimScreen.mContent.setBottom(fromBottom);
454 mAnimScreen.setScaleFactor(1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700455 AnimatorSet set1 = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700456 ObjectAnimator fade2 = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700457 ObjectAnimator fade1 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
John Reck9c5004e2011-10-07 16:00:12 -0700458 set1.playTogether(fade1, fade2);
Michael Kolba3194d02011-09-07 11:23:51 -0700459 set1.setDuration(100);
460 AnimatorSet set2 = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700461 ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
Michael Kolbc3af0672011-08-09 10:24:41 -0700462 fromLeft, toLeft);
John Reckcc0059c2011-10-07 13:53:13 -0700463 ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
Michael Kolbc3af0672011-08-09 10:24:41 -0700464 fromTop, toTop);
John Reckcc0059c2011-10-07 13:53:13 -0700465 ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
Michael Kolbc3af0672011-08-09 10:24:41 -0700466 fromRight, toRight);
John Reckcc0059c2011-10-07 13:53:13 -0700467 ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
Michael Kolbc3af0672011-08-09 10:24:41 -0700468 fromBottom, toBottom);
John Reckcc0059c2011-10-07 13:53:13 -0700469 ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
Michael Kolbc3af0672011-08-09 10:24:41 -0700470 1f, scaleFactor);
Michael Kolbc3af0672011-08-09 10:24:41 -0700471 ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
Michael Kolba3194d02011-09-07 11:23:51 -0700472 otheralpha.setDuration(100);
473 set2.playTogether(l, t, r, b, scale);
474 set2.setDuration(200);
475 AnimatorSet combo = new AnimatorSet();
476 combo.playSequentially(set1, set2, otheralpha);
477 combo.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700478 @Override
479 public void onAnimationEnd(Animator anim) {
John Reckcc0059c2011-10-07 13:53:13 -0700480 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700481 finishAnimateOut();
Michael Kolbc3af0672011-08-09 10:24:41 -0700482 mUiController.setBlockEvents(false);
483 }
484 });
Michael Kolba3194d02011-09-07 11:23:51 -0700485 combo.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700486 }
487
Michael Kolbbf32cd02011-08-16 15:07:04 -0700488 private void finishAnimateOut() {
John Reck8ee633f2011-08-09 16:00:35 -0700489 mTabControl.setOnThumbnailUpdatedListener(null);
John Reckcc0059c2011-10-07 13:53:13 -0700490 mNavScreen.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700491 mCustomViewContainer.setAlpha(1f);
Michael Kolbf2055602011-04-09 17:20:03 -0700492 mCustomViewContainer.setVisibility(View.GONE);
Michael Kolbf2055602011-04-09 17:20:03 -0700493 }
494
John Reck6b4bd5f2011-07-12 10:14:38 -0700495 @Override
496 public boolean needsRestoreAllTabs() {
497 return false;
498 }
499
Michael Kolb20be26d2011-07-18 16:38:02 -0700500 public void toggleNavScreen() {
John Reckcc0059c2011-10-07 13:53:13 -0700501 if (!showingNavScreen()) {
Michael Kolb20be26d2011-07-18 16:38:02 -0700502 showNavScreen();
503 } else {
Michael Kolba3194d02011-09-07 11:23:51 -0700504 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb20be26d2011-07-18 16:38:02 -0700505 }
506 }
507
John Reck1cf4b792011-07-26 10:22:22 -0700508 @Override
509 public boolean shouldCaptureThumbnails() {
510 return true;
511 }
512
Michael Kolbc3af0672011-08-09 10:24:41 -0700513 static class AnimScreen {
John Reck3ba45532011-08-11 16:26:53 -0700514
Michael Kolbc3af0672011-08-09 10:24:41 -0700515 private View mMain;
516 private ImageView mTitle;
517 private ImageView mContent;
518 private float mScale;
John Reckcc0059c2011-10-07 13:53:13 -0700519 private Bitmap mTitleBarBitmap;
520 private Bitmap mContentBitmap;
Michael Kolbc3af0672011-08-09 10:24:41 -0700521
John Reckcc0059c2011-10-07 13:53:13 -0700522 public AnimScreen(Context ctx) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700523 mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
524 null);
Michael Kolbc3af0672011-08-09 10:24:41 -0700525 mTitle = (ImageView) mMain.findViewById(R.id.title);
John Reckcc0059c2011-10-07 13:53:13 -0700526 mContent = (ImageView) mMain.findViewById(R.id.content);
527 mContent.setScaleType(ImageView.ScaleType.MATRIX);
528 mContent.setImageMatrix(new Matrix());
529 mScale = 1.0f;
530 setScaleFactor(getScaleFactor());
531 }
532
533 public void set(TitleBar tbar, WebView web) {
John Reck62077d82011-10-13 15:17:50 -0700534 if (tbar == null || web == null) {
535 return;
536 }
John Reck1adf0302011-10-11 10:58:12 -0700537 if (tbar.getWidth() > 0 && tbar.getEmbeddedHeight() > 0) {
538 if (mTitleBarBitmap == null
539 || mTitleBarBitmap.getWidth() != tbar.getWidth()
540 || mTitleBarBitmap.getHeight() != tbar.getEmbeddedHeight()) {
John Recka98c83b2011-10-31 12:31:58 -0700541 mTitleBarBitmap = safeCreateBitmap(tbar.getWidth(),
542 tbar.getEmbeddedHeight());
John Reck1adf0302011-10-11 10:58:12 -0700543 }
John Recka98c83b2011-10-31 12:31:58 -0700544 if (mTitleBarBitmap != null) {
545 Canvas c = new Canvas(mTitleBarBitmap);
546 tbar.draw(c);
547 c.setBitmap(null);
548 }
John Reck1adf0302011-10-11 10:58:12 -0700549 } else {
550 mTitleBarBitmap = null;
John Reckcc0059c2011-10-07 13:53:13 -0700551 }
John Reckcc0059c2011-10-07 13:53:13 -0700552 mTitle.setImageBitmap(mTitleBarBitmap);
553 mTitle.setVisibility(View.VISIBLE);
John Reck9c5004e2011-10-07 16:00:12 -0700554 int h = web.getHeight() - tbar.getEmbeddedHeight();
John Reckcc0059c2011-10-07 13:53:13 -0700555 if (mContentBitmap == null
556 || mContentBitmap.getWidth() != web.getWidth()
557 || mContentBitmap.getHeight() != h) {
John Recka98c83b2011-10-31 12:31:58 -0700558 mContentBitmap = safeCreateBitmap(web.getWidth(), h);
John Reckcc0059c2011-10-07 13:53:13 -0700559 }
John Recka98c83b2011-10-31 12:31:58 -0700560 if (mContentBitmap != null) {
561 Canvas c = new Canvas(mContentBitmap);
562 int tx = web.getScrollX();
563 int ty = web.getScrollY();
564 c.translate(-tx, -ty - tbar.getEmbeddedHeight());
565 web.draw(c);
566 c.setBitmap(null);
567 }
John Reckcc0059c2011-10-07 13:53:13 -0700568 mContent.setImageBitmap(mContentBitmap);
Michael Kolbc3af0672011-08-09 10:24:41 -0700569 }
570
John Recka98c83b2011-10-31 12:31:58 -0700571 private Bitmap safeCreateBitmap(int width, int height) {
572 if (width <= 0 || height <= 0) {
573 Log.w(LOGTAG, "safeCreateBitmap failed! width: " + width
574 + ", height: " + height);
575 return null;
576 }
577 return Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
578 }
579
John Reckcc0059c2011-10-07 13:53:13 -0700580 public void set(Bitmap image) {
Michael Kolba3194d02011-09-07 11:23:51 -0700581 mTitle.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700582 mContent.setImageBitmap(image);
Michael Kolbc3af0672011-08-09 10:24:41 -0700583 }
584
John Reckcc0059c2011-10-07 13:53:13 -0700585 private void setScaleFactor(float sf) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700586 mScale = sf;
587 Matrix m = new Matrix();
588 m.postScale(sf,sf);
589 mContent.setImageMatrix(m);
590 }
591
John Reckcc0059c2011-10-07 13:53:13 -0700592 private float getScaleFactor() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700593 return mScale;
594 }
595
John Reck3ba45532011-08-11 16:26:53 -0700596 }
597
Michael Kolb66706532010-12-12 19:50:22 -0800598}