com.mapbox.mapboxsdk.annotations.Bubble Maven / Gradle / Ivy
package com.mapbox.mapboxsdk.annotations;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
class Bubble extends Drawable {
private RectF rect;
private float arrowWidth;
private float arrowHeight;
private float arrowPosition;
private float cornersRadius;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float strokeWidth;
private Paint strokePaint;
private Path strokePath;
private Path path = new Path();
Bubble(RectF rect, ArrowDirection arrowDirection, float arrowWidth, float arrowHeight, float arrowPosition,
float cornersRadius, int bubbleColor, float strokeWidth, int strokeColor) {
this.rect = rect;
this.arrowWidth = arrowWidth;
this.arrowHeight = arrowHeight;
this.arrowPosition = arrowPosition;
this.cornersRadius = cornersRadius;
paint.setColor(bubbleColor);
this.strokeWidth = strokeWidth;
if (strokeWidth > 0) {
strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
strokePaint.setColor(strokeColor);
strokePath = new Path();
initPath(arrowDirection, path, strokeWidth);
initPath(arrowDirection, strokePath, 0);
} else {
initPath(arrowDirection, path, 0);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
}
@Override
public void draw(Canvas canvas) {
if (strokeWidth > 0) {
canvas.drawPath(strokePath, strokePaint);
}
canvas.drawPath(path, paint);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
@Override
public int getIntrinsicWidth() {
return (int) rect.width();
}
@Override
public int getIntrinsicHeight() {
return (int) rect.height();
}
private void initPath(ArrowDirection arrowDirection, Path path, float strokeWidth) {
switch (arrowDirection.getValue()) {
case ArrowDirection.LEFT:
if (cornersRadius <= 0) {
initLeftSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initLeftSquarePath(rect, path, strokeWidth);
break;
}
initLeftRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.TOP:
if (cornersRadius <= 0) {
initTopSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initTopSquarePath(rect, path, strokeWidth);
break;
}
initTopRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.RIGHT:
if (cornersRadius <= 0) {
initRightSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initRightSquarePath(rect, path, strokeWidth);
break;
}
initRightRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.BOTTOM:
if (cornersRadius <= 0) {
initBottomSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initBottomSquarePath(rect, path, strokeWidth);
break;
}
initBottomRoundedPath(rect, path, strokeWidth);
break;
}
}
private void initLeftSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(arrowWidth + rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2));
path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initLeftRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(arrowWidth + rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.top + strokeWidth, rect.right - strokeWidth,
cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius,
rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + cornersRadius + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left + arrowWidth, rect.bottom - strokeWidth), 90, 90);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2));
path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left + arrowWidth, cornersRadius + rect.top), 180, 90);
path.close();
}
private void initTopSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.close();
}
private void initTopRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + Math.min(arrowPosition, cornersRadius) + strokeWidth, rect.top + arrowHeight
+ strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - cornersRadius - strokeWidth, rect.top + arrowHeight + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius,
rect.top + arrowHeight + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top + arrowHeight),
270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius,
rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + cornersRadius + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90);
path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top + arrowHeight), 180, 90);
path.close();
}
private void initRightSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - arrowWidth - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2));
path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initRightRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - arrowWidth - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth,
rect.top + strokeWidth, rect.right - arrowWidth - strokeWidth, cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2));
path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth, rect.bottom - cornersRadius,
rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top), 180, 90);
path.close();
}
private void initBottomSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initBottomRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius,
rect.top + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius - arrowHeight,
rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + Math.min(cornersRadius, arrowPosition) + strokeWidth, rect.bottom - arrowHeight
- strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius - arrowHeight,
cornersRadius + rect.left, rect.bottom - arrowHeight - strokeWidth), 90, 90);
path.lineTo(rect.left + strokeWidth, rect.top + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top), 180, 90);
path.close();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy