package net.osmand.core.samples.android.sample1.mapcontextmenu;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v7.view.ContextThemeWrapper;
import android.support.v7.widget.AppCompatButton;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.text.util.Linkify;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.core.samples.android.sample1.IconsCache;
import net.osmand.core.samples.android.sample1.MainActivity;
import net.osmand.core.samples.android.sample1.OsmandResources;
import net.osmand.core.samples.android.sample1.R;
import net.osmand.core.samples.android.sample1.SampleApplication;
import net.osmand.core.samples.android.sample1.data.PointDescription;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.osm.PoiCategory;
import net.osmand.util.MapUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
public class MenuBuilder {
public static final float SHADOW_HEIGHT_TOP_DP = 17f;
protected MainActivity mainActivity;
protected SampleApplication app;
protected LinkedList<PlainMenuItem> plainMenuItems;
private boolean firstRow;
protected boolean light;
private long objectId;
private LatLon latLon;
private boolean showNearestWiki = false;
protected List<Amenity> nearestWiki = new ArrayList<>();
public class PlainMenuItem {
private int iconId;
private String text;
private boolean needLinks;
private boolean url;
private OnClickListener onClickListener;
public PlainMenuItem(int iconId, String text, boolean needLinks, boolean url, OnClickListener onClickListener) {
this.iconId = iconId;
this.text = text;
this.needLinks = needLinks;
this.url = url;
this.onClickListener = onClickListener;
}
public int getIconId() {
return iconId;
}
public String getText() {
return text;
}
public boolean isNeedLinks() {
return needLinks;
}
public boolean isUrl() {
return url;
}
public OnClickListener getOnClickListener() {
return onClickListener;
}
}
public MenuBuilder(MainActivity mainActivity) {
this.mainActivity = mainActivity;
this.app = mainActivity.getMyApplication();
plainMenuItems = new LinkedList<>();
}
public LatLon getLatLon() {
return latLon;
}
public void setLatLon(LatLon objectLocation) {
this.latLon = objectLocation;
}
public boolean isShowNearestWiki() {
return showNearestWiki;
}
public void setShowNearestWiki(boolean showNearestWiki) {
this.showNearestWiki = showNearestWiki;
}
public void setShowNearestWiki(boolean showNearestWiki, long objectId) {
this.objectId = objectId;
this.showNearestWiki = showNearestWiki;
}
public void setLight(boolean light) {
this.light = light;
}
public void build(View view) {
firstRow = true;
buildNearestWikiRow(view);
if (needBuildPlainMenuItems()) {
buildPlainMenuItems(view);
}
buildInternal(view);
buildAfter(view);
}
protected void buildPlainMenuItems(View view) {
for (PlainMenuItem item : plainMenuItems) {
buildRow(view, item.getIconId(), item.getText(), 0, false, null, item.isNeedLinks(),
0, item.isUrl(), item.getOnClickListener());
}
}
protected boolean needBuildPlainMenuItems() {
return true;
}
protected void buildNearestWikiRow(View view) {
if (processNearstWiki() && nearestWiki.size() > 0) {
buildRow(view, OsmandResources.getDrawableId("ic_action_wikipedia"), app.getString("wiki_around") + " (" + nearestWiki.size()+")", 0,
true, getCollapsableWikiView(view.getContext(), true),
false, 0, false, null);
}
}
protected void buildInternal(View view) {
}
protected void buildAfter(View view) {
buildRowDivider(view, false);
}
protected boolean isFirstRow() {
return firstRow;
}
public void rowBuilt() {
firstRow = false;
}
protected View buildRow(View view, int iconId, String text, int textColor,
boolean collapsable, final View collapsableView, boolean needLinks,
int textLinesLimit, boolean isUrl, OnClickListener onClickListener) {
return buildRow(view, getRowIcon(iconId), text, textColor, collapsable, collapsableView,
needLinks, textLinesLimit, isUrl, onClickListener);
}
protected View buildRow(final View view, Drawable icon, final String text, int textColor,
boolean collapsable, final View collapsableView, boolean needLinks,
int textLinesLimit, boolean isUrl, OnClickListener onClickListener) {
if (!isFirstRow()) {
buildRowDivider(view, false);
}
LinearLayout baseView = new LinearLayout(view.getContext());
baseView.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams llBaseViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
baseView.setLayoutParams(llBaseViewParams);
LinearLayout ll = new LinearLayout(view.getContext());
ll.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ll.setLayoutParams(llParams);
ll.setBackgroundResource(resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground));
ll.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
copyToClipboard(text, view.getContext());
return true;
}
});
baseView.addView(ll);
// Icon
LinearLayout llIcon = new LinearLayout(view.getContext());
llIcon.setOrientation(LinearLayout.HORIZONTAL);
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(72f), dpToPx(48f)));
llIcon.setGravity(Gravity.CENTER_VERTICAL);
ll.addView(llIcon);
ImageView iconView = new ImageView(view.getContext());
LinearLayout.LayoutParams llIconParams = new LinearLayout.LayoutParams(dpToPx(24f), dpToPx(24f));
llIconParams.setMargins(dpToPx(16f), dpToPx(12f), dpToPx(32f), dpToPx(12f));
llIconParams.gravity = Gravity.CENTER_VERTICAL;
iconView.setLayoutParams(llIconParams);
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
iconView.setImageDrawable(icon);
llIcon.addView(iconView);
// Text
LinearLayout llText = new LinearLayout(view.getContext());
llText.setOrientation(LinearLayout.VERTICAL);
ll.addView(llText);
TextView textView = new TextView(view.getContext());
LinearLayout.LayoutParams llTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llTextParams.setMargins(0, dpToPx(8f), 0, dpToPx(8f));
textView.setLayoutParams(llTextParams);
textView.setTextSize(16);
textView.setTextColor(app.getResources().getColor(light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
if (isUrl) {
textView.setTextColor(textView.getLinkTextColors());
} else if (needLinks) {
textView.setAutoLinkMask(Linkify.ALL);
textView.setLinksClickable(true);
}
if (textLinesLimit > 0) {
textView.setMinLines(1);
textView.setMaxLines(textLinesLimit);
}
textView.setText(text);
if (textColor > 0) {
textView.setTextColor(view.getResources().getColor(textColor));
}
LinearLayout.LayoutParams llTextViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llTextViewParams.setMargins(0, 0, dpToPx(10f), 0);
llTextViewParams.gravity = Gravity.CENTER_VERTICAL;
llText.setLayoutParams(llTextViewParams);
llText.addView(textView);
final ImageView iconViewCollapse = new ImageView(view.getContext());
if (collapsable && collapsableView != null) {
// Icon
LinearLayout llIconCollapse = new LinearLayout(view.getContext());
llIconCollapse.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(40f), dpToPx(48f)));
llIconCollapse.setOrientation(LinearLayout.HORIZONTAL);
llIconCollapse.setGravity(Gravity.CENTER_VERTICAL);
ll.addView(llIconCollapse);
LinearLayout.LayoutParams llIconCollapseParams = new LinearLayout.LayoutParams(dpToPx(24f), dpToPx(24f));
llIconCollapseParams.setMargins(0, dpToPx(12f), dpToPx(32f), dpToPx(12f));
llIconCollapseParams.gravity = Gravity.CENTER_VERTICAL;
iconViewCollapse.setLayoutParams(llIconCollapseParams);
iconViewCollapse.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon(collapsableView.getVisibility() == View.GONE ?
"ic_action_arrow_down" : "ic_action_arrow_up"));
llIconCollapse.addView(iconViewCollapse);
ll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (collapsableView.getVisibility() == View.VISIBLE) {
collapsableView.setVisibility(View.GONE);
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon("ic_action_arrow_down"));
} else {
collapsableView.setVisibility(View.VISIBLE);
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon("ic_action_arrow_up"));
}
}
});
baseView.addView(collapsableView);
}
if (onClickListener != null) {
ll.setOnClickListener(onClickListener);
} else if (isUrl) {
ll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(text));
v.getContext().startActivity(intent);
}
});
}
((LinearLayout) view).addView(baseView);
rowBuilt();
return ll;
}
protected void copyToClipboard(String text, Context ctx) {
((ClipboardManager) app.getSystemService(Activity.CLIPBOARD_SERVICE)).setText(text);
Toast.makeText(ctx,
app.getString("copied_to_clipboard") + ":\n" + text,
Toast.LENGTH_SHORT).show();
}
protected void buildButtonRow(final View view, Drawable buttonIcon, String text, OnClickListener onClickListener) {
LinearLayout ll = new LinearLayout(view.getContext());
ll.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ll.setLayoutParams(llParams);
ll.setBackgroundResource(resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground));
// Empty
LinearLayout llIcon = new LinearLayout(view.getContext());
llIcon.setOrientation(LinearLayout.HORIZONTAL);
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(62f), dpToPx(58f)));
llIcon.setGravity(Gravity.CENTER_VERTICAL);
ll.addView(llIcon);
// Button
LinearLayout llButton = new LinearLayout(view.getContext());
llButton.setOrientation(LinearLayout.VERTICAL);
ll.addView(llButton);
Button buttonView = new Button(view.getContext());
LinearLayout.LayoutParams llBtnParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
buttonView.setLayoutParams(llBtnParams);
buttonView.setPadding(dpToPx(10f), 0, dpToPx(10f), 0);
buttonView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
//buttonView.setTextSize(view.getResources().getDimension(resolveAttribute(view.getContext(), R.dimen.default_desc_text_size)));
buttonView.setTextColor(view.getResources().getColor(resolveAttribute(view.getContext(), R.attr.contextMenuButtonColor)));
buttonView.setText(text);
if (buttonIcon != null) {
buttonView.setCompoundDrawablesWithIntrinsicBounds(buttonIcon, null, null, null);
buttonView.setCompoundDrawablePadding(dpToPx(8f));
}
llButton.addView(buttonView);
((LinearLayout) view).addView(ll);
ll.setOnClickListener(onClickListener);
rowBuilt();
}
protected void buildRowDivider(View view, boolean matchWidth) {
View horizontalLine = new View(view.getContext());
LinearLayout.LayoutParams llHorLineParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dpToPx(1f));
llHorLineParams.gravity = Gravity.BOTTOM;
if (!matchWidth) {
llHorLineParams.setMargins(dpToPx(72f), 0, 0, 0);
}
horizontalLine.setLayoutParams(llHorLineParams);
horizontalLine.setBackgroundColor(app.getResources().getColor(light ? R.color.ctx_menu_info_divider_light : R.color.ctx_menu_info_divider_dark));
((LinearLayout) view).addView(horizontalLine);
}
public boolean hasCustomAddressLine() {
return false;
}
public void buildCustomAddressLine(LinearLayout ll) {
}
public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl, OnClickListener onClickListener) {
plainMenuItems.add(new PlainMenuItem(iconId, text, needLinks, isUrl, onClickListener));
}
public void clearPlainMenuItems() {
plainMenuItems.clear();
}
public Drawable getRowIcon(int iconId) {
IconsCache iconsCache = app.getIconsCache();
return iconsCache.getOsmandIcon(iconId,
light ? R.color.icon_color : R.color.icon_color_light);
}
public Drawable getRowIcon(Context ctx, String fileName) {
Drawable d = OsmandResources.getBigDrawable(fileName);
if (d != null) {
d.setColorFilter(app.getResources()
.getColor(light ? R.color.icon_color : R.color.icon_color_light), PorterDuff.Mode.SRC_IN);
return d;
} else {
return null;
}
}
public int resolveAttribute(Context ctx, int attribute) {
TypedValue outValue = new TypedValue();
ctx.getTheme().resolveAttribute(attribute, outValue, true);
return outValue.resourceId;
}
public int dpToPx(float dp) {
Resources r = app.getResources();
return (int) TypedValue.applyDimension(
COMPLEX_UNIT_DIP,
dp,
r.getDisplayMetrics()
);
}
protected View getCollapsableTextView(Context context, boolean collapsed, String text) {
final TextView textView = new TextView(context);
textView.setVisibility(collapsed ? View.GONE : View.VISIBLE);
LinearLayout.LayoutParams llTextDescParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llTextDescParams.setMargins(dpToPx(72f), 0, dpToPx(40f), dpToPx(13f));
textView.setLayoutParams(llTextDescParams);
textView.setTextSize(16);
textView.setTextColor(app.getResources().getColor(light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
textView.setText(text);
return textView;
}
protected View getCollapsableWikiView(Context context, boolean collapsed) {
final LinearLayout view = new LinearLayout(context);
view.setOrientation(LinearLayout.VERTICAL);
view.setVisibility(collapsed ? View.GONE : View.VISIBLE);
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llParams.setMargins(dpToPx(68f), 0, dpToPx(12f), dpToPx(13f));
view.setLayoutParams(llParams);
for (final Amenity wiki : nearestWiki) {
AppCompatButton wikiButton = new AppCompatButton(new ContextThemeWrapper(view.getContext(), R.style.AppTheme));
LinearLayout.LayoutParams llWikiButtonParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
wikiButton.setLayoutParams(llWikiButtonParams);
wikiButton.setPadding(dpToPx(14f), 0, dpToPx(14f), 0);
wikiButton.setTextColor(app.getResources()
.getColor(light ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark));
wikiButton.setText(wiki.getName());
wikiButton.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
wikiButton.setSingleLine(true);
wikiButton.setEllipsize(TextUtils.TruncateAt.END);
wikiButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PointDescription pointDescription = MenuController.getObjectName(wiki);
mainActivity.getContextMenu().show(
new LatLon(wiki.getLocation().getLatitude(), wiki.getLocation().getLongitude()),
pointDescription, wiki);
}
});
view.addView(wikiButton);
}
return view;
}
protected boolean processNearstWiki() {
if (showNearestWiki && latLon != null) {
QuadRect rect = MapUtils.calculateLatLonBbox(
latLon.getLatitude(), latLon.getLongitude(), 250);
nearestWiki = app.getResourceManager().searchAmenities(
new BinaryMapIndexReader.SearchPoiTypeFilter() {
@Override
public boolean accept(PoiCategory type, String subcategory) {
return type.isWiki();
}
@Override
public boolean isEmpty() {
return false;
}
}, rect.top, rect.left, rect.bottom, rect.right, -1, null);
Collections.sort(nearestWiki, new Comparator<Amenity>() {
@Override
public int compare(Amenity o1, Amenity o2) {
double d1 = MapUtils.getDistance(latLon, o1.getLocation());
double d2 = MapUtils.getDistance(latLon, o2.getLocation());
return Double.compare(d1, d2);
}
});
Long id = objectId;
if (id != 0) {
for (Amenity wiki : nearestWiki) {
if (wiki.getId().equals(id)) {
nearestWiki.remove(wiki);
break;
}
}
}
return true;
}
return false;
}
}