package net.osmand.plus.views; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import net.osmand.osm.LatLon; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.Paint.Style; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.WindowManager; import android.widget.TextView; import android.widget.FrameLayout.LayoutParams; public class ContextMenuLayer implements OsmandMapLayer { public interface IContextMenuProvider { public Object getPointObject(PointF point); public LatLon getObjectLocation(Object o); public String getObjectDescription(Object o); public DialogInterface.OnClickListener getActionListener(List<String> actionsList, Object o); } private LatLon latLon; private IContextMenuProvider selectedContextProvider; private Object selectedObject; private TextView textView; private DisplayMetrics dm; private OsmandMapTileView view; private static final int BASE_TEXT_SIZE = 170; private int textSize = BASE_TEXT_SIZE; private Paint paintLightBorder; private Paint paintBlack; private RectF textBorder; private Paint paintBorder; private final MapActivity activity; public ContextMenuLayer(MapActivity activity){ this.activity = activity; } @Override public void destroyLayer() { } @Override public void initLayer(OsmandMapTileView view) { this.view = view; dm = new DisplayMetrics(); WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE); wmgr.getDefaultDisplay().getMetrics(dm); textSize = (int) (BASE_TEXT_SIZE * dm.density); paintLightBorder = new Paint(); paintLightBorder.setARGB(130, 220, 220, 220); paintLightBorder.setStyle(Style.FILL); paintBlack = new Paint(); paintBlack.setARGB(255, 0, 0, 0); paintBlack.setStyle(Style.STROKE); paintBlack.setAntiAlias(true); paintBorder = new Paint(); paintBorder.setARGB(220, 160, 160, 160); paintBorder.setStyle(Style.FILL); textView = new TextView(view.getContext()); LayoutParams lp = new LayoutParams(textSize, LayoutParams.WRAP_CONTENT); textView.setLayoutParams(lp); textView.setTextSize(16); textView.setTextColor(Color.argb(255, 0, 0, 0)); textView.setMinLines(1); // textView.setMaxLines(15); textView.setGravity(Gravity.CENTER_HORIZONTAL); textBorder = new RectF(-2, -1, textSize + 2, 0); } @Override public void onDraw(Canvas canvas, RectF latLonBounds, boolean nightMode) { if(latLon != null){ int x = view.getMapXForPoint(latLon.getLongitude()); int y = view.getMapYForPoint(latLon.getLatitude()); canvas.drawCircle(x, y, 5 * dm.density, paintBorder); canvas.drawCircle(x, y, 5 * dm.density, paintBlack); if (textView.getText().length() > 0) { x = view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude()); y = view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude()); canvas.rotate(-view.getRotate(), view.getCenterPointX(), view.getCenterPointY()); canvas.translate(x - textView.getWidth() / 2, y - textView.getHeight() - 12); int c = textView.getLineCount(); textBorder.bottom = textView.getHeight() + 2; canvas.drawRect(textBorder, paintLightBorder); canvas.drawRect(textBorder, paintBlack); textView.draw(canvas); if (c == 0) { // special case relayout after on draw method textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize() + 4) * textView.getLineCount())); view.refreshMap(); } } } } public void setLocation(LatLon loc, String description){ latLon = loc; if(latLon != null){ textView.setText(description); } else { textView.setText(""); //$NON-NLS-1$ } textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize()+4) * textView.getLineCount())); } @Override public boolean onLongPressEvent(PointF point) { if(pressedInTextView(point)){ setLocation(null, ""); //$NON-NLS-1$ view.refreshMap(); return true; } selectedContextProvider = null; selectedObject = null; for(OsmandMapLayer l : view.getLayers()){ if(l instanceof ContextMenuLayer.IContextMenuProvider){ selectedObject = ((ContextMenuLayer.IContextMenuProvider) l).getPointObject(point); if(selectedObject != null){ selectedContextProvider = (IContextMenuProvider) l; break; } } } LatLon latLon = view.getLatLonFromScreenPoint(point.x, point.y); String description = MessageFormat.format(view.getContext().getString(R.string.point_on_map), latLon.getLatitude(), latLon.getLongitude()); if(selectedObject != null){ description = selectedContextProvider.getObjectDescription(selectedObject); LatLon l = selectedContextProvider.getObjectLocation(selectedObject); if(l != null){ latLon = l; } } setLocation(latLon, description); view.refreshMap(); return true; } @Override public boolean drawInScreenPixels() { return false; } public boolean pressedInTextView(PointF point){ if(latLon != null){ int x = view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude()); int y = view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude()); if (textBorder.contains(point.x - x + textView.getWidth() / 2, point.y - y + textView.getHeight() + 8)) { return true; } } return false; } @Override public boolean onTouchEvent(PointF point) { if (pressedInTextView(point)) { if (selectedObject != null) { ArrayList<String> l = new ArrayList<String>(); OnClickListener listener = selectedContextProvider.getActionListener(l, selectedObject); activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude(), l, listener); } else { activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude()); } return true; } return false; } }