package net.osmand.plus.views.mapwidgets; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopTextView; import net.osmand.plus.views.TurnPathHelper; import net.osmand.router.TurnType; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.text.TextPaint; public class NextTurnInfoWidget extends TextInfoWidget { protected boolean horisontalMini; protected int deviatedPath = 0; protected int nextTurnDistance = 0; private TurnDrawable turnDrawable; private OsmandApplication app; public NextTurnInfoWidget(Activity activity, OsmandApplication app, boolean horisontalMini) { super(activity); this.app = app; this.horisontalMini = horisontalMini; turnDrawable = new TurnDrawable(activity, horisontalMini); if(horisontalMini) { setImageDrawable(turnDrawable, false); setTopImageDrawable(null, null); } else { setImageDrawable(null, true); setTopImageDrawable(turnDrawable, ""); } } public TurnType getTurnType() { return turnDrawable.turnType; } public void setTurnType(TurnType turnType) { boolean vis = updateVisibility(turnType != null); if (turnDrawable.setTurnType(turnType) || vis) { turnDrawable.setTextPaint(topTextView.getPaint()); if(horisontalMini) { setImageDrawable(turnDrawable, false); } else { setTopImageDrawable(turnDrawable, ""); // setTopImageDrawable(turnDrawable, turnType == null || turnType.getExitOut() == 0 ? "" : // turnType.getExitOut() + ""); } } } public void setTurnImminent(int turnImminent, boolean deviatedFromRoute) { if(turnDrawable.turnImminent != turnImminent || turnDrawable.deviatedFromRoute != deviatedFromRoute) { turnDrawable.setTurnImminent(turnImminent, deviatedFromRoute); } } public void setDeviatePath(int deviatePath) { if (RouteInfoWidgetsFactory.distChanged(deviatePath, this.deviatedPath)) { this.deviatedPath = deviatePath; updateDistance(); } } public void setTurnDistance(int nextTurnDistance) { if (RouteInfoWidgetsFactory.distChanged(nextTurnDistance, this.nextTurnDistance)) { this.nextTurnDistance = nextTurnDistance; updateDistance(); } } private void updateDistance() { int deviatePath = turnDrawable.deviatedFromRoute ? deviatedPath : nextTurnDistance; String ds = OsmAndFormatter.getFormattedDistance(deviatePath, app); if (ds != null) { TurnType turnType = getTurnType(); RoutingHelper routingHelper = app.getRoutingHelper(); if ((turnType != null) && (routingHelper != null)) { setContentDescription(ds + " " + routingHelper.getRoute().toString(turnType, app, false)); } else { setContentDescription(ds); } } int ls = ds.lastIndexOf(' '); if (ls == -1) { setTextNoUpdateVisibility(ds, null); } else { setTextNoUpdateVisibility(ds.substring(0, ls), ds.substring(ls + 1)); } } @Override public boolean updateInfo(DrawSettings drawSettings) { return false; } public static class TurnDrawable extends Drawable { protected Paint paintBlack; protected Paint paintRouteDirection; protected Path pathForTurn = new Path(); protected Path pathForTurnOutlay = new Path(); protected TurnType turnType = null; protected int turnImminent; protected boolean deviatedFromRoute; private Context ctx; private boolean mini; private PointF centerText; private TextPaint textPaint; private int clr; public TurnDrawable(Context ctx, boolean mini) { this.ctx = ctx; this.mini = mini; centerText = new PointF(); paintBlack = new Paint(); paintBlack.setStyle(Style.STROKE); paintBlack.setColor(Color.BLACK); paintBlack.setAntiAlias(true); paintBlack.setStrokeWidth(2.5f); paintRouteDirection = new Paint(); paintRouteDirection.setStyle(Style.FILL); paintRouteDirection.setAntiAlias(true); setColor(R.color.nav_arrow); } @ColorRes public void setColor(int clr) { if(clr != this.clr) { this.clr = clr; paintRouteDirection.setColor(ctx.getResources().getColor(clr)); } } @Override protected void onBoundsChange(Rect bounds) { Matrix m = new Matrix(); float scaleX = bounds.width() / 72f; float scaleY = bounds.height() / 72f; m.setScale(scaleX, scaleY); pathForTurn.transform(m, pathForTurn); centerText.x = scaleX * centerText.x; centerText.y = scaleY * centerText.y; pathForTurnOutlay.transform(m, pathForTurnOutlay); } public void setTurnImminent(int turnImminent, boolean deviatedFromRoute) { //if user deviates from route that we should draw grey arrow this.turnImminent = turnImminent; this.deviatedFromRoute = deviatedFromRoute; if (deviatedFromRoute){ paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow_distant)); } else if (turnImminent > 0) { paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow)); } else if (turnImminent == 0) { paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow_imminent)); } else { paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow_distant)); } invalidateSelf(); } @Override public void draw(Canvas canvas) { /// small indent // canvas.translate(0, 3 * scaleCoefficient); canvas.drawPath(pathForTurnOutlay, paintBlack); canvas.drawPath(pathForTurn, paintRouteDirection); canvas.drawPath(pathForTurn, paintBlack); if(textPaint != null ) { if (turnType != null && !mini && turnType.getExitOut() > 0) { canvas.drawText(turnType.getExitOut() + "", centerText.x, centerText.y - textPaint.ascent() / 2, textPaint); } } } public void setTextPaint(TextPaint textPaint) { this.textPaint = textPaint; this.textPaint.setTextAlign(Align.CENTER); } @Override public void setAlpha(int alpha) { paintRouteDirection.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { paintRouteDirection.setColorFilter(cf); } @Override public int getOpacity() { return 0; } public boolean setTurnType(TurnType turnType) { if(turnType != this.turnType) { this.turnType = turnType; TurnPathHelper.calcTurnPath(pathForTurn, pathForTurnOutlay, turnType, null, centerText, mini); onBoundsChange(getBounds()); return true; } return false; } } }