summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/layout/qc_tab.xml61
-rw-r--r--res/values/dimensions.xml8
-rw-r--r--src/com/android/browser/Controller.java12
-rw-r--r--src/com/android/browser/PieControl.java115
-rw-r--r--src/com/android/browser/Tab.java15
-rw-r--r--src/com/android/browser/XLargeUi.java29
-rw-r--r--src/com/android/browser/view/BasePieView.java13
-rw-r--r--src/com/android/browser/view/PieListView.java1
-rw-r--r--src/com/android/browser/view/PieMenu.java6
-rw-r--r--src/com/android/browser/view/PieStackView.java104
10 files changed, 333 insertions, 31 deletions
diff --git a/res/layout/qc_tab.xml b/res/layout/qc_tab.xml
new file mode 100644
index 0000000..5379680
--- /dev/null
+++ b/res/layout/qc_tab.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@color/black"
+ android:padding="0dip"
+ >
+ <TextView android:id="@+id/title1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="8dip"
+ android:paddingRight="2dip"
+ android:paddingTop="1dip"
+ android:paddingBottom="1dip"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:typeface="sans"
+ android:textSize="12sp"
+ android:textColor="#DDDDDD"
+ />
+ <ImageView
+ android:id="@+id/thumb"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginTop= "1dip"
+ android:layout_marginLeft= "1dip"
+ android:layout_marginRight= "1dip"
+ android:layout_marginBottom= "1dip"
+ android:src="@drawable/browser_thumbnail"
+ android:scaleType="centerCrop"
+ />
+ <TextView android:id="@+id/title2"
+ android:layout_width="match_parent"
+ android:layout_height="20dip"
+ android:paddingLeft="8dip"
+ android:paddingRight="2dip"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:typeface="sans"
+ android:textSize="12sp"
+ android:textColor="#DDDDDD"
+ />
+</LinearLayout>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index 67acc0a..14c0c04 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -30,10 +30,12 @@
<dimen name="widgetItemMinHeight">48dip</dimen>
<dimen name="favicon_size">16dip</dimen>
<dimen name="favicon_padded_size">20dip</dimen>
- <dimen name="qc_radius_start">30dip</dimen>
- <dimen name="qc_radius_increment">70dip</dimen>
+ <dimen name="qc_radius_start">50dip</dimen>
+ <dimen name="qc_radius_increment">60dip</dimen>
<dimen name="qc_slop">15dip</dimen>
- <dimen name="qc_tab_title_height">20dip</dimen>
+ <dimen name="qc_tab_title_height">30dip</dimen>
+ <dimen name="qc_thumb_width">240dip</dimen>
+ <dimen name="qc_thumb_height">160dip</dimen>
<dimen name="bookmark_widget_thumb_size">32dip</dimen>
<dimen name="bookmark_widget_favicon_size">26dip</dimen>
<!-- For the most visited page -->
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 19ad40e..d02f05c 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -1956,17 +1956,17 @@ public class Controller
int thumbnailWidth = thumbnail.getWidth();
int thumbnailHeight = thumbnail.getHeight();
float scaleFactor = 1.0f;
- if (thumbnailWidth > 0) {
+ if (thumbnailWidth > 0 && thumbnailHeight > 0) {
scaleFactor = (float) width / (float)thumbnailWidth;
} else {
return null;
}
- if (view.getWidth() > view.getHeight() &&
- thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
- // If the device is in landscape and the page is shorter
- // than the height of the view, center the thumnail and crop the sides
- scaleFactor = (float) height / (float)thumbnailHeight;
+ float scaleFactorY = (float) height / (float)thumbnailHeight;
+ if (scaleFactorY > scaleFactor) {
+ // The picture is narrower than the requested AR
+ // Center the thumnail and crop the sides
+ scaleFactor = scaleFactorY;
float wx = (thumbnailWidth * scaleFactor) - width;
canvas.translate((int) -(wx / 2), 0);
}
diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java
index 302cbc0..5e95684 100644
--- a/src/com/android/browser/PieControl.java
+++ b/src/com/android/browser/PieControl.java
@@ -19,9 +19,15 @@ package com.android.browser;
import com.android.browser.view.PieItem;
import com.android.browser.view.PieListView;
import com.android.browser.view.PieMenu;
+import com.android.browser.view.PieMenu.PieView.OnLayoutListener;
+import com.android.browser.view.PieStackView;
+import com.android.browser.view.PieStackView.OnCurrentListener;
import android.app.Activity;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -33,6 +39,7 @@ import android.webkit.WebView;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import java.util.ArrayList;
@@ -56,6 +63,8 @@ public class PieControl implements OnClickListener, PieMenu.PieController {
private PieItem mNewTab;
private PieItem mClose;
private MenuAdapter mMenuAdapter;
+ private PieItem mShowTabs;
+ private TabAdapter mTabAdapter;
public PieControl(Activity activity, UiController controller, XLargeUi ui) {
mActivity = activity;
@@ -76,13 +85,32 @@ public class PieControl implements OnClickListener, PieMenu.PieController {
mForward = makeItem(R.drawable.ic_forward_holo_dark, 2);
mNewTab = makeItem(R.drawable.ic_new_window_holo_dark, 2);
mClose = makeItem(R.drawable.ic_close_window_holo_dark, 2);
+ mShowTabs = makeItem(R.drawable.ic_windows_holo_dark, 2);
mOptions = makeItem(
com.android.internal.R.drawable.ic_menu_moreoverflow_normal_holo_dark,
2);
mMenuAdapter = new MenuAdapter(mActivity, mUiController);
- PieMenuView menusym = new PieMenuView(mActivity);
- mOptions.setPieView(menusym);
- menusym.setAdapter(mMenuAdapter);
+ mTabAdapter = new TabAdapter(mActivity, mUiController);
+ PieStackView stack = new PieStackView(mActivity);
+ stack.setLayoutListener(new OnLayoutListener() {
+ @Override
+ public void onLayout(int ax, int ay, boolean left) {
+ buildTabs();
+ }
+ });
+ stack.setOnCurrentListener(mTabAdapter);
+ stack.setAdapter(mTabAdapter);
+ mShowTabs.setPieView(stack);
+ PieListView menuview = new PieListView(mActivity);
+ menuview.setLayoutListener(new OnLayoutListener() {
+ @Override
+ public void onLayout(int ax, int ay, boolean left) {
+ mActivity.openOptionsMenu();
+ }
+ });
+
+ mOptions.setPieView(menuview);
+ menuview.setAdapter(mMenuAdapter);
setClickListener(mBack,
mRefresh,
mForward,
@@ -98,6 +126,7 @@ public class PieControl implements OnClickListener, PieMenu.PieController {
// level 2
mPie.addItem(mForward);
mPie.addItem(mRefresh);
+ mPie.addItem(mShowTabs);
mPie.addItem(mNewTab);
mPie.addItem(mClose);
mPie.addItem(mOptions);
@@ -106,6 +135,15 @@ public class PieControl implements OnClickListener, PieMenu.PieController {
container.addView(mPie);
}
+ private void buildTabs() {
+ final List<Tab> tabs = mUiController.getTabs();
+ mUi.captureTab(mUi.getActiveTab());
+ mTabAdapter.setTabs(tabs);
+ PieStackView sym = (PieStackView) mShowTabs.getPieView();
+ sym.setCurrent(mUiController.getTabControl().getCurrentIndex());
+
+ }
+
protected void onMenuOpened(Menu menu) {
mMenuAdapter.setMenu(menu);
}
@@ -169,19 +207,72 @@ public class PieControl implements OnClickListener, PieMenu.PieController {
return false;
}
- private class PieMenuView extends PieListView {
+ private static class TabAdapter extends BaseAdapter implements OnCurrentListener {
+
+ LayoutInflater mInflater;
+ UiController mUiController;
+ private List<Tab> mTabs;
+ private int mCurrent;
+
+ public TabAdapter(Context ctx, UiController ctl) {
+ mInflater = LayoutInflater.from(ctx);
+ mUiController = ctl;
+ mTabs = new ArrayList<Tab>();
+ mCurrent = -1;
+ }
+
+ public void setTabs(List<Tab> tabs) {
+ mTabs = tabs;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
- /**
- * @param ctx
- */
- public PieMenuView(Context ctx) {
- super(ctx);
+ @Override
+ public Tab getItem(int position) {
+ return mTabs.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final Tab tab = mTabs.get(position);
+ View view = mInflater.inflate(R.layout.qc_tab,
+ null);
+ ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
+ TextView title1 = (TextView) view.findViewById(R.id.title1);
+ TextView title2 = (TextView) view.findViewById(R.id.title2);
+ Bitmap b = tab.getScreenshot();
+ if (b != null) {
+ thumb.setImageBitmap(b);
+ }
+ if (position > mCurrent) {
+ title1.setVisibility(View.GONE);
+ title2.setText(tab.getTitle());
+ } else {
+ title2.setVisibility(View.GONE);
+ title1.setText(tab.getTitle());
+ }
+ view.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mUiController.switchToTab(mUiController.getTabControl()
+ .getTabIndex(tab));
+ }
+ });
+ return view;
}
@Override
- public void layout(int anchorX, int anchorY, boolean left) {
- mActivity.openOptionsMenu();
- super.layout(anchorX, anchorY, left);
+ public void onSetCurrent(int index) {
+ mCurrent = index;
}
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 70028ea..bab3458 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -136,6 +136,8 @@ class Tab {
// AsyncTask for downloading touch icons
DownloadTouchIcon mTouchIconLoader;
+ private Bitmap mScreenshot;
+
// All the state needed for a page
private static class PageState {
String mUrl;
@@ -191,6 +193,7 @@ class Tab {
static final String APPID = "appid";
static final String ORIGINALURL = "originalUrl";
static final String INCOGNITO = "privateBrowsingEnabled";
+ static final String SCREENSHOT = "screenshot";
// -------------------------------------------------------------------------
@@ -1720,6 +1723,9 @@ class Tab {
mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
mParentTab));
}
+ if (mScreenshot != null) {
+ mSavedState.putParcelable(SCREENSHOT, mScreenshot);
+ }
return true;
}
@@ -1735,6 +1741,7 @@ class Tab {
mSavedState = null;
mCloseOnExit = b.getBoolean(CLOSEONEXIT);
mAppId = b.getString(APPID);
+ mScreenshot = b.getParcelable(SCREENSHOT);
final WebBackForwardList list = mMainView.restoreState(b);
if (list == null) {
@@ -1758,4 +1765,12 @@ class Tab {
}
};
+ public void setScreenshot(Bitmap screenshot) {
+ mScreenshot = screenshot;
+ }
+
+ public Bitmap getScreenshot() {
+ return mScreenshot;
+ }
+
}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 0712f37..a9a55e8 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -21,6 +21,7 @@ import com.android.browser.ScrollWebView.ScrollListener;
import android.app.ActionBar;
import android.app.Activity;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
@@ -118,15 +119,11 @@ public class XLargeUi extends BaseUi implements ScrollListener {
private void checkTabCount() {
if (mUseQuickControls) {
- if (mTabControl.getTabCount() == 1) {
- mHandler.post(new Runnable() {
- public void run() {
- mActionBar.hide();
- }
- });
- } else {
- mActionBar.show();
- }
+ mHandler.post(new Runnable() {
+ public void run() {
+ mActionBar.hide();
+ }
+ });
}
}
@@ -223,6 +220,11 @@ public class XLargeUi extends BaseUi implements ScrollListener {
@Override
public void setActiveTab(final Tab tab) {
+ if (mUseQuickControls) {
+ if (mActiveTab != null) {
+ captureTab(mActiveTab);
+ }
+ }
super.setActiveTab(tab, true);
setActiveTab(tab, true);
}
@@ -258,6 +260,15 @@ public class XLargeUi extends BaseUi implements ScrollListener {
tab.getTopWindow().requestFocus();
}
+ public void captureTab(final Tab tab) {
+ Bitmap sshot = Controller.createScreenshot(tab,
+ (int) mActivity.getResources()
+ .getDimension(R.dimen.qc_thumb_width),
+ (int) mActivity.getResources()
+ .getDimension(R.dimen.qc_thumb_height));
+ tab.setScreenshot(sshot);
+ }
+
@Override
public void updateTabs(List<Tab> tabs) {
mTabBar.updateTabs(tabs);
diff --git a/src/com/android/browser/view/BasePieView.java b/src/com/android/browser/view/BasePieView.java
index 515545a..2120215 100644
--- a/src/com/android/browser/view/BasePieView.java
+++ b/src/com/android/browser/view/BasePieView.java
@@ -33,6 +33,8 @@ public abstract class BasePieView implements PieMenu.PieView {
private DataSetObserver mObserver;
protected ArrayList<View> mViews;
+ protected OnLayoutListener mListener;
+
protected int mCurrent;
protected int mChildWidth;
protected int mChildHeight;
@@ -44,6 +46,10 @@ public abstract class BasePieView implements PieMenu.PieView {
public BasePieView() {
}
+ public void setLayoutListener(OnLayoutListener l) {
+ mListener = l;
+ }
+
public void setAdapter(Adapter adapter) {
mAdapter = adapter;
if (adapter == null) {
@@ -103,7 +109,12 @@ public abstract class BasePieView implements PieMenu.PieView {
* needs to set top, left, width, height
*/
@Override
- public abstract void layout(int anchorX, int anchorY, boolean left);
+ public void layout(int anchorX, int anchorY, boolean left) {
+ if (mListener != null) {
+ mListener.onLayout(anchorX, anchorY, left);
+ }
+ }
+
@Override
public abstract void draw(Canvas canvas);
diff --git a/src/com/android/browser/view/PieListView.java b/src/com/android/browser/view/PieListView.java
index 5fee51d..8cd8a4e 100644
--- a/src/com/android/browser/view/PieListView.java
+++ b/src/com/android/browser/view/PieListView.java
@@ -40,6 +40,7 @@ public class PieListView extends BasePieView {
*/
@Override
public void layout(int anchorX, int anchorY, boolean left) {
+ super.layout(anchorX, anchorY, left);
buildViews();
mWidth = mChildWidth;
mHeight = mChildHeight * mAdapter.getCount();
diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java
index 22ebd18..e494d19 100644
--- a/src/com/android/browser/view/PieMenu.java
+++ b/src/com/android/browser/view/PieMenu.java
@@ -51,6 +51,12 @@ public class PieMenu extends FrameLayout {
*/
public interface PieView {
+ public interface OnLayoutListener {
+ public void onLayout(int ax, int ay, boolean left);
+ }
+
+ public void setLayoutListener(OnLayoutListener l);
+
public void layout(int anchorX, int anchorY, boolean onleft);
public void draw(Canvas c);
diff --git a/src/com/android/browser/view/PieStackView.java b/src/com/android/browser/view/PieStackView.java
new file mode 100644
index 0000000..df387ad
--- /dev/null
+++ b/src/com/android/browser/view/PieStackView.java
@@ -0,0 +1,104 @@
+/*
+ * 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.view;
+
+import com.android.browser.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.view.View;
+
+/**
+ * shows views in a stack
+ */
+public class PieStackView extends BasePieView {
+
+ private static final int SLOP = 5;
+
+ private OnCurrentListener mCurrentListener;
+ private int mMinHeight;
+
+ public interface OnCurrentListener {
+ public void onSetCurrent(int index);
+ }
+
+ public PieStackView(Context ctx) {
+ mMinHeight = (int) ctx.getResources()
+ .getDimension(R.dimen.qc_tab_title_height);
+ }
+
+ public void setOnCurrentListener(OnCurrentListener l) {
+ mCurrentListener = l;
+ }
+
+ @Override
+ public void setCurrent(int ix) {
+ super.setCurrent(ix);
+ if (mCurrentListener != null) {
+ mCurrentListener.onSetCurrent(ix);
+ buildViews();
+ layoutChildrenLinear();
+ }
+ }
+
+ /**
+ * this will be called before the first draw call
+ */
+ @Override
+ public void layout(int anchorX, int anchorY, boolean left) {
+ super.layout(anchorX, anchorY, left);
+ buildViews();
+ mWidth = mChildWidth;
+ mHeight = mChildHeight + (mViews.size() - 1) * mMinHeight;
+ mLeft = anchorX + (left ? SLOP : -(SLOP + mChildWidth));
+ mTop = anchorY - mHeight / 2;
+ if (mViews != null) {
+ layoutChildrenLinear();
+ }
+ }
+
+ private void layoutChildrenLinear() {
+ final int n = mViews.size();
+ int top = mTop;
+ int dy = (n == 1) ? 0 : (mHeight - mChildHeight) / (n - 1);
+ for (View view : mViews) {
+ view.layout(mLeft, top, mLeft + mChildWidth, top + mChildHeight);
+ top += dy;
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (mViews != null) {
+ final int n = mViews.size();
+ for (int i = 0; i < mCurrent; i++) {
+ drawView(mViews.get(i), canvas);
+ }
+ for (int i = n - 1; i > mCurrent; i--) {
+ drawView(mViews.get(i), canvas);
+ }
+ drawView(mViews.get(mCurrent), canvas);
+ }
+ }
+
+ @Override
+ protected int findChildAt(int y) {
+ final int ix = (y - mTop) * mViews.size() / mHeight;
+ return ix;
+ }
+
+}