diff options
-rw-r--r-- | res/layout/qc_tab.xml | 61 | ||||
-rw-r--r-- | res/values/dimensions.xml | 8 | ||||
-rw-r--r-- | src/com/android/browser/Controller.java | 12 | ||||
-rw-r--r-- | src/com/android/browser/PieControl.java | 115 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 15 | ||||
-rw-r--r-- | src/com/android/browser/XLargeUi.java | 29 | ||||
-rw-r--r-- | src/com/android/browser/view/BasePieView.java | 13 | ||||
-rw-r--r-- | src/com/android/browser/view/PieListView.java | 1 | ||||
-rw-r--r-- | src/com/android/browser/view/PieMenu.java | 6 | ||||
-rw-r--r-- | src/com/android/browser/view/PieStackView.java | 104 |
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; + } + +} |