package net.osmand.plus;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.AppCompatImageView;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.activities.HelpActivity;
import net.osmand.plus.activities.actions.AppModeDialog;
import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.dialogs.HelpArticleDialogFragment;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ContextMenuAdapter {
private static final Log LOG = PlatformUtil.getLog(ContextMenuAdapter.class);
@LayoutRes
private int DEFAULT_LAYOUT_ID = R.layout.list_menu_item_native;
List<ContextMenuItem> items = new ArrayList<>();
private ConfigureMapMenu.OnClickListener changeAppModeListener = null;
public int length() {
return items.size();
}
public String[] getItemNames() {
String[] itemNames = new String[items.size()];
for (int i = 0; i < items.size(); i++) {
itemNames[i] = items.get(i).getTitle();
}
return itemNames;
}
public void addItem(ContextMenuItem item) {
try {
items.add(item.getPos(), item);
} catch (IndexOutOfBoundsException ex) {
items.add(item);
}
}
public ContextMenuItem getItem(int position) {
return items.get(position);
}
public void removeItem(int position) {
items.remove(position);
}
public void setDefaultLayoutId(int defaultLayoutId) {
this.DEFAULT_LAYOUT_ID = defaultLayoutId;
}
public void setChangeAppModeListener(ConfigureMapMenu.OnClickListener changeAppModeListener) {
this.changeAppModeListener = changeAppModeListener;
}
public ArrayAdapter<ContextMenuItem> createListAdapter(final Activity activity, final boolean lightTheme) {
final int layoutId = DEFAULT_LAYOUT_ID;
final OsmandApplication app = ((OsmandApplication) activity.getApplication());
return new ContextMenuArrayAdapter(activity, layoutId, R.id.title,
items.toArray(new ContextMenuItem[items.size()]), app, lightTheme, changeAppModeListener);
}
public class ContextMenuArrayAdapter extends ArrayAdapter<ContextMenuItem> {
private OsmandApplication app;
private boolean lightTheme;
@LayoutRes
private int layoutId;
private final ConfigureMapMenu.OnClickListener changeAppModeListener;
private final IconsCache mIconsCache;
public ContextMenuArrayAdapter(Activity context,
@LayoutRes int layoutRes,
@IdRes int textViewResourceId,
ContextMenuItem[] objects,
OsmandApplication app,
boolean lightTheme,
ConfigureMapMenu.OnClickListener changeAppModeListener) {
super(context, layoutRes, textViewResourceId, objects);
this.app = app;
this.lightTheme = lightTheme;
this.layoutId = layoutRes;
this.changeAppModeListener = changeAppModeListener;
mIconsCache = app.getIconsCache();
}
@Override
public boolean isEnabled(int position) {
final ContextMenuItem item = getItem(position);
if (item != null) {
return !item.isCategory() && item.getLayout() != R.layout.drawer_divider;
}
return true;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// User super class to create the View
final ContextMenuItem item = getItem(position);
int layoutId = item.getLayout();
layoutId = layoutId != ContextMenuItem.INVALID_ID ? layoutId : DEFAULT_LAYOUT_ID;
if (layoutId == R.layout.mode_toggles) {
final Set<ApplicationMode> selected = new LinkedHashSet<>();
return AppModeDialog.prepareAppModeDrawerView((Activity) getContext(),
selected, true, new View.OnClickListener() {
@Override
public void onClick(View view) {
if (selected.size() > 0) {
app.getSettings().APPLICATION_MODE.set(selected.iterator().next());
notifyDataSetChanged();
}
if (changeAppModeListener != null) {
changeAppModeListener.onClick();
}
}
});
}
if (convertView == null || !(convertView.getTag() instanceof Integer)
|| (layoutId != (Integer) convertView.getTag())) {
int themeRes = lightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
convertView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), layoutId, null);
convertView.setTag(layoutId);
}
if (item.getMinHeight() > 0) {
convertView.setMinimumHeight(item.getMinHeight());
}
if (layoutId == R.layout.help_to_improve_item) {
TextView feedbackButton = (TextView) convertView.findViewById(R.id.feedbackButton);
Drawable pollIcon = app.getIconsCache().getThemedIcon(R.drawable.ic_action_big_poll);
feedbackButton.setCompoundDrawablesWithIntrinsicBounds(null, pollIcon, null, null);
feedbackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
HelpArticleDialogFragment
.instantiateWithUrl(HelpActivity.OSMAND_POLL_HTML, app.getString(R.string.feedback))
.show(((FragmentActivity) getContext()).getSupportFragmentManager(), null);
}
});
TextView contactUsButton = (TextView) convertView.findViewById(R.id.contactUsButton);
Drawable contactUsIcon =
app.getIconsCache().getThemedIcon(R.drawable.ic_action_big_feedback);
contactUsButton.setCompoundDrawablesWithIntrinsicBounds(null, contactUsIcon, null,
null);
final String email = app.getString(R.string.support_email);
contactUsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{email});
if (intent.resolveActivity(app.getPackageManager()) != null) {
getContext().startActivity(intent);
}
}
});
return convertView;
}
TextView tv = (TextView) convertView.findViewById(R.id.title);
if (tv != null) {
tv.setText(item.getTitle());
}
if (this.layoutId == R.layout.simple_list_menu_item) {
@ColorRes
int color = lightTheme ? R.color.icon_color : R.color.dashboard_subheader_text_dark;
Drawable drawable = item.getIcon() != ContextMenuItem.INVALID_ID
? mIconsCache.getIcon(item.getIcon(), color) : null;
if (drawable != null && tv != null) {
float density = getContext().getResources().getDisplayMetrics().density;
int paddingInPixels = (int) (24 * density);
int drawableSizeInPixels = (int) (24 * density); // 32
drawable.setBounds(0, 0, drawableSizeInPixels, drawableSizeInPixels);
tv.setCompoundDrawables(drawable, null, null, null);
tv.setCompoundDrawablePadding(paddingInPixels);
}
} else {
if (item.getIcon() != ContextMenuItem.INVALID_ID) {
int colorRes = item.getColorRes();
if (colorRes == ContextMenuItem.INVALID_ID) {
if (!item.shouldSkipPainting()) {
colorRes = lightTheme ? R.color.icon_color : R.color.color_white;
} else {
colorRes = 0;
}
}
final Drawable drawable = mIconsCache.getIcon(item.getIcon(), colorRes);
((AppCompatImageView) convertView.findViewById(R.id.icon)).setImageDrawable(drawable);
convertView.findViewById(R.id.icon).setVisibility(View.VISIBLE);
} else if (convertView.findViewById(R.id.icon) != null) {
convertView.findViewById(R.id.icon).setVisibility(View.GONE);
}
}
@DrawableRes
int secondaryDrawable = item.getSecondaryIcon();
if (secondaryDrawable != ContextMenuItem.INVALID_ID) {
@ColorRes
int colorRes;
if (secondaryDrawable == R.drawable.ic_action_additional_option) {
colorRes = lightTheme ? R.color.icon_color_light : R.color.dialog_inactive_text_color_dark;
} else {
colorRes = lightTheme ? R.color.icon_color : R.color.color_white;
}
Drawable drawable = mIconsCache.getIcon(item.getSecondaryIcon(), colorRes);
ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon);
imageView.setImageDrawable(drawable);
imageView.setVisibility(View.VISIBLE);
} else {
ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon);
if (imageView != null) {
imageView.setVisibility(View.GONE);
}
}
if (convertView.findViewById(R.id.toggle_item) != null && !item.isCategory()) {
final CompoundButton ch = (CompoundButton) convertView.findViewById(R.id.toggle_item);
if (item.getSelected() != null) {
ch.setOnCheckedChangeListener(null);
ch.setVisibility(View.VISIBLE);
ch.setChecked(item.getSelected());
final ArrayAdapter<ContextMenuItem> la = this;
final OnCheckedChangeListener listener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ItemClickListener ca = item.getItemClickListener();
item.setSelected(isChecked);
if (ca != null) {
ca.onContextMenuClick(la, item.getTitleId(), position, isChecked);
}
}
};
ch.setOnCheckedChangeListener(listener);
ch.setVisibility(View.VISIBLE);
} else if (ch != null) {
ch.setVisibility(View.GONE);
}
}
if (convertView.findViewById(R.id.seekbar) != null) {
SeekBar seekBar = (SeekBar) convertView.findViewById(R.id.seekbar);
if (item.getProgress() != ContextMenuItem.INVALID_ID) {
seekBar.setProgress(item.getProgress());
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
OnIntegerValueChangedListener listener = item.getIntegerListener();
item.setProgress(progress);
if (listener != null && fromUser) {
listener.onIntegerValueChangedListener(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
seekBar.setVisibility(View.VISIBLE);
} else if (seekBar != null) {
seekBar.setVisibility(View.GONE);
}
}
View progressBar = convertView.findViewById(R.id.ProgressBar);
if (progressBar != null) {
ProgressBar bar = (ProgressBar) progressBar;
if (item.isLoading()) {
int progress = item.getProgress();
if (progress == ContextMenuItem.INVALID_ID) {
bar.setIndeterminate(true);
} else {
bar.setIndeterminate(false);
bar.setProgress(progress);
}
bar.setVisibility(View.VISIBLE);
} else {
bar.setVisibility(View.GONE);
}
}
View descriptionTextView = convertView.findViewById(R.id.description);
if (descriptionTextView != null) {
String itemDescr = item.getDescription();
if (itemDescr != null && (progressBar == null || !item.isLoading())) {
((TextView) descriptionTextView).setText(itemDescr);
descriptionTextView.setVisibility(View.VISIBLE);
} else {
descriptionTextView.setVisibility(View.GONE);
}
}
View dividerView = convertView.findViewById(R.id.divider);
if (dividerView != null) {
if (getCount() - 1 == position || getItem(position + 1).isCategory()
|| item.shouldHideDivider()) {
dividerView.setVisibility(View.GONE);
} else {
dividerView.setVisibility(View.VISIBLE);
}
}
if (item.isCategory()) {
convertView.setFocusable(false);
convertView.setClickable(false);
}
return convertView;
}
}
public interface ItemClickListener {
//boolean return type needed to desribe if drawer needed to be close or not
boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter,
int itemId,
int position,
boolean isChecked);
}
public interface ProgressListener {
boolean onProgressChanged(Object progressObject,
int progress,
ArrayAdapter<ContextMenuItem> adapter,
int itemId,
int position);
}
public interface OnIntegerValueChangedListener {
boolean onIntegerValueChangedListener(int newValue);
}
public static abstract class OnRowItemClick implements ItemClickListener {
//boolean return type needed to describe if drawer needed to be close or not
public boolean onRowItemClick(ArrayAdapter<ContextMenuItem> adapter, View view, int itemId, int position) {
CompoundButton btn = (CompoundButton) view.findViewById(R.id.toggle_item);
if (btn != null && btn.getVisibility() == View.VISIBLE) {
btn.setChecked(!btn.isChecked());
return false;
} else {
return onContextMenuClick(adapter, itemId, position, false);
}
}
}
}