diff options
author | Michael Kolb <kolby@google.com> | 2011-03-08 13:47:38 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-03-08 13:47:38 -0800 |
commit | d648317789ed4d73b831c3d816130792f545d721 (patch) | |
tree | 9e3901c735d0a890b8fdca90b575f4bf1f8017e5 | |
parent | 3912de63b87d32905de08c91280b160f9100d3f2 (diff) | |
parent | 4975d0cab83b1a8904515ed50f3ef1c64104517f (diff) | |
download | packages_apps_Browser-d648317789ed4d73b831c3d816130792f545d721.zip packages_apps_Browser-d648317789ed4d73b831c3d816130792f545d721.tar.gz packages_apps_Browser-d648317789ed4d73b831c3d816130792f545d721.tar.bz2 |
am 4975d0ca: Merge "qc refactor part1" into honeycomb-mr1
* commit '4975d0cab83b1a8904515ed50f3ef1c64104517f':
qc refactor part1
-rw-r--r-- | res/drawable-mdpi/pie_bg_selected.png | bin | 0 -> 1351 bytes | |||
-rw-r--r-- | res/drawable-mdpi/qc_background_normal.png | bin | 12095 -> 59066 bytes | |||
-rw-r--r-- | res/drawable/qc_item_selector.xml | 21 | ||||
-rw-r--r-- | res/values/colors.xml | 3 | ||||
-rw-r--r-- | res/values/dimensions.xml | 5 | ||||
-rw-r--r-- | src/com/android/browser/PieControl.java | 103 | ||||
-rw-r--r-- | src/com/android/browser/XLargeUi.java | 1 | ||||
-rw-r--r-- | src/com/android/browser/view/PieItem.java | 81 | ||||
-rw-r--r-- | src/com/android/browser/view/PieMenu.java | 429 |
9 files changed, 269 insertions, 374 deletions
diff --git a/res/drawable-mdpi/pie_bg_selected.png b/res/drawable-mdpi/pie_bg_selected.png Binary files differnew file mode 100644 index 0000000..787984a --- /dev/null +++ b/res/drawable-mdpi/pie_bg_selected.png diff --git a/res/drawable-mdpi/qc_background_normal.png b/res/drawable-mdpi/qc_background_normal.png Binary files differindex 539b45d..947722d 100644 --- a/res/drawable-mdpi/qc_background_normal.png +++ b/res/drawable-mdpi/qc_background_normal.png diff --git a/res/drawable/qc_item_selector.xml b/res/drawable/qc_item_selector.xml new file mode 100644 index 0000000..77f8023 --- /dev/null +++ b/res/drawable/qc_item_selector.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_selected="true" + android:drawable="@drawable/pie_bg_selected" /> + <item android:state_selected="false" android:drawable="@drawable/clear" /> +</selector> diff --git a/res/values/colors.xml b/res/values/colors.xml index 6fa0840..73daa07 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -29,10 +29,9 @@ <color name="bookmarkWidgetDivider">#383847</color> <color name="bookmarkWidgetItemBackground">#2b2b3c</color> <color name="bookmarkWidgetFolderBackground">#A0383847</color> - <color name="qc_slice_normal">#E0A0A0A0</color> - <color name="qc_slice_active">#E02090FF</color> <color name="bookmarkWidgetFaviconBackground">#23ffffff</color> <color name="bookmarkListFaviconBackground">#23ffffff</color> <color name="tabFaviconBackground">#FF555555</color> <color name="tabFocusHighlight">#FF99CC00</color> + <color name="qcMenuBackground">#C0000000</color> </resources> diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml index 5054254..67acc0a 100644 --- a/res/values/dimensions.xml +++ b/res/values/dimensions.xml @@ -30,9 +30,10 @@ <dimen name="widgetItemMinHeight">48dip</dimen> <dimen name="favicon_size">16dip</dimen> <dimen name="favicon_padded_size">20dip</dimen> - <dimen name="qc_radius">130dip</dimen> - <dimen name="qc_radius_inc">100dip</dimen> + <dimen name="qc_radius_start">30dip</dimen> + <dimen name="qc_radius_increment">70dip</dimen> <dimen name="qc_slop">15dip</dimen> + <dimen name="qc_tab_title_height">20dip</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/PieControl.java b/src/com/android/browser/PieControl.java index 2e2eba4..ad47c72 100644 --- a/src/com/android/browser/PieControl.java +++ b/src/com/android/browser/PieControl.java @@ -16,6 +16,7 @@ package com.android.browser; +import com.android.browser.view.PieItem; import com.android.browser.view.PieMenu; import android.app.Activity; @@ -26,9 +27,6 @@ import android.webkit.WebView; import android.widget.FrameLayout; import android.widget.ImageView; -import java.util.HashMap; -import java.util.Map; - /** * controller for Quick Controls pie menu */ @@ -38,24 +36,19 @@ public class PieControl implements OnClickListener, PieMenu.PieController { private UiController mUiController; private XLargeUi mUi; private PieMenu mPie; - private ImageView mBack; - private ImageView mForward; - private ImageView mRefresh; - private ImageView mUrl; - private ImageView mOptions; - private ImageView mBookmarks; - private ImageView mNewTab; - private ImageView mClose; - - private Map<View,Tab> mTabItems; - - boolean mNewTabMode = true; + private PieItem mBack; + private PieItem mForward; + private PieItem mRefresh; + private PieItem mUrl; + private PieItem mOptions; + private PieItem mBookmarks; + private PieItem mNewTab; + private PieItem mClose; public PieControl(Activity activity, UiController controller, XLargeUi ui) { mActivity = activity; mUiController = controller; mUi = ui; - mTabItems = new HashMap<View, Tab>(); } protected void attachToContainer(FrameLayout container) { @@ -64,22 +57,35 @@ public class PieControl implements OnClickListener, PieMenu.PieController { LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); mPie.setLayoutParams(lp); - mNewTab = makeMenuView(R.drawable.ic_pie_new_tab); - mPie.addItem(mNewTab); - mBack = makeMenuView(R.drawable.ic_pie_back); - mPie.addItem(mBack); - mUrl = makeMenuView(R.drawable.ic_pie_web); - mPie.addItem(mUrl); - mBookmarks = makeMenuView(R.drawable.ic_pie_bookmarks); - mPie.addItem(mBookmarks); - mOptions = makeMenuView(R.drawable.ic_pie_more); - mPie.addItem(mOptions); + mBack = makeItem(R.drawable.ic_back_holo_dark, 1); + mUrl = makeItem(R.drawable.ic_web_holo_dark, 1); + mBookmarks = makeItem(R.drawable.ic_bookmarks_holo_dark, 1); + mRefresh = makeItem(R.drawable.ic_refresh_holo_dark, 2); + 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); + mOptions = makeItem( + com.android.internal.R.drawable.ic_menu_moreoverflow_normal_holo_dark, + 2); setClickListener(mBack, + mRefresh, + mForward, mUrl, mOptions, mBookmarks, - mNewTab + mNewTab, + mClose ); + // level 1 + mPie.addItem(mBack); + mPie.addItem(mUrl); + mPie.addItem(mBookmarks); + // level 2 + mPie.addItem(mForward); + mPie.addItem(mRefresh); + mPie.addItem(mNewTab); + mPie.addItem(mClose); + mPie.addItem(mOptions); mPie.setController(this); } container.addView(mPie); @@ -89,17 +95,20 @@ public class PieControl implements OnClickListener, PieMenu.PieController { container.removeView(mPie); } - private ImageView makeMenuView(int image) { - ImageView item = new ImageView(mActivity); - item.setImageResource(image); + private PieItem makeItem(int image, int l) { + ImageView view = new ImageView(mActivity); + view.setImageResource(image); + view.setMinimumWidth(48); + view.setMinimumHeight(48); LayoutParams lp = new LayoutParams(48, 48); - item.setLayoutParams(lp); - return item; + view.setLayoutParams(lp); + view.setBackgroundResource(R.drawable.qc_item_selector); + return new PieItem(view, l); } - private void setClickListener(View... views) { - for (View view : views) { - view.setOnClickListener(this); + private void setClickListener(PieItem... items) { + for (PieItem item : items) { + item.getView().setOnClickListener(this); } } @@ -112,41 +121,35 @@ public class PieControl implements OnClickListener, PieMenu.PieController { @Override public void onClick(View v) { - mPie.show(false); Tab tab = mUiController.getTabControl().getCurrentTab(); WebView web = tab.getWebView(); - if (mBack == v) { + if (mBack.getView() == v) { web.goBack(); - } else if (mForward == v) { + } else if (mForward.getView() == v) { web.goForward(); - } else if (mRefresh == v) { + } else if (mRefresh.getView() == v) { if (tab.inPageLoad()) { web.stopLoading(); } else { web.reload(); } - } else if (mUrl == v) { + } else if (mUrl.getView() == v) { mUi.showTitleBarAndEdit(); - } else if (mOptions == v) { + } else if (mOptions.getView() == v) { mActivity.openOptionsMenu(); - } else if (mBookmarks == v) { + } else if (mBookmarks.getView() == v) { mUiController.bookmarksOrHistoryPicker(false); - } else if (mNewTab == v) { + } else if (mNewTab.getView() == v) { mUiController.openTabToHomePage(); mUi.showTitleBarAndEdit(); - } else if (mClose == v) { + } else if (mClose.getView() == v) { mUiController.closeCurrentTab(); - } else { - Tab ntab = mTabItems.get(v); - if (ntab != null) { - mUiController.switchToTab(mUiController.getTabControl().getTabIndex(ntab)); - } } } @Override public boolean onOpen() { - return true; + return false; } } diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java index 6225ad4..fdb72e5 100644 --- a/src/com/android/browser/XLargeUi.java +++ b/src/com/android/browser/XLargeUi.java @@ -501,4 +501,5 @@ public class XLargeUi extends BaseUi implements ScrollListener { public void registerDropdownChangeListener(DropdownChangeListener d) { mTitleBar.registerDropdownChangeListener(d); } + } diff --git a/src/com/android/browser/view/PieItem.java b/src/com/android/browser/view/PieItem.java new file mode 100644 index 0000000..c09dba2 --- /dev/null +++ b/src/com/android/browser/view/PieItem.java @@ -0,0 +1,81 @@ +/* + * 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.view.View; + +/** + * Pie menu item + */ +public class PieItem { + + private View mView; + private int level; + private float start; + private float sweep; + private int inner; + private int outer; + private boolean mSelected; + + public PieItem(View view, int level) { + mView = view; + this.level = level; + } + + public void setSelected(boolean s) { + mSelected = s; + if (mView != null) { + mView.setSelected(s); + } + } + + public boolean isSelected() { + return mSelected; + } + + public int getLevel() { + return level; + } + + public void setGeometry(float st, float sw, int inside, int outside) { + start = st; + sweep = sw; + inner = inside; + outer = outside; + } + + public float getStartAngle() { + return start; + } + + public float getSweep() { + return sweep; + } + + public int getInnerRadius() { + return inner; + } + + public int getOuterRadius() { + return outer; + } + + public View getView() { + return mView; + } + +} diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java index 080c257..98c0f59 100644 --- a/src/com/android/browser/view/PieMenu.java +++ b/src/com/android/browser/view/PieMenu.java @@ -20,17 +20,9 @@ import com.android.browser.R; import android.content.Context; import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapShader; import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.MotionEvent; @@ -40,13 +32,11 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class PieMenu extends FrameLayout { - private static final int RADIUS_GAP = 10; + private static final int MAX_LEVELS = 5; public interface PieController { /** @@ -55,31 +45,23 @@ public class PieMenu extends FrameLayout { */ public boolean onOpen(); } + private Point mCenter; private int mRadius; private int mRadiusInc; private int mSlop; private boolean mOpen; - private Paint mPaint; - private Paint mSelectedPaint; private PieController mController; - private Map<View, List<View>> mMenu; - private List<View> mStack; - - private boolean mDirty; - - private Drawable mActiveDrawable; - private Drawable mInactiveDrawable; - private final Paint mActiveShaderPaint = new Paint(); - private final Paint mInactiveShaderPaint = new Paint(); - private final Matrix mActiveMatrix = new Matrix(); - private final Matrix mInactiveMatrix = new Matrix(); + private List<PieItem> mItems; + private int mLevels; + private int[] mCounts; - private BitmapShader mActiveShader; - private BitmapShader mInactiveShader; + private Drawable mBackground; + // touch handling + PieItem mCurrentItem; /** * @param context @@ -109,130 +91,58 @@ public class PieMenu extends FrameLayout { } private void init(Context ctx) { - this.setTag(new MenuTag(0)); - mStack = new ArrayList<View>(); - mStack.add(this); + mItems = new ArrayList<PieItem>(); + mLevels = 0; + mCounts = new int[MAX_LEVELS]; Resources res = ctx.getResources(); - mRadius = (int) res.getDimension(R.dimen.qc_radius); - mRadiusInc = (int) res.getDimension(R.dimen.qc_radius_inc); + mRadius = (int) res.getDimension(R.dimen.qc_radius_start); + mRadiusInc = (int) res.getDimension(R.dimen.qc_radius_increment); mSlop = (int) res.getDimension(R.dimen.qc_slop); - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setColor(res.getColor(R.color.qc_slice_normal)); - mSelectedPaint = new Paint(); - mSelectedPaint.setAntiAlias(true); - mSelectedPaint.setColor(res.getColor(R.color.qc_slice_active)); mOpen = false; - mMenu = new HashMap<View, List<View>>(); setWillNotDraw(false); setDrawingCacheEnabled(false); mCenter = new Point(0,0); - mDirty = true; - mActiveShaderPaint.setStyle(Paint.Style.FILL); - mActiveShaderPaint.setAntiAlias(true); - - mInactiveShaderPaint.setStyle(Paint.Style.FILL); - mInactiveShaderPaint.setAntiAlias(true); - mActiveDrawable = res.getDrawable(R.drawable.qc_background_selected); - mInactiveDrawable = res.getDrawable(R.drawable.qc_background_normal); - - Bitmap activeTexture = getDrawableAsBitmap(mActiveDrawable, - mActiveDrawable.getIntrinsicWidth(), - mActiveDrawable.getIntrinsicHeight()); - Bitmap inactiveTexture = getDrawableAsBitmap(mInactiveDrawable, - mInactiveDrawable.getIntrinsicWidth(), - mInactiveDrawable.getIntrinsicHeight()); - - mActiveShader = new BitmapShader(activeTexture, - Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); - mActiveShaderPaint.setShader(mActiveShader); - - mInactiveShader = new BitmapShader(inactiveTexture, - Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); - mInactiveShaderPaint.setShader(mInactiveShader); - - } - - private static Bitmap getDrawableAsBitmap(Drawable drawable, int width, int height) { - Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(b); - drawable.setBounds(0, 0, width, height); - drawable.draw(c); - return b; + mBackground = res.getDrawable(R.drawable.qc_background_normal); } public void setController(PieController ctl) { mController = ctl; } - public void setRadius(int r) { - mRadius = r; - requestLayout(); - } - - public void setRadiusIncrement(int ri) { - mRadiusInc = ri; - requestLayout(); - } - - /** - * add a menu item to another item as a submenu - * @param item - * @param parent - */ - public void addItem(View item, View parent) { - List<View> subs = mMenu.get(parent); - if (subs == null) { - subs = new ArrayList<View>(); - mMenu.put(parent, subs); - } - subs.add(item); - MenuTag tag = new MenuTag(((MenuTag) parent.getTag()).level + 1); - item.setTag(tag); - } - - public void addItem(View view) { + public void addItem(PieItem item) { // add the item to the pie itself - addItem(view, this); - } - - public void removeItem(View view) { - List<View> subs = mMenu.get(view); - mMenu.remove(view); - for (View p : mMenu.keySet()) { - List<View> sl = mMenu.get(p); - if (sl != null) { - sl.remove(view); - } - } + mItems.add(item); + int l = item.getLevel(); + mLevels = Math.max(mLevels, l); + mCounts[l]++; } - public void clearItems(View parent) { - List<View> subs = mMenu.remove(parent); - if (subs != null) { - for (View sub: subs) { - clearItems(sub); - } - } + public void removeItem(PieItem item) { + mItems.remove(item); } public void clearItems() { - mMenu.clear(); + mItems.clear(); } + private boolean onTheLeft() { + return mCenter.x < mSlop; + } - public void show(boolean show) { + /** + * guaranteed has center set + * @param show + */ + private void show(boolean show) { mOpen = show; if (mOpen) { if (mController != null) { boolean changed = mController.onOpen(); } - mDirty = true; + layoutPie(); } if (!show) { - // hide sub items - mStack.clear(); - mStack.add(this); + mCurrentItem = null; } invalidate(); } @@ -246,151 +156,72 @@ public class PieMenu extends FrameLayout { mCenter.y = y; } - private boolean onTheLeft() { - return mCenter.x < mSlop; - } - - @Override - protected void onDraw(Canvas canvas) { - if (mOpen) { - int radius = mRadius; - // start in the center for 0 level menu - float anchor = (float) Math.PI / 2; - PointF angles = new PointF(); - int state = canvas.save(); - if (onTheLeft()) { - // left handed - canvas.scale(-1, 1); - } - for (View parent : mStack) { - List<View> subs = mMenu.get(parent); - if (subs != null) { - setGeometry(anchor, subs.size(), angles); + private void layoutPie() { + int inner = mRadius; + int outer = mRadius + mRadiusInc; + for (int i = 0; i < mLevels; i++) { + int level = i + 1; + float sweep = (float) Math.PI / (mCounts[level] + 1); + float angle = sweep; + for (PieItem item : mItems) { + if (item.getLevel() == level) { + View view = item.getView(); + view.measure(view.getLayoutParams().width, + view.getLayoutParams().height); + int w = view.getMeasuredWidth(); + int h = view.getMeasuredHeight(); + int x = (int) (outer * Math.sin(angle)); + int y = mCenter.y - (int) (outer * Math.cos(angle)) - h / 2; + if (onTheLeft()) { + x = mCenter.x + x - w; + } else { + x = mCenter.x - x; + } + view.layout(x, y, x + w, y + h); + float itemstart = angle - sweep / 2; + item.setGeometry(itemstart, sweep, inner, outer); + angle += sweep; } - anchor = drawSlices(canvas, subs, radius, angles.x, angles.y); - radius += mRadiusInc + RADIUS_GAP; } - canvas.restoreToCount(state); - mDirty = false; + inner += mRadiusInc; + outer += mRadiusInc; } } - /** - * draw the set of slices - * @param canvas - * @param items - * @param radius - * @param start - * @param sweep - * @return the angle of the selected slice - */ - private float drawSlices(Canvas canvas, List<View> items, int radius, - float start, float sweep) { - float angle = start + sweep / 2; - // gap between slices in degrees - float gap = 1f; - float newanchor = 0f; - for (View item : items) { - if (mDirty) { - item.measure(item.getLayoutParams().width, - item.getLayoutParams().height); - int w = item.getMeasuredWidth(); - int h = item.getMeasuredHeight(); - int x = (int) (radius * Math.sin(angle)); - int y = mCenter.y - (int) (radius * Math.cos(angle)) - h / 2; - if (onTheLeft()) { - x = mCenter.x + x - w / 2; - } else { - x = mCenter.x - x - w / 2; - } - item.layout(x, y, x + w, y + h); - } - float itemstart = angle - sweep / 2; - int inner = radius - mRadiusInc / 2; - int outer = radius + mRadiusInc / 2; - Path slice = makeSlice(getDegrees(itemstart) - gap, - getDegrees(itemstart + sweep) + gap, - outer, inner, mCenter); - MenuTag tag = (MenuTag) item.getTag(); - tag.start = itemstart; - tag.sweep = sweep; - tag.inner = inner; - tag.outer = outer; + @Override + protected void onDraw(Canvas canvas) { + if (mOpen) { + int w = mBackground.getIntrinsicWidth(); + int h = mBackground.getIntrinsicHeight(); + int left = mCenter.x - w; + int top = mCenter.y - h / 2; + mBackground.setBounds(left, top, left + w, top + h); int state = canvas.save(); - int[] topLeft = new int[2]; - getLocationInWindow(topLeft); - topLeft[0] = mCenter.x - outer; - topLeft[1] = mCenter.y - outer; - Paint paint = item.isPressed() ? mActiveShaderPaint : mInactiveShaderPaint; - drawClipped(canvas, paint, slice, topLeft, item.isPressed()); - canvas.restoreToCount(state); - state = canvas.save(); if (onTheLeft()) { canvas.scale(-1, 1); } - canvas.translate(item.getX(), item.getY()); - item.draw(canvas); + mBackground.draw(canvas); canvas.restoreToCount(state); - if (mStack.contains(item)) { - // item is anchor for sub menu - newanchor = angle; + for (PieItem item : mItems) { + drawItem(canvas, item); } - angle += sweep; } - return newanchor; - } - - private void drawClipped(Canvas canvas, Paint paint, Path clipPath, int[] pos, - boolean selected) { - // TODO: We should change the matrix/shader only when needed - final Matrix matrix = selected ? mActiveMatrix : mInactiveMatrix; - matrix.setTranslate(pos[0], pos[1]); - (selected ? mActiveShader : mInactiveShader).setLocalMatrix(matrix); - canvas.drawPath(clipPath, paint); } - - /** - * converts a - * @param angle from 0..PI to Android degrees (clockwise starting at 3 o'clock) - * @return skia angle - */ - private float getDegrees(double angle) { - return (float) (270 - 180 * angle / Math.PI); - } - - private Path makeSlice(float startangle, float endangle, int outerradius, - int innerradius, Point center) { - RectF bb = new RectF(center.x - outerradius, center.y - outerradius, - center.x + outerradius, center.y + outerradius); - RectF bbi = new RectF(center.x - innerradius, center.y - innerradius, - center.x + innerradius, center.y + innerradius); - Path path = new Path(); - path.arcTo(bb, startangle, endangle - startangle, true); - path.arcTo(bbi, endangle, startangle - endangle); - path.close(); - return path; - } - - /** - * all angles are 0 .. MATH.PI where 0 points up, and rotate counterclockwise - * set the startangle and slice sweep in result - * @param anchorangle : angle at which the menu is anchored - * @param nslices - * @param result : x : start, y : sweep - */ - private void setGeometry(float anchorangle, int nslices, PointF result) { - float span = (float) Math.min(anchorangle, Math.PI - anchorangle); - float sweep = 2 * span / (nslices + 1); - result.x = anchorangle - span + sweep / 2; - result.y = sweep; + private void drawItem(Canvas canvas, PieItem item) { + int outer = item.getOuterRadius(); + int left = mCenter.x - outer; + int top = mCenter.y - outer; + // draw the item view + View view = item.getView(); + int state = canvas.save(); + canvas.translate(view.getX(), view.getY()); + view.draw(canvas); + canvas.restoreToCount(state); } // touch handling for pie - View mCurrentView; - Rect mHitRect = new Rect(); - @Override public boolean onTouchEvent(MotionEvent evt) { float x = evt.getX(); @@ -405,12 +236,12 @@ public class PieMenu extends FrameLayout { } } else if (MotionEvent.ACTION_UP == action) { if (mOpen) { - View v = mCurrentView; + PieItem item = mCurrentItem; deselect(); - if (v != null) { - v.performClick(); - } show(false); + if (item != null) { + item.getView().performClick(); + } return true; } } else if (MotionEvent.ACTION_CANCEL == action) { @@ -420,19 +251,21 @@ public class PieMenu extends FrameLayout { deselect(); return false; } else if (MotionEvent.ACTION_MOVE == action) { + boolean handled = false; PointF polar = getPolar(x, y); - if (polar.y > mRadius + 2 * mRadiusInc) { - show(false); + int maxr = mRadius + mLevels * mRadiusInc + 50; + if (polar.y > maxr) { deselect(); + show(false); evt.setAction(MotionEvent.ACTION_DOWN); if (getParent() != null) { ((ViewGroup) getParent()).dispatchTouchEvent(evt); } return false; } - View v = findView(polar); - if (mCurrentView != v) { - onEnter(v); + PieItem item = findItem(polar); + if (mCurrentItem != item) { + onEnter(item); invalidate(); } } @@ -443,50 +276,26 @@ public class PieMenu extends FrameLayout { /** * enter a slice for a view * updates model only - * @param view + * @param item */ - private void onEnter(View view) { + private void onEnter(PieItem item) { // deselect - if (mCurrentView != null) { - if (getLevel(mCurrentView) >= getLevel(view)) { - mCurrentView.setPressed(false); - } + if (mCurrentItem != null) { + mCurrentItem.setSelected(false); } - if (view != null) { + if (item != null) { // clear up stack playSoundEffect(SoundEffectConstants.CLICK); - MenuTag tag = (MenuTag) view.getTag(); - int i = mStack.size() - 1; - while (i > 0) { - View v = mStack.get(i); - if (((MenuTag) v.getTag()).level >= tag.level) { - v.setPressed(false); - mStack.remove(i); - } else { - break; - } - i--; - } - List<View> items = mMenu.get(view); - if (items != null) { - mStack.add(view); - mDirty = true; - } - view.setPressed(true); + item.setSelected(true); } - mCurrentView = view; + mCurrentItem = item; } private void deselect() { - if (mCurrentView != null) { - mCurrentView.setPressed(false); + if (mCurrentItem != null) { + mCurrentItem.setSelected(false); } - mCurrentView = null; - } - - private int getLevel(View v) { - if (v == null) return -1; - return ((MenuTag) v.getTag()).level; + mCurrentItem = null; } private PointF getPolar(float x, float y) { @@ -510,39 +319,19 @@ public class PieMenu extends FrameLayout { /** * * @param polar x: angle, y: dist - * @return + * @return the item at angle/dist or null */ - private View findView(PointF polar) { + private PieItem findItem(PointF polar) { // find the matching item: - for (View parent : mStack) { - List<View> subs = mMenu.get(parent); - if (subs != null) { - for (View item : subs) { - MenuTag tag = (MenuTag) item.getTag(); - if ((tag.inner < polar.y) - && (tag.outer > polar.y) - && (tag.start < polar.x) - && (tag.start + tag.sweep > polar.x)) { - return item; - } - } + for (PieItem item : mItems) { + if ((item.getInnerRadius() < polar.y) + && (item.getOuterRadius() > polar.y) + && (item.getStartAngle() < polar.x) + && (item.getStartAngle() + item.getSweep() > polar.x)) { + return item; } } return null; } - class MenuTag { - - int level; - float start; - float sweep; - int inner; - int outer; - - public MenuTag(int l) { - level = l; - } - - } - } |