Example #1
0
  @Override
  protected void onDraw(Canvas canvas) {
    final ArrayList<Cell> pattern = mPattern;
    final int count = pattern.size();

    if (patternDisplayMode == DisplayMode.Animate) {

      final int oneCycle = (count + 1) * MILLIS_PER_CIRCLE_ANIMATING;
      final int spotInCycle =
          (int) (SystemClock.elapsedRealtime() - animatingPeriodStart) % oneCycle;
      final int numCircles = spotInCycle / MILLIS_PER_CIRCLE_ANIMATING;

      clearPatternDrawLookup();
      for (int i = 0; i < numCircles; i++) {
        final Cell cell = pattern.get(i);
        cellManager.draw(cell, true);
      }

      final boolean needToUpdateInProgressPoint = numCircles > 0 && numCircles < count;

      if (needToUpdateInProgressPoint) {
        final float percentageOfNextCircle =
            ((float) (spotInCycle % MILLIS_PER_CIRCLE_ANIMATING)) / MILLIS_PER_CIRCLE_ANIMATING;

        final Cell currentCell = pattern.get(numCircles - 1);
        final float centerX = getCenterXForColumn(currentCell.getColumn());
        final float centerY = getCenterYForRow(currentCell.getRow());

        final Cell nextCell = pattern.get(numCircles);
        final float dx =
            percentageOfNextCircle * (getCenterXForColumn(nextCell.getColumn()) - centerX);
        final float dy = percentageOfNextCircle * (getCenterYForRow(nextCell.getRow()) - centerY);
        inProgressX = centerX + dx;
        inProgressY = centerY + dy;
      }
      invalidate();
    }

    final float squareWidth = this.squareWidth;
    final float squareHeight = this.squareHeight;

    float radius = (squareWidth * diameterFactor * 0.5f);
    pathPaint.setStrokeWidth(radius);

    final Path currentPath = this.currentPath;
    currentPath.rewind();

    // draw the circles
    final int paddingTop = this.paddingTop;
    final int paddingLeft = this.paddingLeft;

    for (int i = 0; i < gridSize; i++) {
      float topY = paddingTop + i * squareHeight;
      for (int j = 0; j < gridSize; j++) {
        float leftX = paddingLeft + j * squareWidth;
        drawCircle(canvas, (int) leftX, (int) topY, cellManager.isDrawn(i, j));
      }
    }

    // only the last segment of the path should be computed here
    // draw the path of the pattern (unless the user is in progress, and
    // we are in stealth mode)
    final boolean drawPath =
        (!inStealthMode && patternDisplayMode == DisplayMode.Correct
            || !inErrorStealthMode && patternDisplayMode == DisplayMode.Wrong);

    // draw the arrows associated with the path (unless the user is in
    // progress, and
    // we are in stealth mode)
    boolean oldFlag = (circlePaint.getFlags() & Paint.FILTER_BITMAP_FLAG) != 0;
    circlePaint.setFilterBitmap(true);

    if (drawPath) {
      boolean anyCircles = false;
      for (int i = 0; i < count; i++) {
        Cell cell = pattern.get(i);

        // only draw the part of the pattern stored in
        // the lookup table (this is only different in the case
        // of animation).
        if (!cellManager.isDrawn(cell)) {
          break;
        }
        anyCircles = true;

        float centerX = getCenterXForColumn(cell.getColumn());
        float centerY = getCenterYForRow(cell.getRow());
        if (i == 0) {
          currentPath.moveTo(centerX, centerY);
        } else {
          currentPath.lineTo(centerX, centerY);
        }
      }

      // add last in progress section
      if ((patternInProgress || patternDisplayMode == DisplayMode.Animate)
          && anyCircles
          && count > 1) {
        currentPath.lineTo(inProgressX, inProgressY);
      }
      canvas.drawPath(currentPath, pathPaint);
    }

    circlePaint.setFilterBitmap(oldFlag); // restore default flag
  }
Example #2
0
  @Override
  protected void onDraw(Canvas canvas) {
    final ArrayList<Cell> pattern = mPattern;
    final int count = pattern.size();
    final boolean[][] drawLookup = mPatternDrawLookup;

    if (mPatternDisplayMode == DisplayMode.Animate) {

      // figure out which circles to draw

      // + 1 so we pause on complete pattern
      final int oneCycle = (count + 1) * MILLIS_PER_CIRCLE_ANIMATING;
      final int spotInCycle =
          (int) (SystemClock.elapsedRealtime() - mAnimatingPeriodStart) % oneCycle;
      final int numCircles = spotInCycle / MILLIS_PER_CIRCLE_ANIMATING;

      clearPatternDrawLookup();
      for (int i = 0; i < numCircles; i++) {
        final Cell cell = pattern.get(i);
        drawLookup[cell.getRow()][cell.getColumn()] = true;
      }

      // figure out in progress portion of ghosting line

      final boolean needToUpdateInProgressPoint = numCircles > 0 && numCircles < count;

      if (needToUpdateInProgressPoint) {
        final float percentageOfNextCircle =
            ((float) (spotInCycle % MILLIS_PER_CIRCLE_ANIMATING)) / MILLIS_PER_CIRCLE_ANIMATING;

        final Cell currentCell = pattern.get(numCircles - 1);
        final float centerX = getCenterXForColumn(currentCell.column);
        final float centerY = getCenterYForRow(currentCell.row);

        final Cell nextCell = pattern.get(numCircles);
        final float dx = percentageOfNextCircle * (getCenterXForColumn(nextCell.column) - centerX);
        final float dy = percentageOfNextCircle * (getCenterYForRow(nextCell.row) - centerY);
        mInProgressX = centerX + dx;
        mInProgressY = centerY + dy;
      }
      // TODO: Infinite loop here...
      invalidate();
    }

    final float squareWidth = mSquareWidth;
    final float squareHeight = mSquareHeight;

    float radius = (squareWidth * mDiameterFactor * 0.5f);
    mPathPaint.setStrokeWidth(radius);

    final Path currentPath = mCurrentPath;
    currentPath.rewind();

    // draw the circles
    final int paddingTop = getPaddingTop();
    final int paddingLeft = getPaddingLeft();

    for (int i = 0; i < 3; i++) {
      float topY = paddingTop + i * squareHeight;
      // float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight / 2);
      for (int j = 0; j < 3; j++) {
        float leftX = paddingLeft + j * squareWidth;
        drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]);
      }
    }

    // TODO: the path should be created and cached every time we hit-detect a cell
    // only the last segment of the path should be computed here
    // draw the path of the pattern (unless the user is in progress, and
    // we are in stealth mode)
    final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong);

    // draw the arrows associated with the path (unless the user is in progress, and
    // we are in stealth mode)
    boolean oldFlag = (mPaint.getFlags() & Paint.FILTER_BITMAP_FLAG) != 0;
    mPaint.setFilterBitmap(true); // draw with higher quality since we render with transforms
    if (drawPath) {
      for (int i = 0; i < count - 1; i++) {
        Cell cell = pattern.get(i);
        Cell next = pattern.get(i + 1);

        // only draw the part of the pattern stored in
        // the lookup table (this is only different in the case
        // of animation).
        if (!drawLookup[next.row][next.column]) {
          break;
        }

        float leftX = paddingLeft + cell.column * squareWidth;
        float topY = paddingTop + cell.row * squareHeight;

        drawArrow(canvas, leftX, topY, cell, next);
      }
    }

    if (drawPath) {
      boolean anyCircles = false;
      for (int i = 0; i < count; i++) {
        Cell cell = pattern.get(i);

        // only draw the part of the pattern stored in
        // the lookup table (this is only different in the case
        // of animation).
        if (!drawLookup[cell.row][cell.column]) {
          break;
        }
        anyCircles = true;

        float centerX = getCenterXForColumn(cell.column);
        float centerY = getCenterYForRow(cell.row);
        if (i == 0) {
          currentPath.moveTo(centerX, centerY);
        } else {
          currentPath.lineTo(centerX, centerY);
        }
      }

      // add last in progress section
      if ((mPatternInProgress || mPatternDisplayMode == DisplayMode.Animate) && anyCircles) {
        currentPath.lineTo(mInProgressX, mInProgressY);
      }
      if (mPatternDisplayMode == DisplayMode.Wrong) {
        mPathPaint.setColor(mRedPath);
      } else {
        mPathPaint.setColor(mGreenPath);
      }
      canvas.drawPath(currentPath, mPathPaint);
    }

    mPaint.setFilterBitmap(oldFlag); // restore default flag
  }
 /**
  * Setup typeface for Paint.
  *
  * @param paint The paint
  * @param typeface The specify typeface
  */
 public static void setup(@NonNull Paint paint, @NonNull Typeface typeface) {
   paint.setFlags(paint.getFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
   paint.setTypeface(typeface);
 }