@Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);

    // Target placement width/height. This puts the targets on the greater of the ring
    // width or the specified outer radius.
    final float placementWidth = getRingWidth();
    final float placementHeight = getRingHeight();
    float newWaveCenterX = mHorizontalInset + (mMaxTargetWidth + placementWidth) / 2;
    float newWaveCenterY = mVerticalInset + (mMaxTargetHeight + placementHeight) / 2;

    if (mInitialLayout) {
      stopAndHideWaveAnimation();
      hideTargets(false, false);
      mInitialLayout = false;
    }

    mOuterRing.setPositionX(newWaveCenterX);
    mOuterRing.setPositionY(newWaveCenterY);

    mPointCloud.setScale(mRingScaleFactor);

    mHandleDrawable.setPositionX(newWaveCenterX);
    mHandleDrawable.setPositionY(newWaveCenterY);

    updateTargetPositions(newWaveCenterX, newWaveCenterY);
    updatePointCloudPosition(newWaveCenterX, newWaveCenterY);
    updateGlowPosition(newWaveCenterX, newWaveCenterY);

    mWaveCenterX = newWaveCenterX;
    mWaveCenterY = newWaveCenterY;

    if (DEBUG) dump();
  }
 public void onAnimationEnd(Animator animator) {
   if (mNewTargetResources != 0) {
     internalSetTargetResources(mNewTargetResources);
     mNewTargetResources = 0;
     hideTargets(false, false);
   }
   mAnimatingTargets = false;
 }
 /**
  * Resets the widget to default state and cancels all animation. If animate is 'true', will
  * animate objects into place. Otherwise, objects will snap back to place.
  *
  * @param animate
  */
 public void reset(boolean animate) {
   mGlowAnimations.stop();
   mTargetAnimations.stop();
   startBackgroundAnimation(0, 0.0f);
   stopAndHideWaveAnimation();
   hideTargets(animate, false);
   hideGlow(0, 0, 0.0f, null);
   Tweener.reset();
 }
  private void doFinish() {
    final int activeTarget = mActiveTarget;
    final boolean targetHit = activeTarget != -1;

    if (targetHit) {
      if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);

      highlightSelected(activeTarget);

      // Inform listener of any active targets.  Typically only one will be active.
      hideGlow(RETURN_TO_HOME_DURATION, RETURN_TO_HOME_DELAY, 0.0f, mResetListener);
      dispatchTriggerEvent(activeTarget);
      if (!mAlwaysTrackFinger) {
        // Force ring and targets to finish animation to final expanded state
        mTargetAnimations.stop();
      }
    } else {
      // Animate handle back to the center based on current state.
      hideGlow(HIDE_ANIMATION_DURATION, 0, 0.0f, mResetListenerWithPing);
      hideTargets(true, false);
    }

    setGrabbedState(OnTriggerListener.NO_HANDLE);
  }