Code example for Path

Methods: addRectaddRoundRectreset

0
	// PRIVATE ==================================================================================== 
	 
	private void updateGeometry() { 
		final Rect b = getBounds();
		 
		mStrokePath.reset();
		mFillPath.reset();
		mIndicatorFillPath.reset();
		mIndicatorStrokePath.reset();
		 
		if (b.isEmpty()) {
			return; 
		} 
		 
		final boolean isHorizontal = mIndicatorDirection == IndicatorDirection.TOP
				|| mIndicatorDirection == IndicatorDirection.BOTTOM;
		final int innerCornerWidth = mCornerRadius - mStrokeWidth;
		final float sW = mStrokeWidth;
		final float iW = mIndicatorWidth;
		final float cR = mCornerRadius;
		final float iH = mIndicatorHeight;
		final float iVISO = iW * (iH + sW) / 2f / iH - iW / 2f;
		 
		mIndicatorVerticalInnerStrokeOffset = iVISO;
		 
		if (mIndicatorHeight > 0) {
			mIndicatorVerticalStrokeWidth = (float) (sW / Math.cos(Math.atan(iW / 2f / iH)));
		} 
		 
		final float iVSW = mIndicatorVerticalStrokeWidth;
		 
		final RectF outerRect = new RectF(b.left, b.top, b.right, b.bottom);
		final RectF innerRect = new RectF(b.left + sW, b.top + sW, b.right - sW, b.bottom - sW);
		float neededSpace = iW + Math.max(iVISO + Math.max(sW, cR), iVSW + cR) * 2;
		 
		// correct bubble stroke and fill rectangle so the indicator fits besides 
		if (mIndicatorWidth > 0) {
			mIndicatorHorizontalStrokeWidth = 2f * iVSW * iH / iW;
			float addOffset = iH + mIndicatorHorizontalStrokeWidth;
			 
			switch (mIndicatorDirection) {
			case LEFT:
				outerRect.left += addOffset;
				innerRect.left += addOffset;
				break; 
			 
			case RIGHT:
				outerRect.right -= addOffset;
				innerRect.right -= addOffset;
				break; 
			 
			case TOP:
				outerRect.top += addOffset;
				innerRect.top += addOffset;
				break; 
			 
			case BOTTOM:
				outerRect.bottom -= addOffset;
				innerRect.bottom -= addOffset;
				break; 
			} 
		} 
		 
		// only create indicator paths if there is room for it since the bounds might be to little 
		// and/or the corners might need the room so there's not enough room for a indicator 
		if (mIndicatorHeight > 0 && mIndicatorWidth > 0
				&& (!isHorizontal && b.height() >= neededSpace
				|| isHorizontal && b.width() >= neededSpace)) {
			// would throw an exception on indicator width == 0 
			 
			 
			// create indicator stroke and fill path based on the given direction 
			switch (mIndicatorDirection) {
			case LEFT:
				updateLeftIndicator(outerRect, innerRect);
				break; 
			 
			case RIGHT:
				// outerRect.right -= mIndicatorHeight; 
				// innerRect.right -= mIndicatorHeight; 
				// 
				// mIndicatorFillPath.moveTo(outerRect.right, outerRect.top + mStrokeWidth); 
				// mIndicatorFillPath.lineTo(outerRect.right + mIndicatorHeight, 
				// outerRect.top + mStrokeWidth + mIndicatorWidth / 2f); 
				// mIndicatorFillPath.lineTo(outerRect.right, 
				// outerRect.top + mStrokeWidth + mIndicatorWidth); 
				// mIndicatorFillPath.close(); 
				 
				break; 
			 
			case TOP:
				// outerRect.top += mIndicatorHeight; 
				// innerRect.top += mIndicatorHeight; 
				// 
				// mIndicatorFillPath.moveTo(outerRect.left + mStrokeWidth, outerRect.top); 
				// mIndicatorFillPath.lineTo(outerRect.left + mStrokeWidth + mIndicatorWidth / 2f, 
				// outerRect.top - mIndicatorHeight); 
				// mIndicatorFillPath.lineTo(outerRect.left + mStrokeWidth + mIndicatorWidth, 
				// outerRect.top); 
				// mIndicatorFillPath.close(); 
				// 
				// mIndicatorFillPath.setLastPoint(outerRect.left, outerRect.top); 
				// mIndicatorFillPath.lineTo(outerRect.left + mIndicatorHeight, 
				// outerRect.top + mStrokeWidth + mIndicatorWidth / 2f); 
				// mIndicatorFillPath.close(); 
				 
				break; 
			 
			case BOTTOM:
				// outerRect.bottom -= mIndicatorHeight; 
				// innerRect.bottom -= mIndicatorHeight; 
				// 
				// mIndicatorFillPath.moveTo(outerRect.left + mStrokeWidth, outerRect.bottom); 
				// mIndicatorFillPath.lineTo(outerRect.left + mStrokeWidth + mIndicatorWidth / 2f, 
				// outerRect.bottom + mIndicatorHeight); 
				// mIndicatorFillPath.lineTo(outerRect.left + mStrokeWidth + mIndicatorWidth, 
				// outerRect.bottom); 
				// mIndicatorFillPath.close(); 
				 
				break; 
			} 
		} 
		 
		// that's the main fill and stroke path of the bubble 
		if (mCornerRadius >= 1) {
			// create bubble rect with round corners 
			float [] outerRadius = new float [8];
			Arrays.fill(outerRadius, mCornerRadius);
			 
			mStrokePath.addRoundRect(outerRect, outerRadius, Direction.CW);
			 
			if (innerCornerWidth >= 1) {
				float [] innerRadius = new float [8];
				Arrays.fill(innerRadius, innerCornerWidth);
				 
				if (mStrokeWidth >= 1) {
					mStrokePath.addRoundRect(innerRect, innerRadius, Direction.CCW);
				} 
				 
				mFillPath.addRoundRect(innerRect, innerRadius, Direction.CW);
			} else { 
				if (mStrokeWidth >= 1) {
					mStrokePath.addRect(innerRect, Direction.CCW);
				} 
				 
				mFillPath.addRect(innerRect, Direction.CW);
			} 
		} else { 
			// create bubble without round corners 
			if (mStrokeWidth >= 1) {
				mStrokePath.addRect(outerRect, Direction.CW);
				mStrokePath.addRect(innerRect, Direction.CCW);
			} 
			 
			mFillPath.addRect(innerRect, Direction.CW);
		} 
	}