/** * enter a slice for a view updates model only * * @param item */ private void onEnter(PieItem item) { if (mCurrentItem != null) { mCurrentItem.setSelected(false); } if (item != null && item.isEnabled()) { item.setSelected(true); mCurrentItem = item; if ((mCurrentItem != mOpenItem) && mCurrentItem.hasItems()) { openCurrentItem(); } } else { mCurrentItem = null; } }
private void openCurrentItem() { if ((mCurrentItem != null) && mCurrentItem.hasItems()) { mCurrentItem.setSelected(false); mOpenItem = mCurrentItem; mOpening = true; mXFade = new LinearAnimation(1, 0); mXFade.setDuration(PIE_XFADE_DURATION); mXFade.setAnimationListener( new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { mXFade = null; } @Override public void onAnimationRepeat(Animation animation) {} }); mXFade.startNow(); mOverlay.startAnimation(mXFade); } }
private void layoutItems(List<PieItem> items, float centerAngle, int inner, int outer, int gap) { float emptyangle = PIE_SWEEP / 16; float sweep = (float) (PIE_SWEEP - 2 * emptyangle) / items.size(); float angle = centerAngle - PIE_SWEEP / 2 + emptyangle + sweep / 2; // check if we have custom geometry // first item we find triggers custom sweep for all // this allows us to re-use the path for (PieItem item : items) { if (item.getCenter() >= 0) { sweep = item.getSweep(); break; } } Path path = makeSlice(getDegrees(0) - gap, getDegrees(sweep) + gap, outer, inner, mCenter); for (PieItem item : items) { // shared between items item.setPath(path); if (item.getCenter() >= 0) { angle = item.getCenter(); } int w = item.getIntrinsicWidth(); int h = item.getIntrinsicHeight(); // move views to outer border int r = inner + (outer - inner) * 2 / 3; int x = (int) (r * Math.cos(angle)); int y = mCenter.y - (int) (r * Math.sin(angle)) - h / 2; x = mCenter.x + x - w / 2; item.setBounds(x, y, x + w, y + h); float itemstart = angle - sweep / 2; item.setGeometry(itemstart, sweep, inner, outer); if (item.hasItems()) { layoutItems(item.getItems(), angle, inner, outer + mRadiusInc / 2, gap); } angle += sweep; } }
@Override public boolean onTouchEvent(MotionEvent evt) { float x = evt.getX(); float y = evt.getY(); int action = evt.getActionMasked(); PointF polar = getPolar(x, y, !(mTapMode)); if (MotionEvent.ACTION_DOWN == action) { mDown.x = (int) evt.getX(); mDown.y = (int) evt.getY(); mOpening = false; if (mTapMode) { PieItem item = findItem(polar); if ((item != null) && (mCurrentItem != item)) { mState = STATE_PIE; onEnter(item); } } else { setCenter((int) x, (int) y); show(true); } return true; } else if (MotionEvent.ACTION_UP == action) { if (isVisible()) { PieItem item = mCurrentItem; if (mTapMode) { item = findItem(polar); if (item != null && mOpening) { mOpening = false; return true; } } if (item == null) { mTapMode = false; show(false); } else if (!mOpening && !item.hasItems()) { item.performClick(); startFadeOut(); mTapMode = false; } return true; } } else if (MotionEvent.ACTION_CANCEL == action) { if (isVisible() || mTapMode) { show(false); } deselect(); return false; } else if (MotionEvent.ACTION_MOVE == action) { if (polar.y < mRadius) { if (mOpenItem != null) { mOpenItem = null; } else { deselect(); } return false; } PieItem item = findItem(polar); boolean moved = hasMoved(evt); if ((item != null) && (mCurrentItem != item) && (!mOpening || moved)) { // only select if we didn't just open or have moved past slop mOpening = false; if (moved) { // switch back to swipe mode mTapMode = false; } onEnter(item); } } return false; }