Switching widgets mode on Configure screen in progress

This commit is contained in:
Alexey Kulish 2016-04-19 23:36:06 +03:00
parent f4c2efa155
commit 5330409b5e
10 changed files with 330 additions and 58 deletions

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_show"
android:icon="@drawable/ic_action_view"
android:title="@string/shared_string_show"/>
<item
android:id="@+id/action_hide"
android:icon="@drawable/ic_action_hide"
android:title="@string/shared_string_hide"/>
<item
android:id="@+id/action_collapse"
android:icon="@drawable/ic_action_widget_collapse"
android:title="@string/shared_string_collapse"/>
</menu>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/single_selection_group"
android:orderInCategory="1"
android:checkableBehavior="single"
android:menuCategory="alternative"
android:visible="false">
</group>
<group
android:id="@+id/button_group"
android:orderInCategory="2"
android:checkableBehavior="none">
<item
android:id="@+id/action_show"
android:icon="@drawable/ic_action_view"
android:title="@string/shared_string_show"/>
<item
android:id="@+id/action_hide"
android:icon="@drawable/ic_action_hide"
android:title="@string/shared_string_hide"/>
<item
android:id="@+id/action_collapse"
android:icon="@drawable/ic_action_widget_collapse"
android:title="@string/shared_string_collapse"/>
</group>
</menu>

View file

@ -1,4 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="index_item" type="id"/>
<!-- Bearing widget ids-->
<item name="bearing_widget_state_relative_bearing" type="id"/>
<item name="bearing_widget_state_magnetic_bearing" type="id"/>
<!-- Time control widget ids-->
<item name="time_control_widget_state_arrival_time" type="id"/>
<item name="time_control_widget_state_time_to_go" type="id"/>
</resources>

View file

@ -10,6 +10,7 @@
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
<string name="map_widget_magnetic_bearing">Magnetic bearing</string>
<string name="map_widget_bearing">Relative bearing</string>
<string name="access_disable_offroute_recalc">Don\'t change route when you are off the way</string>
<string name="access_disable_offroute_recalc_descr">Prevent automatic route recalculation when you are quite far from the right way</string>

View file

@ -16,7 +16,7 @@ public class ContextMenuItem {
private final int titleId;
private String title;
@DrawableRes
private final int mIcon;
private int mIcon;
@ColorRes
private int colorRes;
@DrawableRes
@ -150,6 +150,10 @@ public class ContextMenuItem {
this.title = title;
}
public void setIcon(int iconId) {
this.mIcon = iconId;
}
public void setColorRes(int colorRes) {
this.colorRes = colorRes;
}

View file

@ -79,14 +79,6 @@ public class IconsCache {
return getDrawable(id, light ? R.color.icon_color : 0);
}
public void paintMenuItem(MenuItem menuItem) {
Drawable drawable = menuItem.getIcon();
drawable = DrawableCompat.wrap(drawable);
drawable.mutate();
int color = ContextCompat.getColor(app, getDefaultColorRes(app));
DrawableCompat.setTint(drawable, color);
}
@ColorRes
public static int getDefaultColorRes(Context context) {
final OsmandApplication app = (OsmandApplication) context.getApplicationContext();

View file

@ -965,8 +965,11 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
}
public void refreshContent(boolean force) {
if (visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.MAP_MARKERS
|| visibleType == DashboardType.MAP_MARKERS_SELECTION || force) {
if (visibleType == DashboardType.WAYPOINTS
|| visibleType == DashboardType.MAP_MARKERS
|| visibleType == DashboardType.MAP_MARKERS_SELECTION
|| visibleType == DashboardType.CONFIGURE_SCREEN
|| force) {
updateListAdapter();
} else if (visibleType == DashboardType.CONFIGURE_MAP || visibleType == DashboardType.ROUTE_PREFERENCES) {
int index = listView.getFirstVisiblePosition();

View file

@ -21,11 +21,14 @@ import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopTextView;
import net.osmand.plus.views.mapwidgets.MapMarkersWidgetsFactory;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WidgetState;
import net.osmand.plus.views.mapwidgets.NextTurnInfoWidget;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory.AlarmWidget;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory.BearingWidgetState;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory.LanesControl;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory.RulerWidget;
import net.osmand.plus.views.mapwidgets.RouteInfoWidgetsFactory.TimeControlWidgetState;
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
import java.lang.reflect.Field;
@ -82,6 +85,11 @@ public class MapInfoLayer extends OsmandMapLayer {
updateReg(calculateTextState(), reg);
}
public void registerSideWidget(TextInfoWidget widget, WidgetState widgetState, String key, boolean left, int priorityOrder) {
MapWidgetRegInfo reg = mapInfoControls.registerSideWidgetInternal(widget, widgetState, key, left, priorityOrder);
updateReg(calculateTextState(), reg);
}
public <T extends TextInfoWidget> T getSideWidget(Class<T> cl) {
return mapInfoControls.getSideWidget(cl);
}
@ -120,9 +128,9 @@ public class MapInfoLayer extends OsmandMapLayer {
TextInfoWidget dist = ric.createDistanceControl(map);
registerSideWidget(dist, R.drawable.ic_action_target, R.string.map_widget_distance, "distance", false, 5);
TextInfoWidget time = ric.createTimeControl(map);
registerSideWidget(time, R.drawable.ic_action_time, R.string.map_widget_time, "time", false, 10);
registerSideWidget(time, new TimeControlWidgetState(app), "time", false, 10);
TextInfoWidget bearing = ric.createBearingControl(map);
registerSideWidget(bearing, R.drawable.ic_action_bearing, R.string.map_widget_bearing, "bearing", false, 11);
registerSideWidget(bearing, new BearingWidgetState(app), "bearing", false, 11);
if (settings.USE_MAP_MARKERS.get()) {
TextInfoWidget marker = mwf.createMapMarkerControl(map, true);

View file

@ -6,6 +6,7 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
@ -16,6 +17,7 @@ import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.MapMarkersMode;
import net.osmand.plus.OsmandSettings.OsmandPreference;
@ -140,12 +142,42 @@ public class MapWidgetRegistry {
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,
@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(settings)) {
boolean collapse = ms.isWidgetCollapsible(key);
boolean def = ms.isWidgetVisible(key);
@ -168,15 +200,6 @@ public class MapWidgetRegistry {
ii.visibleCollapsible.add(ms);
}
}
if (widget != null) {
widget.setContentTitle(messageId);
}
if (left) {
this.leftWidgetSet.add(ii);
} else {
this.rightWidgetSet.add(ii);
}
return ii;
}
private void restoreModes(Set<String> set, Set<MapWidgetRegInfo> mi, ApplicationMode mode) {
@ -343,7 +366,7 @@ public class MapWidgetRegistry {
}
public String getText(Context ctx, final ApplicationMode mode, final MapWidgetRegInfo r) {
return (r.visibleCollapsed(mode) ? " + " : " ") + ctx.getString(r.messageId);
return (r.visibleCollapsed(mode) ? " + " : " ") + ctx.getString(r.getMessageId());
}
public Set<MapWidgetRegInfo> getRightWidgetSet() {
@ -370,8 +393,8 @@ public class MapWidgetRegistry {
final boolean selected = r.visibleCollapsed(mode) || r.visible(mode);
final String desc = mapActivity.getString(R.string.shared_string_collapse);
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(r.messageId, mapActivity)
.setIcon(r.drawableMenu)
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(r.getMessageId(), mapActivity)
.setIcon(r.getDrawableMenu())
.setSelected(selected)
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setSecondaryIcon(R.drawable.ic_action_additional_option)
@ -385,11 +408,32 @@ public class MapWidgetRegistry {
View textWrapper = view.findViewById(R.id.text_wrapper);
IconPopupMenu popup = new IconPopupMenu(view.getContext(), textWrapper);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.vidget_visibility_menu, popup.getMenu());
final Menu menu = popup.getMenu();
inflater.inflate(R.menu.widget_visibility_menu, menu);
IconsCache ic = mapActivity.getMyApplication().getIconsCache();
ic.paintMenuItem(popup.getMenu().findItem(R.id.action_show));
ic.paintMenuItem(popup.getMenu().findItem(R.id.action_hide));
ic.paintMenuItem(popup.getMenu().findItem(R.id.action_collapse));
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();
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()
? 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
@ -405,6 +449,23 @@ public class MapWidgetRegistry {
case R.id.action_collapse:
setVisibility(adapter, pos, true, true);
return true;
default:
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());
item.setTitle(mapActivity.getResources().getString(r.getMessageId()));
adapter.notifyDataSetChanged();
return true;
}
}
}
}
return false;
}
@ -443,9 +504,10 @@ public class MapWidgetRegistry {
public static class MapWidgetRegInfo implements Comparable<MapWidgetRegInfo> {
public final TextInfoWidget widget;
@DrawableRes
public final int drawableMenu;
private int drawableMenu;
@StringRes
public final int messageId;
private int messageId;
private WidgetState widgetState;
public final String key;
public final boolean left;
public final int priorityOrder;
@ -463,6 +525,69 @@ public class MapWidgetRegistry {
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 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);
}
@ -483,7 +608,7 @@ public class MapWidgetRegistry {
@Override
public int hashCode() {
return messageId;
return getMessageId();
}
@Override
@ -496,16 +621,16 @@ public class MapWidgetRegistry {
return false;
}
MapWidgetRegInfo other = (MapWidgetRegInfo) obj;
return messageId == other.messageId;
return getMessageId() == other.getMessageId();
}
@Override
public int compareTo(@NonNull MapWidgetRegInfo another) {
if (messageId == another.messageId) {
if (getMessageId() == another.getMessageId()) {
return 0;
}
if (priorityOrder == another.priorityOrder) {
return messageId - another.messageId;
return getMessageId() - another.getMessageId();
}
return priorityOrder - another.priorityOrder;
}
@ -546,4 +671,27 @@ public class MapWidgetRegistry {
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);
}
}

View file

@ -27,7 +27,6 @@ import net.osmand.Location;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider;
@ -51,6 +50,7 @@ import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.TurnPathHelper;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WidgetState;
import net.osmand.router.RouteResultPreparation;
import net.osmand.router.TurnType;
import net.osmand.util.Algorithms;
@ -196,11 +196,56 @@ public class RouteInfoWidgetsFactory {
// initial state
return nextTurnInfo;
}
public static class TimeControlWidgetState extends WidgetState {
public static final int TIME_CONTROL_WIDGET_STATE_ARRIVAL_TIME = R.id.time_control_widget_state_arrival_time;
public static final int TIME_CONTROL_WIDGET_STATE_TIME_TO_GO = R.id.time_control_widget_state_time_to_go;
private final OsmandPreference<Boolean> showArrival;
public TimeControlWidgetState(OsmandApplication ctx) {
super(ctx);
showArrival = ctx.getSettings().SHOW_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME;
}
@Override
public int getMenuTitleId() {
return showArrival.get() ? R.string.access_arrival_time : R.string.map_widget_time;
}
@Override
public int getMenuIconId() {
return showArrival.get() ? R.drawable.ic_action_time : R.drawable.ic_action_time_to_distance;
}
@Override
public int getMenuItemId() {
return showArrival.get() ? TIME_CONTROL_WIDGET_STATE_ARRIVAL_TIME : TIME_CONTROL_WIDGET_STATE_TIME_TO_GO;
}
@Override
public int[] getMenuTitleIds() {
return new int[]{R.string.access_arrival_time, R.string.map_widget_time};
}
@Override
public int[] getMenuIconIds() {
return new int[]{R.drawable.ic_action_time, R.drawable.ic_action_time_to_distance};
}
@Override
public int[] getMenuItemIds() {
return new int[]{TIME_CONTROL_WIDGET_STATE_ARRIVAL_TIME, TIME_CONTROL_WIDGET_STATE_TIME_TO_GO};
}
@Override
public void changeState(int stateId) {
showArrival.set(stateId == TIME_CONTROL_WIDGET_STATE_ARRIVAL_TIME);
}
}
public TextInfoWidget createTimeControl(final MapActivity map){
final RoutingHelper routingHelper = map.getRoutingHelper();
@ -508,6 +553,55 @@ public class RouteInfoWidgetsFactory {
return distanceControl;
}
public static class BearingWidgetState extends WidgetState {
public static final int BEARING_WIDGET_STATE_RELATIVE_BEARING = R.id.bearing_widget_state_relative_bearing;
public static final int BEARING_WIDGET_STATE_MAGNETIC_BEARING = R.id.bearing_widget_state_magnetic_bearing;
private final OsmandPreference<Boolean> showRelativeBearing;
public BearingWidgetState(OsmandApplication ctx) {
super(ctx);
showRelativeBearing = ctx.getSettings().SHOW_RELATIVE_BEARING_OTHERWISE_REGULAR_BEARING;
}
@Override
public int getMenuTitleId() {
return showRelativeBearing.get() ? R.string.map_widget_bearing : R.string.map_widget_magnetic_bearing;
}
@Override
public int getMenuIconId() {
return showRelativeBearing.get() ? R.drawable.ic_action_relative_bearing : R.drawable.ic_action_bearing;
}
@Override
public int getMenuItemId() {
return showRelativeBearing.get() ? BEARING_WIDGET_STATE_RELATIVE_BEARING : BEARING_WIDGET_STATE_MAGNETIC_BEARING;
}
@Override
public int[] getMenuTitleIds() {
return new int[]{R.string.map_widget_magnetic_bearing, R.string.map_widget_bearing};
}
@Override
public int[] getMenuIconIds() {
return new int[]{R.drawable.ic_action_bearing, R.drawable.ic_action_relative_bearing};
}
@Override
public int[] getMenuItemIds() {
return new int[]{BEARING_WIDGET_STATE_MAGNETIC_BEARING, BEARING_WIDGET_STATE_RELATIVE_BEARING};
}
@Override
public void changeState(int stateId) {
showRelativeBearing.set(stateId == BEARING_WIDGET_STATE_RELATIVE_BEARING);
}
}
public TextInfoWidget createBearingControl(final MapActivity map) {
final int bearingResId = R.drawable.widget_bearing_day;
final int bearingNightResId = R.drawable.widget_bearing_night;
@ -526,7 +620,9 @@ public class RouteInfoWidgetsFactory {
@Override
public boolean updateInfo(DrawSettings drawSettings) {
int b = getBearing(showRelativeBearing.get());
boolean relative = showRelativeBearing.get();
setContentTitle(relative ? R.string.map_widget_bearing : R.string.map_widget_magnetic_bearing);
int b = getBearing(relative);
if (distChanged(cachedDegrees, b)) {
cachedDegrees = b;
if (b != -1000) {
@ -590,15 +686,15 @@ public class RouteInfoWidgetsFactory {
@Override
public void onClick(View v) {
showRelativeBearing.set(!showRelativeBearing.get());
bearingControl.setIcons(showRelativeBearing.get() ? bearingResId : relativeBearingResId,
showRelativeBearing.get() ? bearingNightResId : relativeBearingNightResId);
bearingControl.setIcons(!showRelativeBearing.get() ? bearingResId : relativeBearingResId,
!showRelativeBearing.get() ? bearingNightResId : relativeBearingNightResId);
map.getMapView().refreshMap();
}
});
bearingControl.setText(null, null);
bearingControl.setIcons(showRelativeBearing.get() ? bearingResId : relativeBearingResId,
showRelativeBearing.get() ? bearingNightResId : relativeBearingNightResId);
bearingControl.setIcons(!showRelativeBearing.get() ? bearingResId : relativeBearingResId,
!showRelativeBearing.get() ? bearingNightResId : relativeBearingNightResId);
return bearingControl;
}