summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/browser/BaseUi.java2
-rw-r--r--src/com/android/browser/Controller.java3
-rw-r--r--src/com/android/browser/NavScreen.java382
-rw-r--r--src/com/android/browser/PhoneUi.java215
-rw-r--r--src/com/android/browser/TitleBarPhone.java2
-rw-r--r--src/com/android/browser/UiController.java2
6 files changed, 520 insertions, 86 deletions
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index b7964dc..43bc7d6 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -76,7 +76,7 @@ public abstract class BaseUi implements UI, WebViewFactory {
private FrameLayout mBrowserFrameLayout;
protected FrameLayout mContentView;
- private FrameLayout mCustomViewContainer;
+ protected FrameLayout mCustomViewContainer;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 2f47cad..f920702 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -2128,7 +2128,8 @@ public class Controller
mTabControl.removeTab(tab);
}
- protected void setActiveTab(Tab tab) {
+ @Override
+ public void setActiveTab(Tab tab) {
// monkey protection against delayed start
if (tab != null) {
mTabControl.setCurrentTab(tab);
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
new file mode 100644
index 0000000..8b897df
--- /dev/null
+++ b/src/com/android/browser/NavScreen.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.Gallery;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+import android.widget.LinearLayout;
+import android.widget.ListPopupWindow;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NavScreen extends LinearLayout implements OnClickListener {
+
+ UiController mUiController;
+ PhoneUi mUi;
+ Tab mTab;
+ Activity mActivity;
+
+ View mTopPanel;
+ ImageButton mBack;
+ ImageButton mRefresh;
+ ImageButton mForward;
+ ImageButton mTabs;
+ ImageButton mBookmarks;
+ ImageButton mMore;
+ ImageButton mNewTab;
+ ImageButton mNewIncognito;
+ FrameLayout mHolder;
+
+ Gallery mFlipper;
+ int mTabWidth;
+ int mTabHeight;
+ TabAdapter mAdapter;
+ ListPopupWindow mPopup;
+
+ boolean mReady;
+
+ public NavScreen(Activity activity, UiController ctl, PhoneUi ui) {
+ super(activity);
+ mActivity = activity;
+ mUiController = ctl;
+ mUi = ui;
+ init();
+ }
+
+ protected Tab getSelectedTab() {
+ return (Tab) mFlipper.getSelectedItem();
+ }
+
+ protected void setTabDimensions(int w, int h) {
+ mTabWidth = w;
+ mTabHeight = h;
+ requestLayout();
+ }
+
+ protected void showMenu(Menu menu) {
+ MenuAdapter menuAdapter = new MenuAdapter(mContext);
+ menuAdapter.setMenu(menu);
+ ListPopupWindow popup = new ListPopupWindow(mContext);
+ popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
+ popup.setAdapter(menuAdapter);
+ popup.setModal(true);
+ popup.setAnchorView(mMore);
+ popup.setWidth((int) mContext.getResources().getDimension(
+ R.dimen.menu_width));
+ popup.show();
+ mPopup = popup;
+ }
+
+ protected void dismissMenu() {
+ if (mPopup != null) {
+ mPopup.dismiss();
+ }
+ }
+
+ private void init() {
+ LayoutInflater.from(mContext).inflate(R.layout.nav_screen, this);
+ LinearLayout content = (LinearLayout) findViewById(R.id.nav_screen);
+ mTopPanel = findViewById(R.id.navtop);
+ mBack = (ImageButton) findViewById(R.id.back);
+ mForward = (ImageButton) findViewById(R.id.forward);
+ mRefresh = (ImageButton) findViewById(R.id.refresh);
+ mTabs = (ImageButton) findViewById(R.id.tabs);
+ mBookmarks = (ImageButton) findViewById(R.id.bookmarks);
+ mNewTab = (ImageButton) findViewById(R.id.newtab);
+ mNewIncognito = (ImageButton) findViewById(R.id.newincognito);
+ mMore = (ImageButton) findViewById(R.id.more);
+ mBack.setOnClickListener(this);
+ mForward.setOnClickListener(this);
+ mRefresh.setOnClickListener(this);
+ mTabs.setOnClickListener(this);
+ mBookmarks.setOnClickListener(this);
+ mNewTab.setOnClickListener(this);
+ mNewIncognito.setOnClickListener(this);
+ mMore.setOnClickListener(this);
+ mHolder = (FrameLayout) findViewById(R.id.galleryholder);
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ mFlipper = new TabGallery(mContext);
+ mFlipper.setSpacing((int)(mContext.getResources()
+ .getDimension(R.dimen.nav_tab_spacing)));
+ mFlipper.setLayoutParams(lp);
+ mHolder.addView(mFlipper, 0);
+ mAdapter = new TabAdapter(mContext, mUiController.getTabControl());
+ mFlipper.setAdapter(mAdapter);
+ setTab(mUi.getActiveTab(), true);
+ mFlipper.setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ // post as runnable to prevent bug in gesturedetector
+ // when view is removed in click handler
+ // sends action_cancel before action_up
+ mFlipper.post(new Runnable() {
+ public void run() {
+ close();
+ }
+ });
+ }
+ });
+ mFlipper.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view,
+ int position, long id) {
+ final Tab tab = mAdapter.getItem(position);
+ setTab(tab, false);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+ }
+
+ private void setTab(Tab tab, boolean updateFlipper) {
+ mTab = tab;
+ // refresh state from tab
+ WebView web = tab.getWebView();
+ if (web != null) {
+ mBack.setImageResource(web.canGoBack()
+ ? R.drawable.ic_back_holo_dark
+ : R.drawable.ic_back_disabled_holo_dark);
+ mForward.setImageResource(web.canGoForward()
+ ? R.drawable.ic_forward_holo_dark
+ : R.drawable.ic_forward_disabled_holo_dark);
+ }
+ if (updateFlipper) {
+ mFlipper.setSelection(mUiController.getTabControl().getTabIndex(tab));
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ WebView web = (mTab != null) ? mTab.getWebView() : null;
+ if (web != null) {
+ if (mBack == v) {
+ mUi.hideNavScreen(true);
+ web.goBack();
+ } else if (mForward == v) {
+ mUi.hideNavScreen(true);
+ web.goForward();
+ } else if (mRefresh == v) {
+ mUi.hideNavScreen(true);
+ web.reload();
+ }
+ }
+ if (mBookmarks == v) {
+ mUi.hideNavScreen(false);
+ mUiController.bookmarksOrHistoryPicker(false);
+ } else if (mTabs == v) {
+ mUi.hideNavScreen(false);
+ mUi.showActiveTabsPage();
+ } else if (mNewTab == v) {
+ mUi.hideNavScreen(true);
+ mUiController.openTabToHomePage();
+ } else if (mMore == v) {
+ mActivity.openOptionsMenu();
+ } else if (mNewIncognito == v) {
+ mUi.hideNavScreen(true);
+ mUiController.openIncognitoTab();
+ }
+ }
+
+ protected void close() {
+ close(true);
+ }
+
+ protected void close(boolean animate) {
+ mUi.hideNavScreen(animate);
+ Tab tab = (Tab) mFlipper.getSelectedItem();
+ if (tab != mUi.getActiveTab()) {
+ mUiController.setActiveTab(tab);
+ }
+ }
+
+ class TabGallery extends Gallery {
+
+ public TabGallery(Context ctx) {
+ super(ctx);
+ setUnselectedAlpha(0.3f);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new Gallery.LayoutParams(
+ LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
+ return generateDefaultLayoutParams();
+ }
+
+ }
+
+ class TabAdapter extends BaseAdapter {
+
+ Context context;
+ TabControl tabControl;
+
+ public TabAdapter(Context ctx, TabControl tc) {
+ context = ctx;
+ tabControl = tc;
+ }
+
+ void onCloseTab(Tab tab) {
+ if (tab != null) {
+ mUiController.closeTab(tab);
+ if (tabControl.getTabCount() == 0) {
+ mUiController.openTabToHomePage();
+ mUi.hideNavScreen(false);
+ } else {
+ notifyDataSetChanged();
+ }
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return tabControl.getTabCount();
+ }
+
+ @Override
+ public Tab getItem(int position) {
+ return tabControl.getTab(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ImageView content = null;
+ if (convertView == null) {
+ convertView = LayoutInflater.from(context).inflate(R.layout.nav_tab_view,
+ null);
+ content = (ImageView) convertView.findViewById(R.id.content);
+ content.setLayoutParams(new LayoutParams(mTabWidth, mTabHeight));
+ } else {
+ content = (ImageView) convertView.findViewById(R.id.content);
+ }
+ TextView title = (TextView) convertView.findViewById(R.id.title);
+ ImageView icon = (ImageView) convertView.findViewById(R.id.favicon);
+ ImageButton close = (ImageButton) convertView.findViewById(R.id.closetab);
+ final Tab tab = getItem(position);
+ if (tab.getFavicon() != null) {
+ icon.setImageBitmap(tab.getFavicon());
+ }
+ title.setText(tab.getUrl());
+ Bitmap screen = tab.getScreenshot();
+ content.setImageBitmap(screen);
+ close.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onCloseTab(tab);
+ }
+ });
+ title.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ close(false);
+ mUi.editUrl(false);
+ }
+ });
+ return convertView;
+ }
+ }
+
+ private class MenuAdapter extends BaseAdapter implements OnClickListener {
+
+ List<MenuItem> mItems;
+ LayoutInflater mInflater;
+
+ public MenuAdapter(Context ctx) {
+ mInflater = LayoutInflater.from(ctx);
+ mItems = new ArrayList<MenuItem>();
+ }
+
+ public void setMenu(Menu menu) {
+ mItems.clear();
+ for (int i = 0; i < menu.size(); i++) {
+ MenuItem item = menu.getItem(i);
+ if (item.isEnabled() && item.isVisible()) {
+ mItems.add(item);
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public MenuItem getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getTag() != null) {
+ dismissMenu();
+ mActivity.closeOptionsMenu();
+ mUi.hideNavScreen(false);
+ mUiController.onOptionsItemSelected((MenuItem) v.getTag());
+ }
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final MenuItem item = mItems.get(position);
+ View view = mInflater.inflate(R.layout.qc_menu_item, null);
+ TextView label = (TextView) view.findViewById(R.id.title);
+ label.setText(item.getTitle());
+ label.setTag(item);
+ label.setOnClickListener(this);
+ return label;
+ }
+
+ }
+
+}
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 471a9e6..3415e39 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -16,17 +16,17 @@
package com.android.browser;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.app.Activity;
-import android.content.Context;
-import android.graphics.PixelFormat;
import android.util.Log;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.FrameLayout;
@@ -36,12 +36,13 @@ import android.widget.FrameLayout;
public class PhoneUi extends BaseUi {
private static final String LOGTAG = "PhoneUi";
+ private static final float NAV_TAB_SCALE = 0.75f;
private TitleBarPhone mTitleBar;
private ActiveTabsPage mActiveTabsPage;
- private TouchProxy mTitleOverlay;
private boolean mUseQuickControls;
private PieControl mPieControl;
+ private NavScreen mNavScreen;
boolean mExtendedMenuOpen;
boolean mOptionsMenuOpen;
@@ -100,11 +101,31 @@ public class PhoneUi extends BaseUi {
// if tab page is showing, hide it
mUiController.removeActiveTabsPage(true);
return true;
+ } else if (mNavScreen != null) {
+ mNavScreen.close();
+ return true;
}
return super.onBackKey();
}
@Override
+ public boolean dispatchKey(int code, KeyEvent event) {
+ if (!isComboViewShowing()) {
+ switch (code) {
+ case KeyEvent.KEYCODE_MENU:
+ if (mNavScreen == null) {
+ showNavScreen();
+ return true;
+ } else {
+ mNavScreen.close();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
public void onProgressChanged(Tab tab) {
if (tab.inForeground()) {
int progress = tab.getLoadProgress();
@@ -198,46 +219,6 @@ public class PhoneUi extends BaseUi {
// menu handling callbacks
@Override
- public void onOptionsMenuOpened() {
- if (!mUseQuickControls) {
- mOptionsMenuOpen = true;
- // options menu opened, show title bar
- showTitleBar();
- if (mTitleOverlay == null) {
- // This assumes that getTitleBar always returns the same View
- mTitleOverlay = new TouchProxy(mActivity, getTitleBar());
- }
- mActivity.getWindowManager().addView(mTitleOverlay,
- mTitleOverlay.getWindowLayoutParams());
- }
- }
-
- @Override
- public void onExtendedMenuOpened() {
- // Switching the menu to expanded view, so hide the
- // title bar.
- mExtendedMenuOpen = true;
- hideTitleBar();
- }
-
- @Override
- public void onOptionsMenuClosed(boolean inLoad) {
- mOptionsMenuOpen = false;
- mActivity.getWindowManager().removeView(mTitleOverlay);
- if (!inLoad && !getTitleBar().hasFocus()) {
- hideTitleBar();
- }
- }
-
- @Override
- public void onExtendedMenuClosed(boolean inLoad) {
- mExtendedMenuOpen = false;
- if (!mUseQuickControls) {
- showTitleBar();
- }
- }
-
- @Override
public void onContextMenuCreated(Menu menu) {
hideTitleBar();
}
@@ -268,40 +249,6 @@ public class PhoneUi extends BaseUi {
}
@Override
- public boolean dispatchKey(int code, KeyEvent event) {
- return false;
- }
-
- static class TouchProxy extends View {
-
- View mTarget;
-
- TouchProxy(Context context, View target) {
- super(context);
- mTarget = target;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- return mTarget.dispatchTouchEvent(event);
- }
-
- WindowManager.LayoutParams getWindowLayoutParams() {
- WindowManager.LayoutParams params =
- new WindowManager.LayoutParams(
- mTarget.getWidth(),
- mTarget.getHeight(),
- WindowManager.LayoutParams.TYPE_APPLICATION,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
- PixelFormat.TRANSPARENT);
- params.gravity = Gravity.TOP | Gravity.LEFT;
- params.y = mTarget.getTop();
- params.x = mTarget.getLeft();
- return params;
- }
- }
-
- @Override
protected void setTitleGravity(int gravity) {
if (mUseQuickControls) {
FrameLayout.LayoutParams lp =
@@ -337,12 +284,15 @@ public class PhoneUi extends BaseUi {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
+ menu.setGroupVisible(R.id.NAV_MENU, false);
if (mUseQuickControls) {
- menu.setGroupVisible(R.id.NAV_MENU, false);
mPieControl.onMenuOpened(menu);
return false;
} else {
- return true;
+ if (mNavScreen != null) {
+ mNavScreen.showMenu(menu);
+ }
+ return false;
}
}
@@ -353,9 +303,108 @@ public class PhoneUi extends BaseUi {
} else {
captureTab(tab,
mActivity.getWindowManager().getDefaultDisplay().getWidth(),
- (int) mActivity.getResources()
- .getDimension(R.dimen.tab_view_thumbnail_height));
+ mActivity.getWindowManager().getDefaultDisplay().getHeight());
+ }
+ }
+
+ void showNavScreen() {
+ captureTab(mActiveTab);
+ mNavScreen = new NavScreen(mActivity, mUiController, this);
+ WebView web = getWebView();
+ if (web != null) {
+ int w = web.getWidth();
+ int h = web.getHeight();
+ mNavScreen.setTabDimensions((int) (w * NAV_TAB_SCALE),
+ (int) (h * NAV_TAB_SCALE));
+ }
+ // Add the custom view to its container.
+ mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_GRAVITY_CENTER);
+ ObjectAnimator animx = ObjectAnimator.ofFloat(mContentView,
+ "scaleX", 1.0f, 0.85f);
+ ObjectAnimator animy = ObjectAnimator.ofFloat(mContentView,
+ "scaleY", 1.0f, 0.85f);
+ AnimatorSet anims = new AnimatorSet();
+ anims.setDuration(200);
+ anims.addListener(new AnimatorListener() {
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ finishShowNavScreen();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishShowNavScreen();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+ });
+ anims.playTogether(animx, animy);
+ anims.start();
+ }
+
+ private void finishShowNavScreen() {
+ // Hide the content view.
+ mContentView.setVisibility(View.GONE);
+ mContentView.setScaleX(1.0f);
+ mContentView.setScaleY(1.0f);
+ // Finally show the custom view container.
+ mCustomViewContainer.setVisibility(View.VISIBLE);
+ mCustomViewContainer.bringToFront();
+ }
+
+ void hideNavScreen(boolean animateToPage) {
+ if (mNavScreen == null) return;
+ if (animateToPage) {
+ ObjectAnimator animx = ObjectAnimator.ofFloat(mNavScreen, "scaleX",
+ 1.0f, 1.2f);
+ ObjectAnimator animy = ObjectAnimator.ofFloat(mNavScreen, "scaleY",
+ 1.0f, 1.2f);
+ AnimatorSet anims = new AnimatorSet();
+ anims.setDuration(200);
+ anims.addListener(new AnimatorListener() {
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ finishHideNavScreen();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishHideNavScreen();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+ });
+ anims.playTogether(animx, animy);
+ anims.start();
+ } else {
+ finishHideNavScreen();
}
+
+ }
+
+ private void finishHideNavScreen() {
+ // Hide the custom view.
+ mNavScreen.setVisibility(View.GONE);
+ // Remove the custom view from its container.
+ mCustomViewContainer.removeView(mNavScreen);
+ mNavScreen = null;
+ mCustomViewContainer.setVisibility(View.GONE);
+ // Show the content view.
+ mContentView.setVisibility(View.VISIBLE);
}
}
diff --git a/src/com/android/browser/TitleBarPhone.java b/src/com/android/browser/TitleBarPhone.java
index 875e4b5..0eb2d1a 100644
--- a/src/com/android/browser/TitleBarPhone.java
+++ b/src/com/android/browser/TitleBarPhone.java
@@ -134,7 +134,7 @@ public class TitleBarPhone extends TitleBarBase implements OnFocusChangeListener
}
}
super.onFocusChange(v, hasFocus);
- if (mUseQuickControls && !hasFocus) {
+ if (!hasFocus) {
mBaseUi.hideTitleBar();
}
}
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index ed5fa6a..2b3ee69 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -44,6 +44,8 @@ public interface UiController extends BookmarksHistoryCallbacks {
Tab openIncognitoTab();
+ void setActiveTab(Tab tab);
+
boolean switchToTab(int tabIndex);
void closeCurrentTab();