Context menu in progress

This commit is contained in:
Alexey Kulish 2015-09-08 15:32:42 +03:00
parent 85f604e9c1
commit 73c1664ff8
6 changed files with 325 additions and 49 deletions

View file

@ -53,8 +53,9 @@
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:orientation="vertical">
@ -79,25 +80,41 @@
android:layout_marginTop="3dp"
android:text="@string/other_location"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"/>
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>
<LinearLayout
android:id="@+id/context_menu_close_btn_layout"
android:orientation="horizontal"
android:layout_width="32dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/context_menu_close_btn_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="12dp"
android:scaleType="center"
android:src="@drawable/ic_action_remove_dark"/>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#c9c9c9"/>
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:id="@+id/context_menu_buttons"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_gravity="bottom"
android:background="@android:color/white">
android:layout_gravity="bottom">
<ImageButton
android:id="@+id/context_menu_route_button"
@ -110,9 +127,9 @@
android:src="@drawable/map_directions"/>
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#c9c9c9"/>
android:layout_width="1dp"
android:background="?attr/dashboard_divider"/>
<ImageButton
android:id="@+id/context_menu_fav_button"
@ -125,9 +142,9 @@
android:src="@drawable/ic_action_fav_dark"/>
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#c9c9c9"/>
android:layout_width="1dp"
android:background="?attr/dashboard_divider"/>
<ImageButton
android:id="@+id/context_menu_share_button"
@ -140,9 +157,9 @@
android:src="@drawable/abc_ic_menu_share_mtrl_alpha"/>
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#c9c9c9"/>
android:layout_width="1dp"
android:background="?attr/dashboard_divider"/>
<ImageButton
android:id="@+id/context_menu_more_button"
@ -155,6 +172,21 @@
android:src="@drawable/ic_action_core_overflow_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/context_menu_bottom_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,27 @@
package net.osmand.plus.mapcontextmenu;
import android.graphics.drawable.Drawable;
import android.view.View;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
public abstract class BottomSectionBuilder {
protected OsmandApplication app;
public BottomSectionBuilder(OsmandApplication app) {
this.app = app;
}
public abstract void buildSection(View view);
public Drawable getRowIcon(int iconId) {
IconsCache iconsCache = app.getIconsCache();
boolean light = app.getSettings().isLightContent();
return iconsCache.getIcon(iconId,
light ? R.color.icon_color : R.color.icon_color_light);
}
}

View file

@ -0,0 +1,166 @@
package net.osmand.plus.mapcontextmenu;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import net.osmand.data.Amenity;
import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes;
import net.osmand.osm.PoiType;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import java.util.Map;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
public class InfoSectionBuilder extends BottomSectionBuilder {
private final Amenity amenity;
public InfoSectionBuilder(OsmandApplication app, final Amenity amenity) {
super(app);
this.amenity = amenity;
}
private void buildRow(View view, int iconId, String text) {
/*
<LinearLayout
android:id="@+id/context_menu_top_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/context_menu_icon_layout"
android:orientation="horizontal"
android:layout_width="42dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/context_menu_icon_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:scaleType="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:src="@drawable/ic_action_building_number"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/context_menu_line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:text="@string/search_address_building"
android:textSize="@dimen/default_list_text_size_large"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#c9c9c9"/>
*/
LinearLayout ll = new LinearLayout(view.getContext());
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
// Icon
LinearLayout llIcon = new LinearLayout(view.getContext());
llIcon.setOrientation(LinearLayout.HORIZONTAL);
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(42f), ViewGroup.LayoutParams.MATCH_PARENT));
ll.addView(llIcon);
ImageView icon = new ImageView(view.getContext());
ViewGroup.MarginLayoutParams llIconParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
llIconParams.setMargins(dpToPx(12f), 0, 0, 0);
//llIconParams.setGravity(Gravity.CENTER_VERTICAL);
icon.setLayoutParams(llIconParams);
icon.setScaleType(ImageView.ScaleType.CENTER);
icon.setImageDrawable(getRowIcon(iconId));
llIcon.addView(icon);
// Text
LinearLayout llText = new LinearLayout(view.getContext());
llText.setOrientation(LinearLayout.VERTICAL);
ViewGroup.MarginLayoutParams llTextParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llTextParams.setMargins(0, dpToPx(4f), 0, dpToPx(4f));
llText.setLayoutParams(llTextParams);
ll.addView(llText);
TextView textView = new TextView(view.getContext());
ViewGroup.MarginLayoutParams llTextViewParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llTextViewParams.setMargins(dpToPx(10f), 0, dpToPx(10f), 0);
llText.setLayoutParams(llTextViewParams);
}
public int dpToPx(float dp) {
Resources r = app.getResources();
return (int) TypedValue.applyDimension(
COMPLEX_UNIT_DIP,
dp,
r.getDisplayMetrics()
);
}
@Override
public void buildSection(View view) {
MapPoiTypes poiTypes = app.getPoiTypes();
for(Map.Entry<String, String> e : amenity.getAdditionalInfo().entrySet()) {
int iconId = 0;
String key = e.getKey();
String vl = e.getValue();
if(key.startsWith("name:")) {
continue;
} else if(Amenity.OPENING_HOURS.equals(key)) {
iconId = R.drawable.mm_clock; // todo: change icon
} else if(Amenity.PHONE.equals(key)) {
iconId = R.drawable.mm_amenity_telephone; // todo: change icon
} else if(Amenity.WEBSITE.equals(key)) {
iconId = R.drawable.mm_internet_access; // todo: change icon
} else {
iconId = R.drawable.ic_type_info; // todo: change icon
AbstractPoiType pt = poiTypes.getAnyPoiAdditionalTypeByKey(e.getKey());
if (pt != null) {
if(pt instanceof PoiType && !((PoiType) pt).isText()) {
vl = pt.getTranslation();
} else {
vl = /*pt.getTranslation() + ": " + */amenity.unzipContent(e.getValue());
}
} else {
vl = /*Algorithms.capitalizeFirstLetterAndLowercase(e.getKey()) +
": " + */amenity.unzipContent(e.getValue());
}
}
buildRow(view, iconId, vl);
}
}
}

View file

@ -134,7 +134,7 @@ public class MapContextMenu {
res = typeName;
}
return Algorithms.isEmpty(res) ? "Address is unknown yet" : res;
return Algorithms.isEmpty(res) ? "Address is unknown yet" : res; // todo: text constant
}
public String getLocationStr() {
@ -144,6 +144,17 @@ public class MapContextMenu {
return foundStreetName;
}
public BottomSectionBuilder getBottomSectionBuilder() {
if (object != null) {
if (object instanceof Amenity) {
return new InfoSectionBuilder(app, (Amenity)object);
}
}
return null;
}
public void buttonNavigatePressed() {
mapActivity.getMapActions().showNavigationContextMenuPoint(pointDescription.getLat(), pointDescription.getLon());
}

View file

@ -126,6 +126,7 @@ public class MapContextMenuFragment extends Fragment {
}
});
// Left icon
IconsCache iconsCache = getMyApplication().getIconsCache();
boolean light = getMyApplication().getSettings().isLightContent();
@ -140,12 +141,27 @@ public class MapContextMenuFragment extends Fragment {
light ? R.color.icon_color : R.color.icon_color_light));
}
// Text line 1
TextView line1 = (TextView) view.findViewById(R.id.context_menu_line1);
line1.setText(MapContextMenu.getInstance().getAddressStr());
// Text line 2
TextView line2 = (TextView) view.findViewById(R.id.context_menu_line2);
line2.setText(MapContextMenu.getInstance().getLocationStr());
// Close button
final ImageView closeButtonView = (ImageView)view.findViewById(R.id.context_menu_close_btn_view);
closeButtonView.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_remove_dark,
light ? R.color.actionbar_dark_color : R.color.actionbar_light_color));
closeButtonView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((MapActivity)getActivity()).getMapLayers().getContextMenuLayer().hideMapContextMenuMarker();
dismissMenu();
}
});
// Action buttons
final ImageButton buttonNavigate = (ImageButton) view.findViewById(R.id.context_menu_route_button);
buttonNavigate.setImageDrawable(iconsCache.getIcon(R.drawable.map_directions,
light ? R.color.actionbar_dark_color : R.color.actionbar_light_color));
@ -186,6 +202,14 @@ public class MapContextMenuFragment extends Fragment {
}
});
// Bottom view
BottomSectionBuilder bottomSectionBuilder = MapContextMenu.getInstance().getBottomSectionBuilder();
if (bottomSectionBuilder != null) {
View bottomView = view.findViewById(R.id.context_menu_bottom_view);
bottomSectionBuilder.buildSection(bottomView);
}
/*
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.poi_create_title);

View file

@ -4,14 +4,9 @@ import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.os.Build;
import android.text.Html;
@ -35,6 +30,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class ContextMenuLayer extends OsmandMapLayer {
@ -68,6 +64,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
private LatLon latLon;
private String description;
private Map<Object, IContextMenuProvider> selectedObjects = new ConcurrentHashMap<Object, IContextMenuProvider>();
private Object selectedObj;
private TextView textView;
private ImageView closeButton;
@ -78,10 +75,8 @@ public class ContextMenuLayer extends OsmandMapLayer {
private float scaleCoefficient = 1;
private CallbackWithObject<LatLon> selectOnMap = null;
private Bitmap mapContextMarker;
private boolean showMapContextMarker;
private Paint mapMarkerPaintIcon;
private boolean showContextMarker;
private ImageView contextMarker;
public ContextMenuLayer(MapActivity activity){
this.activity = activity;
@ -130,11 +125,14 @@ public class ContextMenuLayer extends OsmandMapLayer {
closeButton.setImageDrawable(view.getResources().getDrawable(R.drawable.headliner_close));
closeButton.setClickable(true);
showMapContextMarker = false;
mapMarkerPaintIcon = new Paint();
mapMarkerPaintIcon.setColorFilter(new PorterDuffColorFilter(activity.getResources().getColor(R.color.osmand_orange), PorterDuff.Mode.SRC_IN));
mapContextMarker = BitmapFactory.decodeResource(view.getResources(), R.drawable.ic_action_marker2);
showContextMarker = false;
contextMarker = new ImageView(view.getContext());
contextMarker.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
contextMarker.setImageDrawable(view.getResources().getDrawable(R.drawable.map_pin_context_menu));
contextMarker.setClickable(true);
int minw = contextMarker.getDrawable().getMinimumWidth();
int minh = contextMarker.getDrawable().getMinimumHeight();
contextMarker.layout(0, 0, minw, minh);
if(latLon != null){
setLocation(latLon, description);
@ -153,8 +151,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
int x = (int) box.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude());
int y = (int) box.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude());
if (showMapContextMarker)
canvas.drawBitmap(mapContextMarker, x - mapContextMarker.getWidth() / 2, y - mapContextMarker.getHeight(), mapMarkerPaintIcon);
if (showContextMarker) {
canvas.translate(x - contextMarker.getWidth() / 2, y - contextMarker.getHeight());
contextMarker.draw(canvas);
}
textView.setTextColor(nightMode != null && nightMode.isNightMode() ? Color.GRAY : Color.WHITE);
if (textView.getText().length() > 0) {
@ -201,15 +201,15 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
public void showMapContextMenuMarker() {
if (!showMapContextMarker) {
showMapContextMarker = true;
if (!showContextMarker) {
showContextMarker = true;
view.refreshMap();
}
}
public void hideMapContextMenuMarker() {
if (showMapContextMarker) {
showMapContextMarker = false;
if (showContextMarker) {
showContextMarker = false;
view.refreshMap();
}
}
@ -273,11 +273,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
if (latLon != null) {
if (selectedObjects.size() == 1) {
setLocation(null, "");
Object selectedObj = selectedObjects.keySet().iterator().next();
selectedObj = selectedObjects.keySet().iterator().next();
showMapContextMenu(selectedObj, latLon);
} else {
String description = getSelectedObjectDescription();
setLocation(latLon, description);
} else if (selectedObjects.size() > 1) {
showContextMenuForSelectedObjects(latLon);
}
} else {
setLocation(null, "");
@ -363,6 +362,18 @@ public class ContextMenuLayer extends OsmandMapLayer {
return 0;
}
public boolean pressedContextMarker(RotatedTileBox tb, float px, float py) {
if (latLon != null && showContextMarker) {
Rect bs = contextMarker.getDrawable().getBounds();
int dx = (int) (px - tb.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude()));
int dy = (int) (py - tb.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude()));
int bx = dx + bs.width() / 2;
int by = dy + bs.height();
return (bs.contains(bx, by));
}
return false;
}
public String getSelectedObjectName(){
return getSelectedObjectInfo(true);
}
@ -412,6 +423,11 @@ public class ContextMenuLayer extends OsmandMapLayer {
@Override
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
if (pressedContextMarker(tileBox, point.x, point.y)) {
showMapContextMenu(selectedObj, latLon);
return true;
}
boolean nativeMode = (Build.VERSION.SDK_INT >= 14) || view.getSettings().SCROLL_MAP_BY_GESTURES.get();
int val = pressedInTextView(tileBox, point.x, point.y);
if(selectOnMap != null) {
@ -438,12 +454,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
if (latLon != null) {
if (selectedObjects.size() == 1) {
setLocation(null, "");
Object selectedObj = selectedObjects.keySet().iterator().next();
selectedObj = selectedObjects.keySet().iterator().next();
showMapContextMenu(selectedObj, latLon);
} else {
String description = getSelectedObjectDescription();
setLocation(latLon, description);
view.refreshMap();
} else if (selectedObjects.size() > 1) {
showContextMenuForSelectedObjects(latLon);
return true;
}
}
@ -467,13 +481,13 @@ public class ContextMenuLayer extends OsmandMapLayer {
builder.setItems(d, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Object selectedObj = s.get(which);
selectedObj = s.get(which);
showMapContextMenu(selectedObj, l);
}
});
builder.show();
} else {
Object selectedObj = selectedObjects.keySet().iterator().next();
selectedObj = selectedObjects.keySet().iterator().next();
showMapContextMenu(selectedObj, l);
}
}
@ -481,13 +495,15 @@ public class ContextMenuLayer extends OsmandMapLayer {
private void showMapContextMenu(Object obj, LatLon latLon) {
PointDescription pointDescription;
if (obj != null) {
pointDescription = selectedObjects.get(obj).getObjectName(obj);
pointDescription.setLat(latLon.getLatitude());
pointDescription.setLon(latLon.getLongitude());
IContextMenuProvider typedObj = selectedObjects.get(obj);
pointDescription = typedObj.getObjectName(obj);
LatLon objLocation = typedObj.getObjectLocation(obj);
pointDescription.setLat(objLocation.getLatitude());
pointDescription.setLon(objLocation.getLongitude());
} else {
pointDescription = new PointDescription(latLon.getLatitude(), latLon.getLongitude());
}
this.latLon = latLon;
this.latLon = new LatLon(pointDescription.getLat(), pointDescription.getLon());
showMapContextMenuMarker();
MapContextMenu.getInstance().show(pointDescription, obj);