diff options
author | Michael Kolb <kolby@google.com> | 2011-03-08 14:12:06 -0800 |
---|---|---|
committer | Michael Kolb <kolby@google.com> | 2011-03-09 09:37:22 -0800 |
commit | 1acef69ffc079d1bc029ff7eb1f5043f7efd7f36 (patch) | |
tree | 9e8daece975b283d9866d2c1915cbd86446bb16b /src/com/android | |
parent | 66996bfa98bcf98f2ea944ddd27439f554f8f0b9 (diff) | |
download | packages_apps_Browser-1acef69ffc079d1bc029ff7eb1f5043f7efd7f36.zip packages_apps_Browser-1acef69ffc079d1bc029ff7eb1f5043f7efd7f36.tar.gz packages_apps_Browser-1acef69ffc079d1bc029ff7eb1f5043f7efd7f36.tar.bz2 |
add menu options to qc
Bug 4071315
Use the standard menu items to popuplate a menu from within quick
controls
Change-Id: I80d483ab2ce054e9b70ff4c6b0d6e0d9be783dc4
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/browser/BaseUi.java | 5 | ||||
-rw-r--r-- | src/com/android/browser/Controller.java | 9 | ||||
-rw-r--r-- | src/com/android/browser/PieControl.java | 102 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 1 | ||||
-rw-r--r-- | src/com/android/browser/UI.java | 2 | ||||
-rw-r--r-- | src/com/android/browser/UiController.java | 4 | ||||
-rw-r--r-- | src/com/android/browser/XLargeUi.java | 20 | ||||
-rw-r--r-- | src/com/android/browser/view/BasePieView.java | 150 | ||||
-rw-r--r-- | src/com/android/browser/view/PieItem.java | 21 | ||||
-rw-r--r-- | src/com/android/browser/view/PieListView.java | 78 | ||||
-rw-r--r-- | src/com/android/browser/view/PieMenu.java | 45 |
11 files changed, 428 insertions, 9 deletions
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java index b108fd8..5084e31 100644 --- a/src/com/android/browser/BaseUi.java +++ b/src/com/android/browser/BaseUi.java @@ -616,6 +616,11 @@ public abstract class BaseUi implements UI, WebViewFactory { // menu handling callbacks @Override + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + @Override public void onOptionsMenuOpened() { } diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java index 7a6ea41..19ad40e 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -1479,7 +1479,7 @@ public class Controller break; } mCurrentMenuState = mMenuState; - return true; + return mUi.onPrepareOptionsMenu(menu); } public boolean onOptionsItemSelected(MenuItem item) { @@ -1931,6 +1931,13 @@ public class Controller R.dimen.bookmarkThumbnailHeight); } + static Bitmap createScreenshot(Tab tab, int width, int height) { + if ((tab != null) && (tab.getWebView() != null)) { + return createScreenshot(tab.getWebView(), width, height); + } + return null; + } + private static Bitmap createScreenshot(WebView view, int width, int height) { // We render to a bitmap 2x the desired size so that we can then // re-scale it with filtering since canvas.scale doesn't filter diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java index ad47c72..302cbc0 100644 --- a/src/com/android/browser/PieControl.java +++ b/src/com/android/browser/PieControl.java @@ -17,15 +17,26 @@ package com.android.browser; import com.android.browser.view.PieItem; +import com.android.browser.view.PieListView; import com.android.browser.view.PieMenu; import android.app.Activity; +import android.content.Context; +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.view.ViewGroup.LayoutParams; import android.webkit.WebView; +import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; /** * controller for Quick Controls pie menu @@ -44,6 +55,7 @@ public class PieControl implements OnClickListener, PieMenu.PieController { private PieItem mBookmarks; private PieItem mNewTab; private PieItem mClose; + private MenuAdapter mMenuAdapter; public PieControl(Activity activity, UiController controller, XLargeUi ui) { mActivity = activity; @@ -67,11 +79,14 @@ public class PieControl implements OnClickListener, PieMenu.PieController { 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); setClickListener(mBack, mRefresh, mForward, mUrl, - mOptions, mBookmarks, mNewTab, mClose @@ -91,6 +106,10 @@ public class PieControl implements OnClickListener, PieMenu.PieController { container.addView(mPie); } + protected void onMenuOpened(Menu menu) { + mMenuAdapter.setMenu(menu); + } + protected void removeFromContainer(FrameLayout container) { container.removeView(mPie); } @@ -135,8 +154,6 @@ public class PieControl implements OnClickListener, PieMenu.PieController { } } else if (mUrl.getView() == v) { mUi.showTitleBarAndEdit(); - } else if (mOptions.getView() == v) { - mActivity.openOptionsMenu(); } else if (mBookmarks.getView() == v) { mUiController.bookmarksOrHistoryPicker(false); } else if (mNewTab.getView() == v) { @@ -152,4 +169,83 @@ public class PieControl implements OnClickListener, PieMenu.PieController { return false; } + private class PieMenuView extends PieListView { + + /** + * @param ctx + */ + public PieMenuView(Context ctx) { + super(ctx); + } + + @Override + public void layout(int anchorX, int anchorY, boolean left) { + mActivity.openOptionsMenu(); + super.layout(anchorX, anchorY, left); + } + + } + + private static class MenuAdapter extends BaseAdapter + implements OnClickListener { + + List<MenuItem> mItems; + UiController mUiController; + LayoutInflater mInflater; + + public MenuAdapter(Context ctx, UiController ctl) { + mUiController = ctl; + 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) { + 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); + label.setLayoutParams(new LayoutParams(240, 32)); + return label; + } + + } + } diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index 47cefbc..70028ea 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -1757,4 +1757,5 @@ class Tab { } } }; + } diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java index bec7034..13f8af2 100644 --- a/src/com/android/browser/UI.java +++ b/src/com/android/browser/UI.java @@ -89,6 +89,8 @@ public interface UI { public void revertVoiceTitleBar(Tab tab); + public boolean onPrepareOptionsMenu(Menu menu); + public void onOptionsMenuOpened(); public void onExtendedMenuOpened(); diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java index 551d0ce..65fa5f8 100644 --- a/src/com/android/browser/UiController.java +++ b/src/com/android/browser/UiController.java @@ -19,6 +19,7 @@ package com.android.browser; import com.android.browser.UI.DropdownChangeListener; import android.content.Intent; +import android.view.MenuItem; import android.webkit.WebView; import java.util.List; @@ -88,4 +89,7 @@ public interface UiController extends BookmarksHistoryCallbacks { void unregisterOptionsMenuHandler(OptionsMenuHandler handler); void registerDropdownChangeListener(DropdownChangeListener d); + + boolean onOptionsItemSelected(MenuItem item); + } diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java index d940b50..debb763 100644 --- a/src/com/android/browser/XLargeUi.java +++ b/src/com/android/browser/XLargeUi.java @@ -24,12 +24,15 @@ import android.animation.ObjectAnimator; import android.app.ActionBar; import android.app.Activity; import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Canvas; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.ActionMode; import android.view.Gravity; import android.view.KeyEvent; +import android.view.Menu; import android.view.View; import android.webkit.WebChromeClient.CustomViewCallback; import android.webkit.WebView; @@ -121,15 +124,14 @@ public class XLargeUi extends BaseUi implements ScrollListener { private void checkTabCount() { if (mUseQuickControls) { - int n = mTabBar.getTabCount(); - if (n >= 2) { - mActionBar.show(); - } else if (n == 1) { + if (mTabControl.getTabCount() == 1) { mHandler.post(new Runnable() { public void run() { mActionBar.hide(); } }); + } else { + mActionBar.show(); } } } @@ -503,4 +505,14 @@ public class XLargeUi extends BaseUi implements ScrollListener { mTitleBar.registerDropdownChangeListener(d); } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (mUseQuickControls) { + mPieControl.onMenuOpened(menu); + return false; + } else { + return true; + } + } + } diff --git a/src/com/android/browser/view/BasePieView.java b/src/com/android/browser/view/BasePieView.java new file mode 100644 index 0000000..515545a --- /dev/null +++ b/src/com/android/browser/view/BasePieView.java @@ -0,0 +1,150 @@ +/* + * 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 android.database.DataSetObserver; +import android.graphics.Canvas; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Adapter; + +import java.util.ArrayList; + +/** + * common code for pie views + */ +public abstract class BasePieView implements PieMenu.PieView { + + protected Adapter mAdapter; + private DataSetObserver mObserver; + protected ArrayList<View> mViews; + + protected int mCurrent; + protected int mChildWidth; + protected int mChildHeight; + protected int mWidth; + protected int mHeight; + protected int mLeft; + protected int mTop; + + public BasePieView() { + } + + public void setAdapter(Adapter adapter) { + mAdapter = adapter; + if (adapter == null) { + if (mAdapter != null) { + mAdapter.unregisterDataSetObserver(mObserver); + } + mViews = null; + mCurrent = -1; + } else { + mObserver = new DataSetObserver() { + @Override + public void onChanged() { + buildViews(); + } + + @Override + public void onInvalidated() { + mViews.clear(); + } + }; + mAdapter.registerDataSetObserver(mObserver); + setCurrent(0); + } + } + + public void setCurrent(int ix) { + mCurrent = ix; + } + + public Adapter getAdapter() { + return mAdapter; + } + + protected void buildViews() { + if (mAdapter != null) { + final int n = mAdapter.getCount(); + if (mViews == null) { + mViews = new ArrayList<View>(n); + } else { + mViews.clear(); + } + mChildWidth = 0; + mChildHeight = 0; + for (int i = 0; i < n; i++) { + View view = mAdapter.getView(i, null, null); + view.measure(View.MeasureSpec.UNSPECIFIED, + View.MeasureSpec.UNSPECIFIED); + mChildWidth = Math.max(mChildWidth, view.getMeasuredWidth()); + mChildHeight = Math.max(mChildHeight, view.getMeasuredHeight()); + mViews.add(view); + } + } + } + + /** + * this will be called before the first draw call + * needs to set top, left, width, height + */ + @Override + public abstract void layout(int anchorX, int anchorY, boolean left); + + @Override + public abstract void draw(Canvas canvas); + + protected void drawView(View view, Canvas canvas) { + final int state = canvas.save(); + canvas.translate(view.getLeft(), view.getTop()); + view.draw(canvas); + canvas.restoreToCount(state); + } + + protected abstract int findChildAt(int y); + + @Override + public boolean onTouchEvent(MotionEvent evt) { + int action = evt.getActionMasked(); + int evtx = (int) evt.getX(); + int evty = (int) evt.getY(); + if ((evtx < mLeft) || (evtx >= mLeft + mWidth) + || (evty < mTop) || (evty >= mTop + mHeight)) { + return false; + } + switch (action) { + case MotionEvent.ACTION_MOVE: + View v = mViews.get(mCurrent); + setCurrent(Math.max(0, Math.min(mViews.size() -1, + findChildAt(evty)))); + View v1 = mViews.get(mCurrent); + if (v != v1) { + v.setPressed(false); + v1.setPressed(true); + } + break; + case MotionEvent.ACTION_UP: + mViews.get(mCurrent).performClick(); + mViews.get(mCurrent).setPressed(false); + break; + default: + break; + } + return true; + } + +} diff --git a/src/com/android/browser/view/PieItem.java b/src/com/android/browser/view/PieItem.java index c09dba2..84a6ac0 100644 --- a/src/com/android/browser/view/PieItem.java +++ b/src/com/android/browser/view/PieItem.java @@ -16,6 +16,8 @@ package com.android.browser.view; +import com.android.browser.view.PieMenu.PieView; + import android.view.View; /** @@ -24,6 +26,7 @@ import android.view.View; public class PieItem { private View mView; + private PieView mPieView; private int level; private float start; private float sweep; @@ -36,6 +39,12 @@ public class PieItem { this.level = level; } + public PieItem(View view, int level, PieView sym) { + mView = view; + this.level = level; + mPieView = sym; + } + public void setSelected(boolean s) { mSelected = s; if (mView != null) { @@ -74,8 +83,20 @@ public class PieItem { return outer; } + public boolean isPieView() { + return (mPieView != null); + } + public View getView() { return mView; } + public void setPieView(PieView sym) { + mPieView = sym; + } + + public PieView getPieView() { + return mPieView; + } + } diff --git a/src/com/android/browser/view/PieListView.java b/src/com/android/browser/view/PieListView.java new file mode 100644 index 0000000..5fee51d --- /dev/null +++ b/src/com/android/browser/view/PieListView.java @@ -0,0 +1,78 @@ +/* + * 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.graphics.Paint; +import android.view.View; + +/** + * shows views in a menu style list + */ +public class PieListView extends BasePieView { + + private Paint mBgPaint; + + public PieListView(Context ctx) { + mBgPaint = new Paint(); + mBgPaint.setColor(ctx.getResources().getColor(R.color.qcMenuBackground)); + } + + /** + * this will be called before the first draw call + */ + @Override + public void layout(int anchorX, int anchorY, boolean left) { + buildViews(); + mWidth = mChildWidth; + mHeight = mChildHeight * mAdapter.getCount(); + mLeft = anchorX + (left ? 0 : - mChildWidth); + mTop = anchorY - mHeight / 2; + if (mViews != null) { + layoutChildrenLinear(); + } + } + + protected void layoutChildrenLinear() { + final int n = mViews.size(); + int top = mTop; + for (View view : mViews) { + view.layout(mLeft, top, mLeft + mChildWidth, top + mChildHeight); + top += mChildHeight; + } + } + + @Override + public void draw(Canvas canvas) { + canvas.drawRect(mLeft, mTop, mLeft + mWidth, mTop + mHeight, mBgPaint); + if (mViews != null) { + for (View view : mViews) { + drawView(view, canvas); + } + } + } + + @Override + protected int findChildAt(int y) { + final int ix = (y - mTop) * mViews.size() / mHeight; + return ix; + } + +} diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java index 98c0f59..22ebd18 100644 --- a/src/com/android/browser/view/PieMenu.java +++ b/src/com/android/browser/view/PieMenu.java @@ -46,6 +46,19 @@ public class PieMenu extends FrameLayout { public boolean onOpen(); } + /** + * A view like object that lives off of the pie menu + */ + public interface PieView { + + public void layout(int anchorX, int anchorY, boolean onleft); + + public void draw(Canvas c); + + public boolean onTouchEvent(MotionEvent evt); + + } + private Point mCenter; private int mRadius; private int mRadiusInc; @@ -57,6 +70,7 @@ public class PieMenu extends FrameLayout { private List<PieItem> mItems; private int mLevels; private int[] mCounts; + private PieView mPieView = null; private Drawable mBackground; @@ -143,6 +157,7 @@ public class PieMenu extends FrameLayout { } if (!show) { mCurrentItem = null; + mPieView = null; } invalidate(); } @@ -159,6 +174,7 @@ public class PieMenu extends FrameLayout { private void layoutPie() { int inner = mRadius; int outer = mRadius + mRadiusInc; + int radius = mRadius; for (int i = 0; i < mLevels; i++) { int level = i + 1; float sweep = (float) Math.PI / (mCounts[level] + 1); @@ -205,6 +221,9 @@ public class PieMenu extends FrameLayout { for (PieItem item : mItems) { drawItem(canvas, item); } + if (mPieView != null) { + mPieView.draw(canvas); + } } } @@ -236,10 +255,14 @@ public class PieMenu extends FrameLayout { } } else if (MotionEvent.ACTION_UP == action) { if (mOpen) { + boolean handled = false; + if (mPieView != null) { + handled = mPieView.onTouchEvent(evt); + } PieItem item = mCurrentItem; deselect(); show(false); - if (item != null) { + if (!handled && (item != null)) { item.getView().performClick(); } return true; @@ -254,6 +277,13 @@ public class PieMenu extends FrameLayout { boolean handled = false; PointF polar = getPolar(x, y); int maxr = mRadius + mLevels * mRadiusInc + 50; + if (mPieView != null) { + handled = mPieView.onTouchEvent(evt); + } + if (handled) { + invalidate(); + return false; + } if (polar.y > maxr) { deselect(); show(false); @@ -266,6 +296,13 @@ public class PieMenu extends FrameLayout { PieItem item = findItem(polar); if (mCurrentItem != item) { onEnter(item); + if ((item != null) && item.isPieView()) { + int cx = item.getView().getLeft() + (onTheLeft() + ? item.getView().getWidth() : 0); + int cy = item.getView().getTop(); + mPieView = item.getPieView(); + layoutPieView(mPieView, cx, cy); + } invalidate(); } } @@ -273,6 +310,10 @@ public class PieMenu extends FrameLayout { return false; } + private void layoutPieView(PieView pv, int x, int y) { + pv.layout(x, y, onTheLeft()); + } + /** * enter a slice for a view * updates model only @@ -287,6 +328,7 @@ public class PieMenu extends FrameLayout { // clear up stack playSoundEffect(SoundEffectConstants.CLICK); item.setSelected(true); + mPieView = null; } mCurrentItem = item; } @@ -296,6 +338,7 @@ public class PieMenu extends FrameLayout { mCurrentItem.setSelected(false); } mCurrentItem = null; + mPieView = null; } private PointF getPolar(float x, float y) { |