@Override public void onClick(View v) { if (mShare.getView() == v) { } else if (mClose.getView() == v) { mActivity.finish(); } else if (mInfo.getView() == v) { } }
/** * 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; } }
@Override public void onDraw(Canvas canvas) { float alpha = 1; if (mXFade != null) { alpha = mXFade.getValue(); } else if (mFadeIn != null) { alpha = mFadeIn.getValue(); } int state = canvas.save(); if (mFadeIn != null) { float sf = 0.9f + alpha * 0.1f; canvas.scale(sf, sf, mCenter.x, mCenter.y); } drawFocus(canvas); if (mState == STATE_FINISHING) { canvas.restoreToCount(state); return; } if ((mOpenItem == null) || (mXFade != null)) { // draw base menu for (PieItem item : mItems) { drawItem(canvas, item, alpha); } } if (mOpenItem != null) { for (PieItem inner : mOpenItem.getItems()) { drawItem(canvas, inner, (mXFade != null) ? (1 - 0.5f * alpha) : 1); } } canvas.restoreToCount(state); }
private void deselect() { if (mCurrentItem != null) { mCurrentItem.setSelected(false); } if (mOpenItem != null) { mOpenItem = null; } mCurrentItem = null; }
/** * @param polar x: angle, y: dist * @return the item at angle/dist or null */ private PieItem findItem(PointF polar) { // find the matching item: List<PieItem> items = (mOpenItem != null) ? mOpenItem.getItems() : mItems; for (PieItem item : items) { if (inside(polar, item)) { return item; } } return null; }
/** * guaranteed has center set * * @param show */ private void show(boolean show) { if (show) { mState = STATE_PIE; // ensure clean state mCurrentItem = null; mOpenItem = null; for (PieItem item : mItems) { item.setSelected(false); } layoutPie(); fadeIn(); } else { mState = STATE_IDLE; mTapMode = false; if (mXFade != null) { mXFade.cancel(); } } setVisible(show); mHandler.sendEmptyMessage(show ? MSG_OPEN : MSG_CLOSE); }
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); } }
protected void populateMenu() { mClose = makeItem(R.drawable.ic_close_window_holo_dark, 1); mInfo = makeItem(android.R.drawable.ic_menu_info_details, 1); mShare = makeItem(R.drawable.ic_share_holo_dark, 1); mOptions = makeItem(R.drawable.ic_settings_holo_dark, 1); // PieStackView stack = new PieStackView(mActivity); // stack.setLayoutListener(new OnLayoutListener() { // @Override // public void onLayout(int ax, int ay, boolean left) { // } // }); // // stack.setOnCurrentListener(mTabAdapter); // stack.setAdapter(mTabAdapter); setClickListener(this, mInfo, mShare, mClose, mOptions); // level 1 mPie.addItem(mOptions); mOptions.addItem(makeFiller()); mOptions.addItem(makeFiller()); mOptions.addItem(makeFiller()); mPie.addItem(mShare); mOptions.addItem(mClose); mPie.addItem(mInfo); }
private void drawItem(Canvas canvas, PieItem item, float alpha) { if (mState == STATE_PIE) { if (item.getPath() != null) { if (item.isSelected()) { Paint p = mSelectedPaint; int state = canvas.save(); float r = getDegrees(item.getStartAngle()); canvas.rotate(r, mCenter.x, mCenter.y); canvas.drawPath(item.getPath(), p); canvas.restoreToCount(state); } alpha = alpha * (item.isEnabled() ? 1 : 0.3f); // draw the item view item.setAlpha(alpha); item.draw(canvas); } } }
private boolean inside(PointF polar, PieItem item) { return (item.getInnerRadius() < polar.y) && (item.getStartAngle() < polar.x) && (item.getStartAngle() + item.getSweep() > polar.x) && (!mTapMode || (item.getOuterRadius() > polar.y)); }
@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; }
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; } }
protected void setClickListener(OnClickListener listener, PieItem... items) { for (PieItem item : items) { item.getView().setOnClickListener(listener); } }