blob: 053773ce4253cb9b13ec63102c5a4690dbc3a006 [file] [log] [blame]
package net.osmand.plus.views.mapwidgets;
import android.content.Context;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.mapmarkers.DirectionIndicationDialogFragment;
import net.osmand.plus.quickaction.QuickActionListFragment;
import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.MapQuickActionLayer;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.widgets.IconPopupMenu;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class MapWidgetRegistry {
public static final String COLLAPSED_PREFIX = "+";
public static final String HIDE_PREFIX = "-";
public static final String SHOW_PREFIX = "";
public static final String SETTINGS_SEPARATOR = ";";
public static String WIDGET_NEXT_TURN = "next_turn";
public static String WIDGET_NEXT_TURN_SMALL = "next_turn_small";
public static String WIDGET_NEXT_NEXT_TURN = "next_next_turn";
public static String WIDGET_COMPASS = "compass";
public static String WIDGET_DISTANCE = "distance";
public static String WIDGET_INTERMEDIATE_DISTANCE = "intermediate_distance";
public static String WIDGET_TIME = "time";
public static String WIDGET_INTERMEDIATE_TIME = "intermediate_time";
public static String WIDGET_MAX_SPEED = "max_speed";
public static String WIDGET_SPEED = "speed";
public static String WIDGET_ALTITUDE = "altitude";
public static String WIDGET_GPS_INFO = "gps_info";
public static String WIDGET_MARKER_1 = "map_marker_1st";
public static String WIDGET_MARKER_2 = "map_marker_2nd";
public static String WIDGET_BEARING = "bearing";
public static String WIDGET_PLAIN_TIME = "plain_time";
public static String WIDGET_BATTERY = "battery";
public static String WIDGET_RULER = "ruler";
public static String WIDGET_STREET_NAME = "street_name";
private Set<MapWidgetRegInfo> leftWidgetSet = new TreeSet<>();
private Set<MapWidgetRegInfo> rightWidgetSet = new TreeSet<>();
private Map<ApplicationMode, Set<String>> visibleElementsFromSettings = new LinkedHashMap<>();
private final OsmandApplication app;
private final OsmandSettings settings;
public MapWidgetRegistry(OsmandApplication app) {
this.app = app;
this.settings = app.getSettings();
for (ApplicationMode ms : ApplicationMode.values(app)) {
String mpf = settings.MAP_INFO_CONTROLS.getModeValue(ms);
if (mpf.equals(SHOW_PREFIX)) {
visibleElementsFromSettings.put(ms, null);
} else {
LinkedHashSet<String> set = new LinkedHashSet<>();
visibleElementsFromSettings.put(ms, set);
Collections.addAll(set, mpf.split(SETTINGS_SEPARATOR));
}
}
}
public void populateStackControl(LinearLayout stack,
ApplicationMode mode, boolean left, boolean expanded) {
Set<MapWidgetRegInfo> s = left ? this.leftWidgetSet : this.rightWidgetSet;
for (MapWidgetRegInfo r : s) {
if (r.widget != null && (r.visible(mode) || r.widget.isExplicitlyVisible())) {
stack.addView(r.widget.getView());
}
}
if (expanded) {
for (MapWidgetRegInfo r : s) {
if (r.widget != null && r.visibleCollapsed(mode) && !r.widget.isExplicitlyVisible()) {
stack.addView(r.widget.getView());
}
}
}
}
public boolean hasCollapsibles(ApplicationMode mode) {
for (MapWidgetRegInfo r : leftWidgetSet) {
if (r.visibleCollapsed(mode)) {
return true;
}
}
for (MapWidgetRegInfo r : rightWidgetSet) {
if (r.visibleCollapsed(mode)) {
return true;
}
}
return false;
}
public void updateInfo(ApplicationMode mode, DrawSettings drawSettings, boolean expanded) {
update(mode, drawSettings, expanded, leftWidgetSet);
update(mode, drawSettings, expanded, rightWidgetSet);
}
private void update(ApplicationMode mode, DrawSettings drawSettings, boolean expanded, Set<MapWidgetRegInfo> l) {
for (MapWidgetRegInfo r : l) {
if (r.widget != null && (r.visible(mode) || (r.visibleCollapsed(mode) && expanded))) {
r.widget.updateInfo(drawSettings);
}
}
}
public void removeSideWidgetInternal(TextInfoWidget widget) {
Iterator<MapWidgetRegInfo> it = leftWidgetSet.iterator();
while (it.hasNext()) {
if (it.next().widget == widget) {
it.remove();
}
}
it = rightWidgetSet.iterator();
while (it.hasNext()) {
if (it.next().widget == widget) {
it.remove();
}
}
}
public <T extends TextInfoWidget> T getSideWidget(Class<T> cl) {
for (MapWidgetRegInfo ri : leftWidgetSet) {
if (cl.isInstance(ri)) {
//noinspection unchecked
return (T) ri.widget;
}
}
for (MapWidgetRegInfo ri : rightWidgetSet) {
if (cl.isInstance(ri)) {
//noinspection unchecked
return (T) ri.widget;
}
}
return null;
}
public MapWidgetRegInfo registerSideWidgetInternal(TextInfoWidget widget,
WidgetState widgetState,
String key, boolean left, int priorityOrder) {
MapWidgetRegInfo ii = new MapWidgetRegInfo(key, widget, widgetState, priorityOrder, left);
processVisibleModes(key, ii);
if (widget != null) {
widget.setContentTitle(widgetState.getMenuTitleId());
}
if (left) {
this.leftWidgetSet.add(ii);
} else {
this.rightWidgetSet.add(ii);
}
return ii;
}
public MapWidgetRegInfo registerSideWidgetInternal(TextInfoWidget widget,
@DrawableRes int drawableMenu,
String message,
String key, boolean left, int priorityOrder) {
MapWidgetRegInfo ii = new MapWidgetRegInfo(key, widget, drawableMenu,
message, priorityOrder, left);
processVisibleModes(key, ii);
if (widget != null) {
widget.setContentTitle(message);
}
if (left) {
this.leftWidgetSet.add(ii);
} else {
this.rightWidgetSet.add(ii);
}
return ii;
}
public MapWidgetRegInfo registerSideWidgetInternal(TextInfoWidget widget,
@DrawableRes int drawableMenu,
@StringRes int messageId,
String key, boolean left, int priorityOrder) {
MapWidgetRegInfo ii = new MapWidgetRegInfo(key, widget, drawableMenu,
messageId, priorityOrder, left);
processVisibleModes(key, ii);
if (widget != null) {
widget.setContentTitle(messageId);
}
if (left) {
this.leftWidgetSet.add(ii);
} else {
this.rightWidgetSet.add(ii);
}
return ii;
}
private void processVisibleModes(String key, MapWidgetRegInfo ii) {
for (ApplicationMode ms : ApplicationMode.values(app)) {
boolean collapse = ms.isWidgetCollapsible(key);
boolean def = ms.isWidgetVisible(app, key);
Set<String> set = visibleElementsFromSettings.get(ms);
if (set != null) {
if (set.contains(key)) {
def = true;
collapse = false;
} else if (set.contains(HIDE_PREFIX + key)) {
def = false;
collapse = false;
} else if (set.contains(COLLAPSED_PREFIX + key)) {
def = false;
collapse = true;
}
}
if (def) {
ii.visibleModes.add(ms);
} else if (collapse) {
ii.visibleCollapsible.add(ms);
}
}
}
private void restoreModes(Set<String> set, Set<MapWidgetRegInfo> mi, ApplicationMode mode) {
for (MapWidgetRegInfo m : mi) {
if (m.visibleModes.contains(mode)) {
set.add(m.key);
} else if (m.visibleCollapsible != null && m.visibleCollapsible.contains(mode)) {
set.add(COLLAPSED_PREFIX + m.key);
} else {
set.add(HIDE_PREFIX + m.key);
}
}
}
public boolean isVisible(String key) {
ApplicationMode mode = settings.APPLICATION_MODE.get();
Set<String> elements = visibleElementsFromSettings.get(mode);
return elements != null && (elements.contains(key) || elements.contains(COLLAPSED_PREFIX + key));
}
public void setVisibility(MapWidgetRegInfo m, boolean visible, boolean collapsed) {
ApplicationMode mode = settings.APPLICATION_MODE.get();
setVisibility(mode, m, visible, collapsed);
}
public void setVisibility(ApplicationMode mode, MapWidgetRegInfo m, boolean visible, boolean collapsed) {
defineDefaultSettingsElement(mode);
// clear everything
this.visibleElementsFromSettings.get(mode).remove(m.key);
this.visibleElementsFromSettings.get(mode).remove(COLLAPSED_PREFIX + m.key);
this.visibleElementsFromSettings.get(mode).remove(HIDE_PREFIX + m.key);
m.visibleModes.remove(mode);
m.visibleCollapsible.remove(mode);
if (visible && collapsed) {
// Set "collapsed" state
m.visibleCollapsible.add(mode);
this.visibleElementsFromSettings.get(mode).add(COLLAPSED_PREFIX + m.key);
} else if (visible) {
// Set "visible" state
m.visibleModes.add(mode);
this.visibleElementsFromSettings.get(mode).add(SHOW_PREFIX + m.key);
} else {
// Set "hidden" state
this.visibleElementsFromSettings.get(mode).add(HIDE_PREFIX + m.key);
}
saveVisibleElementsToSettings(mode);
if (m.stateChangeListener != null) {
m.stateChangeListener.run();
}
}
private void defineDefaultSettingsElement(ApplicationMode mode) {
if (this.visibleElementsFromSettings.get(mode) == null) {
LinkedHashSet<String> set = new LinkedHashSet<>();
restoreModes(set, leftWidgetSet, mode);
restoreModes(set, rightWidgetSet, mode);
this.visibleElementsFromSettings.put(mode, set);
}
}
private void saveVisibleElementsToSettings(ApplicationMode mode) {
StringBuilder bs = new StringBuilder();
for (String ks : this.visibleElementsFromSettings.get(mode)) {
bs.append(ks).append(SETTINGS_SEPARATOR);
}
settings.MAP_INFO_CONTROLS.set(bs.toString());
}
private void resetDefault(ApplicationMode mode, Set<MapWidgetRegInfo> set) {
for (MapWidgetRegInfo ri : set) {
ri.visibleCollapsible.remove(mode);
ri.visibleModes.remove(mode);
if (mode.isWidgetVisible(app, ri.key)) {
if (mode.isWidgetCollapsible(ri.key)) {
ri.visibleCollapsible.add(mode);
} else {
ri.visibleModes.add(mode);
}
}
}
}
public void resetToDefault() {
ApplicationMode appMode = settings.getApplicationMode();
resetDefault(appMode, leftWidgetSet);
resetDefault(appMode, rightWidgetSet);
resetDefaultAppearance(appMode);
this.visibleElementsFromSettings.put(appMode, null);
settings.MAP_INFO_CONTROLS.set(SHOW_PREFIX);
}
private void resetDefaultAppearance(ApplicationMode appMode) {
settings.TRANSPARENT_MAP_THEME.resetToDefault();
settings.SHOW_STREET_NAME.resetToDefault();
settings.MAP_MARKERS_MODE.resetToDefault();
}
public void addControlsAppearance(final MapActivity map, final ContextMenuAdapter cm, ApplicationMode mode) {
if (mode != ApplicationMode.DEFAULT) {
addControlId(map, cm, R.string.map_widget_top_text, settings.SHOW_STREET_NAME);
}
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.coordinates_widget, map)
.setIcon(R.drawable.ic_action_coordinates_widget)
.setSelected(settings.SHOW_COORDINATES_WIDGET.get())
.setListener(new ApearanceItemClickListener(settings.SHOW_COORDINATES_WIDGET, map)).createItem());
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_markers, map)
.setDescription(settings.MAP_MARKERS_MODE.get().toHumanString(map))
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> adapter, int itemId, final int position, boolean isChecked, int[] viewCoordinates) {
DirectionIndicationDialogFragment fragment = new DirectionIndicationDialogFragment();
fragment.setListener(new DirectionIndicationDialogFragment.DirectionIndicationFragmentListener() {
@Override
public void onMapMarkersModeChanged(boolean showDirectionEnabled) {
updateMapMarkersMode(map);
cm.getItem(position).setDescription(settings.MAP_MARKERS_MODE.get().toHumanString(map));
adapter.notifyDataSetChanged();
}
});
fragment.show(map.getSupportFragmentManager(), DirectionIndicationDialogFragment.TAG);
return false;
}
}).setLayout(R.layout.list_item_text_button).createItem());
addControlId(map, cm, R.string.map_widget_transparent, settings.TRANSPARENT_MAP_THEME);
addControlId(map, cm, R.string.show_lanes, settings.SHOW_LANES);
}
public void updateMapMarkersMode(MapActivity mapActivity) {
for (MapWidgetRegInfo info : rightWidgetSet) {
if ("map_marker_1st".equals(info.key)) {
setVisibility(info, settings.MAP_MARKERS_MODE.get().isWidgets()
&& settings.MARKERS_DISTANCE_INDICATION_ENABLED.get(), false);
} else if ("map_marker_2nd".equals(info.key)) {
setVisibility(info, settings.MAP_MARKERS_MODE.get().isWidgets()
&& settings.MARKERS_DISTANCE_INDICATION_ENABLED.get()
&& settings.DISPLAYED_MARKERS_WIDGETS_COUNT.get() == 2, false);
}
}
MapInfoLayer mil = mapActivity.getMapLayers().getMapInfoLayer();
if (mil != null) {
mil.recreateControls();
}
mapActivity.refreshMap();
}
private void addControlId(final MapActivity map, ContextMenuAdapter cm,
@StringRes int stringId, OsmandPreference<Boolean> pref) {
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(stringId, map)
.setSelected(pref.get())
.setListener(new ApearanceItemClickListener(pref, map)).createItem());
}
public static boolean distChanged(int oldDist, int dist) {
return !(oldDist != 0 && oldDist - dist < 100 && Math.abs(((float) dist - oldDist) / oldDist) < 0.01);
}
public void addControls(MapActivity map, ContextMenuAdapter cm, ApplicationMode mode) {
addQuickActionControl(map, cm, mode);
// Right panel
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_right, map)
.setCategory(true).setLayout(R.layout.list_group_title_with_switch).createItem());
addControls(map, cm, rightWidgetSet, mode);
// Left panel
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_left, map)
.setCategory(true).setLayout(R.layout.list_group_title_with_switch).createItem());
addControls(map, cm, leftWidgetSet, mode);
// Remaining items
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_appearance_rem, map)
.setCategory(true).setLayout(R.layout.list_group_title_with_switch).createItem());
addControlsAppearance(map, cm, mode);
}
public String getText(Context ctx, final ApplicationMode mode, final MapWidgetRegInfo r) {
if (r.getMessage() != null) {
return (r.visibleCollapsed(mode) ? " + " : " ") + r.getMessage();
}
return (r.visibleCollapsed(mode) ? " + " : " ") + ctx.getString(r.getMessageId());
}
public Set<MapWidgetRegInfo> getRightWidgetSet() {
return rightWidgetSet;
}
public Set<MapWidgetRegInfo> getLeftWidgetSet() {
return leftWidgetSet;
}
private void addQuickActionControl(final MapActivity mapActivity, final ContextMenuAdapter contextMenuAdapter, ApplicationMode mode) {
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_right, mapActivity)
.setCategory(true).setLayout(R.layout.list_group_empty_title_with_switch).createItem());
boolean selected = mapActivity.getMapLayers().getQuickActionRegistry().isQuickActionOn();
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder()
.setTitleId(R.string.configure_screen_quick_action, mapActivity)
.setIcon(R.drawable.map_quick_action)
.setSelected(selected)
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setSecondaryIcon( R.drawable.ic_action_additional_option)
.setListener(new ContextMenuAdapter.OnRowItemClick() {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) {
setVisibility(adapter, position, isChecked);
return false;
}
@Override
public boolean onRowItemClick(ArrayAdapter<ContextMenuItem> adapter, View view, int itemId, int position) {
int slideInAnim = R.anim.slide_in_bottom;
int slideOutAnim = R.anim.slide_out_bottom;
mapActivity.getSupportFragmentManager().beginTransaction()
.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
.add(R.id.fragmentContainer, new QuickActionListFragment(), QuickActionListFragment.TAG)
.addToBackStack(QuickActionListFragment.TAG).commitAllowingStateLoss();
return true;
}
private void setVisibility(ArrayAdapter<ContextMenuItem> adapter,
int position,
boolean visible) {
mapActivity.getMapLayers().getQuickActionRegistry().setQuickActionFabState(visible);
MapQuickActionLayer mil = mapActivity.getMapLayers().getMapQuickActionLayer();
if (mil != null) {
mil.refreshLayer();
}
ContextMenuItem item = adapter.getItem(position);
item.setSelected(visible);
item.setColorRes(visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged();
}
})
.createItem());
}
private void addControls(final MapActivity mapActivity, final ContextMenuAdapter contextMenuAdapter,
Set<MapWidgetRegInfo> groupTitle, final ApplicationMode mode) {
for (final MapWidgetRegInfo r : groupTitle) {
if (!mode.isWidgetAvailable(app, r.key)) {
continue;
}
final boolean selected = r.visibleCollapsed(mode) || r.visible(mode);
final String desc = mapActivity.getString(R.string.shared_string_collapse);
ContextMenuItem.ItemBuilder itemBuilder = new ContextMenuItem.ItemBuilder()
.setIcon(r.getDrawableMenu())
.setSelected(selected)
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setSecondaryIcon(r.widget != null ? R.drawable.ic_action_additional_option : ContextMenuItem.INVALID_ID)
.setDescription(r.visibleCollapsed(mode) ? desc : null)
.setListener(new ContextMenuAdapter.OnRowItemClick() {
@Override
public boolean onRowItemClick(final ArrayAdapter<ContextMenuItem> adapter,
final View view,
final int itemId,
final int pos) {
if (r.widget == null) {
setVisibility(adapter, pos, !r.visible(mode), false);
return false;
}
View textWrapper = view.findViewById(R.id.text_wrapper);
IconPopupMenu popup = new IconPopupMenu(view.getContext(), textWrapper);
MenuInflater inflater = popup.getMenuInflater();
final Menu menu = popup.getMenu();
inflater.inflate(R.menu.widget_visibility_menu, menu);
UiUtilities ic = app.getUIUtilities();
menu.findItem(R.id.action_show).setIcon(ic.getThemedIcon(R.drawable.ic_action_view));
menu.findItem(R.id.action_hide).setIcon(ic.getThemedIcon(R.drawable.ic_action_hide));
menu.findItem(R.id.action_collapse).setIcon(ic.getThemedIcon(R.drawable.ic_action_widget_collapse));
final int[] menuIconIds = r.getDrawableMenuIds();
final int[] menuTitleIds = r.getMessageIds();
final int[] menuItemIds = r.getItemIds();
int checkedId = r.getItemId();
boolean selected = r.visibleCollapsed(mode) || r.visible(mode);
if (menuIconIds != null && menuTitleIds != null && menuItemIds != null
&& menuIconIds.length == menuTitleIds.length && menuIconIds.length == menuItemIds.length) {
for (int i = 0; i < menuIconIds.length; i++) {
int iconId = menuIconIds[i];
int titleId = menuTitleIds[i];
int id = menuItemIds[i];
MenuItem menuItem = menu.add(R.id.single_selection_group, id, i, titleId)
.setChecked(id == checkedId);
menuItem.setIcon(menuItem.isChecked() && selected
? ic.getIcon(iconId, R.color.osmand_orange) : ic.getThemedIcon(iconId));
}
menu.setGroupCheckable(R.id.single_selection_group, true, true);
menu.setGroupVisible(R.id.single_selection_group, true);
}
popup.setOnMenuItemClickListener(
new IconPopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
int i = menuItem.getItemId();
if (i == R.id.action_show) {
setVisibility(adapter, pos, true, false);
return true;
} else if (i == R.id.action_hide) {
setVisibility(adapter, pos, false, false);
return true;
} else if (i == R.id.action_collapse) {
setVisibility(adapter, pos, true, true);
return true;
} else {
if (menuItemIds != null) {
for (int menuItemId : menuItemIds) {
if (menuItem.getItemId() == menuItemId) {
r.changeState(menuItemId);
MapInfoLayer mil = mapActivity.getMapLayers().getMapInfoLayer();
if (mil != null) {
mil.recreateControls();
}
ContextMenuItem item = adapter.getItem(pos);
item.setIcon(r.getDrawableMenu());
if (r.getMessage() != null) {
item.setTitle(r.getMessage());
} else {
item.setTitle(mapActivity.getResources().getString(r.getMessageId()));
}
adapter.notifyDataSetChanged();
return true;
}
}
}
}
return false;
}
});
popup.show();
return false;
}
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> a,
int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
setVisibility(a, pos, isChecked, false);
return false;
}
private void setVisibility(ArrayAdapter<ContextMenuItem> adapter,
int position,
boolean visible,
boolean collapsed) {
MapWidgetRegistry.this.setVisibility(r, visible, collapsed);
MapInfoLayer mil = mapActivity.getMapLayers().getMapInfoLayer();
if (mil != null) {
mil.recreateControls();
}
ContextMenuItem item = adapter.getItem(position);
item.setSelected(visible);
item.setColorRes(visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
item.setDescription(visible && collapsed ? desc : null);
adapter.notifyDataSetChanged();
}
});
if (r.getMessage() != null) {
itemBuilder.setTitle(r.getMessage());
} else {
itemBuilder.setTitleId(r.getMessageId(), mapActivity);
}
contextMenuAdapter.addItem(itemBuilder.createItem());
}
}
public static class MapWidgetRegInfo implements Comparable<MapWidgetRegInfo> {
public final TextInfoWidget widget;
@DrawableRes
private int drawableMenu;
@StringRes
private int messageId;
private String message;
private WidgetState widgetState;
public final String key;
public final boolean left;
public final int priorityOrder;
private final Set<ApplicationMode> visibleCollapsible = new LinkedHashSet<>();
private final Set<ApplicationMode> visibleModes = new LinkedHashSet<>();
private Runnable stateChangeListener = null;
public MapWidgetRegInfo(String key, TextInfoWidget widget, @DrawableRes int drawableMenu,
@StringRes int messageId, int priorityOrder, boolean left) {
this.key = key;
this.widget = widget;
this.drawableMenu = drawableMenu;
this.messageId = messageId;
this.priorityOrder = priorityOrder;
this.left = left;
}
public MapWidgetRegInfo(String key, TextInfoWidget widget, @DrawableRes int drawableMenu,
String message, int priorityOrder, boolean left) {
this.key = key;
this.widget = widget;
this.drawableMenu = drawableMenu;
this.message = message;
this.priorityOrder = priorityOrder;
this.left = left;
}
public MapWidgetRegInfo(String key, TextInfoWidget widget, WidgetState widgetState,
int priorityOrder, boolean left) {
this.key = key;
this.widget = widget;
this.widgetState = widgetState;
this.priorityOrder = priorityOrder;
this.left = left;
}
public int getDrawableMenu() {
if (widgetState != null) {
return widgetState.getMenuIconId();
} else {
return drawableMenu;
}
}
public String getMessage() {
return message;
}
public int getMessageId() {
if (widgetState != null) {
return widgetState.getMenuTitleId();
} else {
return messageId;
}
}
public int getItemId() {
if (widgetState != null) {
return widgetState.getMenuItemId();
} else {
return messageId;
}
}
public int[] getDrawableMenuIds() {
if (widgetState != null) {
return widgetState.getMenuIconIds();
} else {
return null;
}
}
public int[] getMessageIds() {
if (widgetState != null) {
return widgetState.getMenuTitleIds();
} else {
return null;
}
}
public int[] getItemIds() {
if (widgetState != null) {
return widgetState.getMenuItemIds();
} else {
return null;
}
}
public void changeState(int stateId) {
if (widgetState != null) {
widgetState.changeState(stateId);
}
}
public boolean visibleCollapsed(ApplicationMode mode) {
return visibleCollapsible.contains(mode);
}
public boolean visible(ApplicationMode mode) {
return visibleModes.contains(mode);
}
public MapWidgetRegInfo required(ApplicationMode... modes) {
Collections.addAll(visibleModes, modes);
return this;
}
public void setStateChangeListener(Runnable stateChangeListener) {
this.stateChangeListener = stateChangeListener;
}
@Override
public int hashCode() {
if (getMessage() != null) {
return getMessage().hashCode();
}
return getMessageId();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
}
MapWidgetRegInfo other = (MapWidgetRegInfo) obj;
if (getMessageId() == 0 && other.getMessageId() == 0) {
return key.equals(other.key);
}
return getMessageId() == other.getMessageId();
}
@Override
public int compareTo(@NonNull MapWidgetRegInfo another) {
if (getMessageId() == 0 && another.getMessageId() == 0) {
if (key.equals(another.key)) {
return 0;
}
} else if (getMessageId() == another.getMessageId()) {
return 0;
}
if (priorityOrder == another.priorityOrder) {
if (getMessageId() == 0 && another.getMessageId() == 0) {
return key.compareTo(key);
} else {
return getMessageId() - another.getMessageId();
}
}
return priorityOrder - another.priorityOrder;
}
}
public ContextMenuAdapter getViewConfigureMenuAdapter(final MapActivity map) {
final ContextMenuAdapter cm = new ContextMenuAdapter();
cm.setDefaultLayoutId(R.layout.list_item_icon_and_menu);
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.app_modes_choose, map)
.setLayout(R.layout.mode_toggles).createItem());
cm.setChangeAppModeListener(new ConfigureMapMenu.OnClickListener() {
@Override
public void onClick() {
map.getDashboard().updateListAdapter(getViewConfigureMenuAdapter(map));
}
});
final ApplicationMode mode = settings.getApplicationMode();
addControls(map, cm, mode);
return cm;
}
class ApearanceItemClickListener implements ContextMenuAdapter.ItemClickListener {
private MapActivity map;
private OsmandPreference<Boolean> pref;
public ApearanceItemClickListener(OsmandPreference<Boolean> pref, MapActivity map) {
this.pref = pref;
this.map = map;
}
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> a,
int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
pref.set(!pref.get());
map.updateApplicationModeSettings();
a.notifyDataSetChanged();
return false;
}
}
public static abstract class WidgetState {
private OsmandApplication ctx;
public OsmandApplication getCtx() {
return ctx;
}
public WidgetState(OsmandApplication ctx) {
this.ctx = ctx;
}
public abstract int getMenuTitleId();
public abstract int getMenuIconId();
public abstract int getMenuItemId();
public abstract int[] getMenuTitleIds();
public abstract int[] getMenuIconIds();
public abstract int[] getMenuItemIds();
public abstract void changeState(int stateId);
}
}