Пример #1
0
  private Item createItem(String label, float percent, int sliceColor, int itemColor) {
    Item it = new Item();
    it.mLabel = label;
    it.mItemColor = itemColor;
    it.cSliceColor = sliceColor;
    it.cPercent = percent;
    //        Log.d(TAG, "Percent for "+it.mLabel+": "+it.cPercent);

    // Calculate the highlight color. Saturate at 0xff to make sure that high values
    // don't result in aliasing.
    it.mItemHighlight =
        Color.argb(
            0xff,
            Math.min((int) (mHighlightStrength * (float) Color.red(itemColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.green(itemColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.blue(itemColor)), 0xff));

    it.cSliceHighlight =
        Color.argb(
            0xff,
            Math.min((int) (mHighlightStrength * (float) Color.red(sliceColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.green(sliceColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.blue(sliceColor)), 0xff));

    float centerX = mPieBounds.width() / 2;
    float centerY = mPieBounds.height() / 2;
    float itemW = (mPieBounds.width() / 2) * it.cPercent;
    float itemH = (mPieBounds.height() / 2) * it.cPercent;
    it.cSliceBounds = new RectF(centerX - itemW, centerY - itemH, centerX + itemW, centerY + itemH);

    return it;
  }
Пример #2
0
  /** Do all of the recalculations needed when the data array changes. */
  private void onDataChanged() {
    int angle = 360 / mData.size();
    // This is the extra degrees that cannot be equally divided by the number of sides
    int extra = 360 % mData.size();

    // When the data changes, we have to recalculate
    // all of the angles.
    int currentAngle = 0;
    for (Item it : mData) {

      // Adds the extra degrees to the last slice to ensue no gaps
      if (mData.get(mData.size() - 1).mLabel.equals(it.mLabel)) {
        it.mEndAngle = currentAngle + angle + extra;
      } else {

        it.mEndAngle = currentAngle + angle;
      }
      it.mStartAngle = currentAngle;
      currentAngle = it.mEndAngle;

      // Recalculate the gradient shaders. There are
      // three values in this gradient, even though only
      // two are necessary, in order to work around
      // a bug in certain versions of the graphics engine
      // that expects at least three values if the
      // positions array is non-null.
      //
      it.mItemShader =
          new SweepGradient(
              mPieBounds.width() / 2.0f,
              mPieBounds.height() / 2.0f,
              new int[] {
                it.mItemHighlight, it.mItemHighlight, it.mItemColor, it.mItemColor,
              },
              new float[] {
                0,
                (float) (360 - it.mEndAngle) / 360.0f,
                (float) (360 - it.mStartAngle) / 360.0f,
                1.0f
              });

      it.cSliceShader =
          new SweepGradient(
              mPieBounds.width() / 2.0f,
              mPieBounds.height() / 2.0f,
              new int[] {
                it.cSliceHighlight, it.cSliceHighlight, it.cSliceColor, it.cSliceColor,
              },
              new float[] {
                0,
                (float) (360 - it.mEndAngle) / 360.0f,
                (float) (360 - it.mStartAngle) / 360.0f,
                1.0f
              });
    }
    calcCurrentItem();
    onScrollFinished();
  }
Пример #3
0
  // Grows the cropping rectange by (dx, dy) in image space.
  void growBy(float dx, float dy) {

    if (mMaintainAspectRatio) {
      if (dx != 0) {
        dy = dx / mInitialAspectRatio;
      } else if (dy != 0) {
        dx = dy * mInitialAspectRatio;
      }
    }

    // Don't let the cropping rectangle grow too fast.
    // Grow at most half of the difference between the image rectangle and
    // the cropping rectangle.
    RectF r = new RectF(mCropRect);
    if (dx > 0F && r.width() + 2 * dx > mImageRect.width()) {
      float adjustment = (mImageRect.width() - r.width()) / 2F;
      dx = adjustment;
      if (mMaintainAspectRatio) {
        dy = dx / mInitialAspectRatio;
      }
    }
    if (dy > 0F && r.height() + 2 * dy > mImageRect.height()) {
      float adjustment = (mImageRect.height() - r.height()) / 2F;
      dy = adjustment;
      if (mMaintainAspectRatio) {
        dx = dy * mInitialAspectRatio;
      }
    }

    r.inset(-dx, -dy);

    // Don't let the cropping rectangle shrink too fast.
    final float widthCap = 25F;
    if (r.width() < widthCap) {
      r.inset(-(widthCap - r.width()) / 2F, 0F);
    }
    float heightCap = mMaintainAspectRatio ? (widthCap / mInitialAspectRatio) : widthCap;
    if (r.height() < heightCap) {
      r.inset(0F, -(heightCap - r.height()) / 2F);
    }

    // Put the cropping rectangle inside the image rectangle.
    if (r.left < mImageRect.left) {
      r.offset(mImageRect.left - r.left, 0F);
    } else if (r.right > mImageRect.right) {
      r.offset(-(r.right - mImageRect.right), 0);
    }
    if (r.top < mImageRect.top) {
      r.offset(0F, mImageRect.top - r.top);
    } else if (r.bottom > mImageRect.bottom) {
      r.offset(0F, -(r.bottom - mImageRect.bottom));
    }

    mCropRect.set(r);
    mDrawRect = computeLayout();
    mContext.invalidate();
  }
Пример #4
0
  public SVGTileProvider(File file, float dpi) throws IOException {
    mScale = Math.round(dpi + .3f); // Make it look nice on N7 (1.3 dpi)
    mDimension = BASE_TILE_SIZE * mScale;

    mPool = new TileGeneratorPool(POOL_MAX_SIZE);

    SVG svg = new SVGBuilder().readFromInputStream(new FileInputStream(file)).build();
    mSvgPicture = svg.getPicture();
    RectF limits = svg.getLimits();

    // These values map the SVG file to world coordinates.
    // See: http://stackoverflow.com/questions/21167584/google-io-2013-app-mystery-values
    mBaseMatrix = new Matrix();
    mBaseMatrix.setPolyToPoly(
        new float[] {
          0,
          0, // North-West
          limits.width(),
          0, // North-East
          limits.width(),
          limits.height() // South-East
        },
        0,
        BuildConfig.MAP_FLOORPLAN_MAPPING,
        0,
        3);
  }
Пример #5
0
 public PointF getElementCoordinates(
     float height, float width, RectF viewRect, PositionMetrics metrics) {
   float x = metrics.getXPositionMetric().getPixelValue(viewRect.width()) + viewRect.left;
   float y = metrics.getYPositionMetric().getPixelValue(viewRect.height()) + viewRect.top;
   PointF point = new PointF(x, y);
   return PixelUtils.sub(point, getAnchorOffset(width, height, metrics.getAnchor()));
 }
Пример #6
0
  public SVGTileProvider(File file, float dpi) throws IOException {
    mScale = Math.round(dpi + .3f); // Make it look nice on N7 (1.3 dpi)
    mDimension = BASE_TILE_SIZE * mScale;

    mPool = new TileGeneratorPool(POOL_MAX_SIZE);

    SVG svg = new SVGBuilder().readFromInputStream(new FileInputStream(file)).build();
    mSvgPicture = svg.getPicture();
    RectF limits = svg.getLimits();

    mBaseMatrix = new Matrix();
    mBaseMatrix.setPolyToPoly(
        new float[] {0, 0, limits.width(), 0, limits.width(), limits.height()},
        0,
        new float[] {
          40.95635986328125f, 98.94217824936158f,
          40.95730018615723f, 98.94123077396628f,
          40.95791244506836f, 98.94186019897214f
        },
        0,
        3);
  }
  @Override
  protected void onDraw(Canvas canvas) {
    float ringWidth = textHeight + 4;
    int height = getMeasuredHeight();
    int width = getMeasuredWidth();

    int px = width / 2;
    int py = height / 2;
    Point center = new Point(px, py);

    int radius = Math.min(px, py) - 2;

    RectF boundingBox =
        new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);

    RectF innerBoundingBox =
        new RectF(
            center.x - radius + ringWidth,
            center.y - radius + ringWidth,
            center.x + radius - ringWidth,
            center.y + radius - ringWidth);

    float innerRadius = innerBoundingBox.height() / 2;
    RadialGradient borderGradient =
        new RadialGradient(
            px, py, radius, borderGradientColors, borderGradientPositions, TileMode.CLAMP);

    Paint pgb = new Paint();
    pgb.setShader(borderGradient);

    Path outerRingPath = new Path();
    outerRingPath.addOval(boundingBox, Direction.CW);

    canvas.drawPath(outerRingPath, pgb);
    LinearGradient skyShader =
        new LinearGradient(
            center.x,
            innerBoundingBox.top,
            center.x,
            innerBoundingBox.bottom,
            skyHorizonColorFrom,
            skyHorizonColorTo,
            TileMode.CLAMP);

    Paint skyPaint = new Paint();
    skyPaint.setShader(skyShader);

    LinearGradient groundShader =
        new LinearGradient(
            center.x,
            innerBoundingBox.top,
            center.x,
            innerBoundingBox.bottom,
            groundHorizonColorFrom,
            groundHorizonColorTo,
            TileMode.CLAMP);

    Paint groundPaint = new Paint();
    groundPaint.setShader(groundShader);
    float tiltDegree = pitch;
    while (tiltDegree > 90 || tiltDegree < -90) {
      if (tiltDegree > 90) tiltDegree = -90 + (tiltDegree - 90);
      if (tiltDegree < -90) tiltDegree = 90 - (tiltDegree + 90);
    }

    float rollDegree = roll;
    while (rollDegree > 180 || rollDegree < -180) {
      if (rollDegree > 180) rollDegree = -180 + (rollDegree - 180);
      if (rollDegree < -180) rollDegree = 180 - (rollDegree + 180);
    }
    Path skyPath = new Path();
    skyPath.addArc(innerBoundingBox, -rollDegree, (180 + (2 * rollDegree)));
    canvas.rotate(-tiltDegree, px, py);
    canvas.drawOval(innerBoundingBox, groundPaint);
    canvas.drawPath(skyPath, skyPaint);
    canvas.drawPath(skyPath, markerPaint);
    int markWidth = radius / 3;
    int startX = center.x - markWidth;
    int endX = center.x + markWidth;

    Log.d("PAARV ", "Roll " + String.valueOf(rollDegree));
    Log.d("PAARV ", "Pitch " + String.valueOf(tiltDegree));

    double h = innerRadius * Math.cos(Math.toRadians(90 - tiltDegree));
    double justTiltX = center.x - h;

    float pxPerDegree = (innerBoundingBox.height() / 2) / 45f;
    for (int i = 90; i >= -90; i -= 10) {
      double ypos = justTiltX + i * pxPerDegree;

      if ((ypos < (innerBoundingBox.top + textHeight))
          || (ypos > innerBoundingBox.bottom - textHeight)) continue;

      canvas.drawLine(startX, (float) ypos, endX, (float) ypos, markerPaint);
      int displayPos = (int) (tiltDegree - i);
      String displayString = String.valueOf(displayPos);
      float stringSizeWidth = textPaint.measureText(displayString);
      canvas.drawText(
          displayString, (int) (center.x - stringSizeWidth / 2), (int) (ypos) + 1, textPaint);
    }
    markerPaint.setStrokeWidth(2);
    canvas.drawLine(
        center.x - radius / 2,
        (float) justTiltX,
        center.x + radius / 2,
        (float) justTiltX,
        markerPaint);
    markerPaint.setStrokeWidth(1);

    Path rollArrow = new Path();
    rollArrow.moveTo(center.x - 3, (int) innerBoundingBox.top + 14);
    rollArrow.lineTo(center.x, (int) innerBoundingBox.top + 10);
    rollArrow.moveTo(center.x + 3, innerBoundingBox.top + 14);
    rollArrow.lineTo(center.x, innerBoundingBox.top + 10);
    canvas.drawPath(rollArrow, markerPaint);
    String rollText = String.valueOf(rollDegree);
    double rollTextWidth = textPaint.measureText(rollText);
    canvas.drawText(
        rollText,
        (float) (center.x - rollTextWidth / 2),
        innerBoundingBox.top + textHeight + 2,
        textPaint);
    canvas.restore();

    canvas.save();
    canvas.rotate(180, center.x, center.y);
    for (int i = -180; i < 180; i += 10) {
      if (i % 30 == 0) {
        String rollString = String.valueOf(i * -1);
        float rollStringWidth = textPaint.measureText(rollString);
        PointF rollStringCenter =
            new PointF(center.x - rollStringWidth / 2, innerBoundingBox.top + 1 + textHeight);
        canvas.drawText(rollString, rollStringCenter.x, rollStringCenter.y, textPaint);
      } else {
        canvas.drawLine(
            center.x,
            (int) innerBoundingBox.top,
            center.x,
            (int) innerBoundingBox.top + 5,
            markerPaint);
      }

      canvas.rotate(10, center.x, center.y);
    }
    canvas.restore();
    canvas.save();
    canvas.rotate(-1 * (bearing), px, py);

    double increment = 22.5;

    for (double i = 0; i < 360; i += increment) {
      CompassDirection cd = CompassDirection.values()[(int) (i / 22.5)];
      String headString = cd.toString();

      float headStringWidth = textPaint.measureText(headString);
      PointF headStringCenter =
          new PointF(center.x - headStringWidth / 2, boundingBox.top + 1 + textHeight);

      if (i % increment == 0)
        canvas.drawText(headString, headStringCenter.x, headStringCenter.y, textPaint);
      else
        canvas.drawLine(
            center.x, (int) boundingBox.top, center.x, (int) boundingBox.top + 3, markerPaint);

      canvas.rotate((int) increment, center.x, center.y);
    }
    canvas.restore();
    RadialGradient glassShader =
        new RadialGradient(
            px, py, (int) innerRadius, glassGradientColors, glassGradientPositions, TileMode.CLAMP);
    Paint glassPaint = new Paint();
    glassPaint.setShader(glassShader);

    canvas.drawOval(innerBoundingBox, glassPaint);
    canvas.drawOval(boundingBox, circlePaint);

    circlePaint.setStrokeWidth(2);
    canvas.drawOval(innerBoundingBox, circlePaint);

    canvas.restore();
  }
Пример #8
0
 private int calcY(float y) {
   RectF r = mPlotBounds;
   return Math.round(r.top + r.height() * (1 - (y - getYMin()) / (getYMax() - getYMin())));
 }
Пример #9
0
 public static PointF getAnchorCoordinates(RectF widgetRect, Anchor anchor) {
   return PixelUtils.add(
       new PointF(widgetRect.left, widgetRect.top),
       getAnchorOffset(widgetRect.width(), widgetRect.height(), anchor));
 }
Пример #10
0
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    Log.d(TAG, "Slice Count: " + mData.size());
    if (mData.size() > 0) {
      //
      // Set dimensions for text, pie chart, etc
      //
      // Account for padding
      float xpad = (float) (getPaddingLeft() + getPaddingRight());
      float ypad = (float) (getPaddingTop() + getPaddingBottom());

      // Account for the label
      if (mShowText) xpad += mTextWidth;

      float ww = (float) w - xpad;
      float hh = (float) h - ypad;

      // Figure out how big we can make the pie.
      float diameter = Math.min(ww, hh);
      mPieBounds = new RectF(0.0f, 0.0f, diameter, diameter);
      mPieBounds.offsetTo(getPaddingLeft(), getPaddingTop());
      //	        Log.d(TAG, "mPieBounds>> "+mPieBounds);

      mPointerY = mTextY - (mTextHeight / 2.0f);
      float pointerOffset = mPieBounds.centerY() - mPointerY;

      // Make adjustments based on text position
      if (mTextPos == TEXTPOS_LEFT) {
        mTextPaint.setTextAlign(Paint.Align.RIGHT);
        if (mShowText) mPieBounds.offset(mTextWidth, 0.0f);
        mTextX = mPieBounds.left;

        if (pointerOffset < 0) {
          pointerOffset = -pointerOffset;
          mCurrentItemAngle = 225;
        } else {
          mCurrentItemAngle = 135;
        }
        mPointerX = mPieBounds.centerX() - pointerOffset;
      } else {
        mTextPaint.setTextAlign(Paint.Align.LEFT);
        mTextX = mPieBounds.right;

        if (pointerOffset < 0) {
          pointerOffset = -pointerOffset;
          mCurrentItemAngle = 315;
        } else {
          mCurrentItemAngle = 45;
        }
        mPointerX = mPieBounds.centerX() + pointerOffset;
      }

      mShadowBounds =
          new RectF(
              mPieBounds.left + 10,
              mPieBounds.bottom + 10,
              mPieBounds.right - 10,
              mPieBounds.bottom + 20);

      // Lay out the child view that actually draws the pie.
      mPieView.layout(
          (int) mPieBounds.left,
          (int) mPieBounds.top,
          (int) mPieBounds.right,
          (int) mPieBounds.bottom);
      mPieView.setPivot(mPieBounds.width() / 2, mPieBounds.height() / 2);

      mPointerView.layout(0, 0, w, h);
      onDataChanged();
    }
  }