@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();
  }
 /**
  * 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();
 }