summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kolb <kolby@google.com>2011-03-08 13:47:38 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-03-08 13:47:38 -0800
commitd648317789ed4d73b831c3d816130792f545d721 (patch)
tree9e3901c735d0a890b8fdca90b575f4bf1f8017e5
parent3912de63b87d32905de08c91280b160f9100d3f2 (diff)
parent4975d0cab83b1a8904515ed50f3ef1c64104517f (diff)
downloadpackages_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.pngbin0 -> 1351 bytes
-rw-r--r--res/drawable-mdpi/qc_background_normal.pngbin12095 -> 59066 bytes
-rw-r--r--res/drawable/qc_item_selector.xml21
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/dimensions.xml5
-rw-r--r--src/com/android/browser/PieControl.java103
-rw-r--r--src/com/android/browser/XLargeUi.java1
-rw-r--r--src/com/android/browser/view/PieItem.java81
-rw-r--r--src/com/android/browser/view/PieMenu.java429
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
new file mode 100644
index 0000000..787984a
--- /dev/null
+++ b/res/drawable-mdpi/pie_bg_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/qc_background_normal.png b/res/drawable-mdpi/qc_background_normal.png
index 539b45d..947722d 100644
--- a/res/drawable-mdpi/qc_background_normal.png
+++ b/res/drawable-mdpi/qc_background_normal.png
Binary files differ
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;
- }
-
- }
-
}