Skip to content

Commit

Permalink
Merge branch 'only_show_direction_widget_for_explicitly_cardinal_fields'
Browse files Browse the repository at this point in the history
  • Loading branch information
simonpoole committed Oct 21, 2024
2 parents b5301cc + 378d1b8 commit c3ef77a
Show file tree
Hide file tree
Showing 12 changed files with 239 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ public void nodeWithDirection1() {
fail();
}
assertNotNull(direction);
assertEquals("Type or tap for values", direction.getText());
assertEquals(main.getString(R.string.tag_dialog_value_hint), direction.getText());
direction.clickAndWait(Until.newWindow(), 2000);
TestUtils.clickText(device, true, main.getString(R.string.save), true, false);
TestUtils.clickHome(device, true);
Expand Down Expand Up @@ -371,12 +371,12 @@ public void nodeWithDirection2() {
fail();
}
assertNotNull(direction);
assertEquals("Type or tap for values", direction.getText());
assertEquals(main.getString(R.string.tag_dialog_value_hint), direction.getText());
direction.clickAndWait(Until.newWindow(), 2000);
TestUtils.clickText(device, true, "Forward", false, false);
TestUtils.clickText(device, true, main.getString(R.string.save), true, false);
TestUtils.clickHome(device, true);
assertEquals("forward", n.getTagWithKey("direction"));
assertEquals("forward", n.getTagWithKey("direction").toLowerCase());
}

@Test
Expand Down Expand Up @@ -410,7 +410,7 @@ public void nodeWithDirection3() {
fail();
}
assertNotNull(direction);
assertEquals("forward", direction.getText());
assertEquals("forward", direction.getText().toLowerCase());
direction.clickAndWait(Until.newWindow(), 2000);
TestUtils.clickText(device, true, "Forward", false, false);
TestUtils.clickText(device, true, main.getString(R.string.save), true, false);
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/de/blau/android/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentActivity;
import ch.poole.osm.josmfilterparser.Nodes;
import de.blau.android.contract.HttpStatusCodes;
import de.blau.android.contract.Urls;
import de.blau.android.dialogs.AttachedObjectWarning;
Expand Down Expand Up @@ -110,6 +109,7 @@
import de.blau.android.osm.ViewBox;
import de.blau.android.osm.Way;
import de.blau.android.prefs.Preferences;
import de.blau.android.presets.Preset;
import de.blau.android.resources.DataStyle;
import de.blau.android.resources.DataStyle.FeatureStyle;
import de.blau.android.tasks.Note;
Expand Down Expand Up @@ -1577,7 +1577,7 @@ synchronized void handleTouchEventMove(@NonNull Main main, final float absoluteX
/**
* Rotate selected objects
*
* Note that this needs to rotate all the nodes of all objects at once to avoid rotating the same ome multiple
* Note that this needs to rotate all the nodes of all objects at once to avoid rotating the same one multiple
* times, special cases exactly one node selected.
*
* @param activity the current Activity
Expand All @@ -1597,7 +1597,7 @@ private void rotateSelection(@NonNull FragmentActivity activity, @NonNull final
List<Node> selectedNodes = selection.getNodes();
if (selectedNodes != null) {
if (selection.count() == 1) {
updateDirection((float) Math.toDegrees(angle), direction, selectedNodes.get(0));
updateDirection(activity, (float) Math.toDegrees(angle), direction, selectedNodes.get(0));
return;
}
nodes.addAll(selectedNodes);
Expand Down Expand Up @@ -1625,8 +1625,9 @@ private void rotateSelection(@NonNull FragmentActivity activity, @NonNull final
* @param direction rotation direction (+ == clockwise)
* @param node the Node
*/
private void updateDirection(float angle, int direction, @NonNull final Node node) {
String directionKey = Tags.getDirectionKey(node);
private void updateDirection(@NonNull Context context, float angle, int direction, @NonNull final Node node) {
// this is obviously quiet expensive bit avoids having state somewhere else
String directionKey = Tags.getDirectionKey(Preset.findBestMatch(App.getCurrentPresets(context), node.getTags(), null, null), node);
if (directionKey != null) {
java.util.Map<String, String> tags = new HashMap<>(node.getTags());
Float currentAngle = Tags.parseDirection(tags.get(directionKey));
Expand Down Expand Up @@ -2808,8 +2809,11 @@ private Node findTargetNode(@NonNull List<Node> targetNodes, double newLon, doub
for (Node target : targetNodes) {
double distance = GeoMath.haversineDistance(target.getLon() / 1E7D, target.getLat() / 1E7D, newLon, newLat);
if (distance < bestDistance) {
if (target.hasTags() && prefs != null && distance > prefs.getReplaceTolerance()) { // only use tagged nodes if they are really close to new
// position
if (target.hasTags() && prefs != null && distance > prefs.getReplaceTolerance()) { // only use tagged
// nodes if they are
// really close to
// new
// position
continue;
}
bestDistance = distance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.app.AppCompatDialog;
import androidx.appcompat.view.ActionMode;
import de.blau.android.App;
import de.blau.android.DisambiguationMenu;
import de.blau.android.R;
import de.blau.android.dialogs.ElementIssueDialog;
Expand All @@ -36,6 +37,7 @@
import de.blau.android.osm.Result;
import de.blau.android.osm.Tags;
import de.blau.android.osm.Way;
import de.blau.android.presets.Preset;
import de.blau.android.util.GeoMath;
import de.blau.android.util.ScreenMessage;
import de.blau.android.util.Sound;
Expand Down Expand Up @@ -67,6 +69,7 @@ public class NodeSelectionActionModeCallback extends ElementSelectionActionModeC
private MenuItem restrictionItem;
private MenuItem rotateItem;
private int action;
private Preset[] presets;

/**
* Construct a callback for Node selection
Expand All @@ -86,9 +89,9 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
main.invalidateMap();
mode.setTitle(R.string.actionmode_nodeselect);
mode.setSubtitle(null);

presets = App.getCurrentPresets(main);
menu = replaceMenu(menu, mode, this);
SortedMap<String, String> tags = ((Node) element).getTags();
SortedMap<String, String> tags = element.getTags();
if (!tags.containsKey(Tags.KEY_ADDR_HOUSENUMBER) && !tags.containsKey(Tags.KEY_HIGHWAY)) {
// exclude some stuff that typically doesn't have an address
menu.add(Menu.NONE, MENUITEM_ADDRESS, Menu.NONE, R.string.tag_menu_address).setIcon(ThemeUtils.getResIdFromAttribute(main, R.attr.menu_address));
Expand Down Expand Up @@ -137,7 +140,7 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
}
updated |= setItemVisibility(highways.size() >= 2, restrictionItem, false);

updated |= setItemVisibility(Tags.getDirectionKey(element) != null, rotateItem, false);
updated |= setItemVisibility(Tags.getDirectionKey(Preset.findBestMatch(presets, element.getTags(), null, null), element) != null, rotateItem, false);

if (updated) {
arrangeMenu(menu);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,22 @@
import java.util.HashSet;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.util.Log;
import android.view.Menu;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ActionMode;
import de.blau.android.App;
import de.blau.android.Logic;
import de.blau.android.R;
import de.blau.android.dialogs.ElementIssueDialog;
import de.blau.android.exception.OsmIllegalOperationException;
import de.blau.android.exception.StorageException;
import de.blau.android.osm.GeoPoint;
import de.blau.android.osm.MergeAction;
import de.blau.android.osm.Node;
import de.blau.android.osm.OsmElement;
import de.blau.android.osm.Result;
import de.blau.android.osm.StorageDelegator;
import de.blau.android.osm.Way;
import de.blau.android.util.SerializableState;

Expand Down
36 changes: 31 additions & 5 deletions src/main/java/de/blau/android/layer/data/MapOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ public class MapOverlay<O extends OsmElement> extends MapViewLayer
*/
private final WeakHashMap<java.util.Map<String, String>, Float> directionCache = new WeakHashMap<>();

/**
* Cache for any preset matching during one draw pass
*/
private final HashMap<java.util.Map<String, String>, PresetItem> matchCache = new HashMap<>();

/**
* Stores custom icons
*/
Expand Down Expand Up @@ -477,6 +482,7 @@ protected void onDraw(Canvas canvas, IMapView osmv) {
download.setBox(viewBox);
map.getRootView().postDelayed(download, 100);
}
matchCache.clear();
paintOsmData(canvas);
}

Expand Down Expand Up @@ -1141,9 +1147,12 @@ private Float getDirection(@NonNull final Node node) {
Float direction = node.getFromCache(directionCache);
if (direction == null) {
direction = Float.NaN;
String key = Tags.getDirectionKey(node);
if (key != null) {
direction = Tags.parseDirection(node.getTagWithKey(key));
PresetItem match = getMatch(node);
if (match != null) {
String key = Tags.getDirectionKey(match, node);
if (key != null) {
direction = Tags.parseDirection(node.getTagWithKey(key));
}
}
synchronized (directionCache) {
node.addToCache(directionCache, direction);
Expand All @@ -1152,6 +1161,23 @@ private Float getDirection(@NonNull final Node node) {
return direction;
}

/**
* Get the best preset match for an element and cache it during this draw pass
*
* @param e the OsmElement
* @return a PresetItem or null
*/
@Nullable
private PresetItem getMatch(@NonNull OsmElement e) {
java.util.Map<String, String> tags = e.getTags();
PresetItem match = matchCache.get(tags);
if (match == null && !matchCache.containsKey(tags)) {
match = Preset.findBestMatch(tmpPresets, tags, null, null);
matchCache.put(tags, match);
}
return match;
}

/**
* Draw a circle with center at x,y with the house number in it
*
Expand Down Expand Up @@ -1190,7 +1216,7 @@ private void paintLabel(final float x, final float y, @NonNull final Canvas canv
}
FeatureStyle style = styles.matchStyle(e);
if (style.usePresetLabel() && tmpPresets != null) {
PresetItem match = Preset.findBestMatch(tmpPresets, e.getTags(), null, null);
PresetItem match = getMatch(e);
if (match != null) {
String template = e.nameFromTemplate(context, match);
label = template != null ? template : match.getTranslatedName();
Expand Down Expand Up @@ -1265,7 +1291,7 @@ private void retrieveIcon(@NonNull OsmElement element, boolean isWay, @NonNull W
iconDrawable = retrieveCustomIcon(iconPath);
}
} else if (tmpPresets != null) {
PresetItem match = !isWay || usePresetIcon ? Preset.findBestMatch(tmpPresets, element.getTags(), null, null) : null;
PresetItem match = !isWay || usePresetIcon ? getMatch(element) : null;
if (match != null) {
iconDrawable = match.getMapIcon(context);
}
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/de/blau/android/osm/Tags.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.blau.android.presets.PresetField;
import de.blau.android.presets.PresetItem;
import de.blau.android.presets.PresetTagField;
import de.blau.android.presets.ValueType;

/**
* Key and value constants for tags that are used in the code
Expand Down Expand Up @@ -281,19 +285,20 @@ public static boolean isSpeedKey(@Nullable final String key) {
public static final String KEY_CAMERA_DIRECTION = "camera:direction";
public static final String KEY_LIGHT_DIRECTION = "light:direction";

public static final List<String> DIRECTION_KEYS = Collections.unmodifiableList(Arrays.asList(KEY_DIRECTION, KEY_CAMERA_DIRECTION, KEY_LIGHT_DIRECTION));

/**
* Get a direction key if any are present from the OSM element
*
* @param presetItem matching preset item
* @param e the OSM element
* @return the key or null
*/
@Nullable
public static String getDirectionKey(@NonNull OsmElement e) {
for (String key : Tags.DIRECTION_KEYS) {
if (e.hasTagKey(key)) {
return key;
public static String getDirectionKey(@Nullable PresetItem presetItem, @NonNull OsmElement e) {
if (presetItem != null) {
for (PresetField field : presetItem.getFields().values()) {
if (field instanceof PresetTagField && ((PresetTagField) field).getValueType() == ValueType.CARDINAL_DIRECTION) {
return ((PresetTagField) field).getKey();
}
}
}
return null;
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/de/blau/android/presets/ValueType.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import androidx.annotation.Nullable;

public enum ValueType {
OPENING_HOURS, OPENING_HOURS_MIXED, DIMENSION_HORIZONTAL, DIMENSION_VERTICAL, INTEGER, WEBSITE, PHONE, WIKIPEDIA, WIKIDATA;
OPENING_HOURS, OPENING_HOURS_MIXED, DIMENSION_HORIZONTAL, DIMENSION_VERTICAL, INTEGER, WEBSITE, PHONE, WIKIPEDIA, WIKIDATA, CARDINAL_DIRECTION;

/**
* Get a ValueType corresponding to the input String
Expand Down Expand Up @@ -44,6 +44,9 @@ static ValueType fromString(@NonNull String typeString) {
case "wikidata":
type = WIKIDATA;
break;
case "cardinal_direction":
type = CARDINAL_DIRECTION;
break;
default:
Log.e(ValueType.class.getSimpleName(), "Unknown value type string " + typeString);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class IntegerWidget implements ValueWidget {
if (editView instanceof EditText) {
// Remove default input filter
((EditText) editView).setFilters(new InputFilter[0]);
((EditText) editView).setFocusable(false);
editView.setFocusable(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,7 @@ void addRow(@Nullable final LinearLayout rowLayout, @NonNull final PresetTagFiel
ValueType valueType = field.getValueType();
if (field instanceof PresetTextField || key.startsWith(Tags.KEY_ADDR_BASE)
|| (isComboField && ((PresetComboField) field).isEditable() && ValueType.OPENING_HOURS_MIXED != valueType) || Tags.isConditional(key)
|| ValueType.INTEGER == valueType || Tags.DIRECTION_KEYS.contains(key)) {
|| ValueType.INTEGER == valueType || ValueType.CARDINAL_DIRECTION == valueType) {
if (Tags.isConditional(key)) {
rowLayout.addView(getConditionalRestrictionDialogRow(rowLayout, preset, hint, key, value, values, allTags));
return;
Expand All @@ -1014,6 +1014,10 @@ void addRow(@Nullable final LinearLayout rowLayout, @NonNull final PresetTagFiel
rowLayout.addView(LongTextDialogRow.getRow(this, inflater, rowLayout, preset, (PresetTextField) field, value, maxStringLength));
return;
}
if ( ValueType.INTEGER == valueType || ValueType.CARDINAL_DIRECTION == valueType) {
rowLayout.addView(ValueWidgetRow.getRow(this, inflater, rowLayout, preset, field, value, values, allTags));
return;
}
rowLayout.addView(TextRow.getRow(this, inflater, rowLayout, preset, field, value, values, allTags));
return;
}
Expand Down
20 changes: 0 additions & 20 deletions src/main/java/de/blau/android/propertyeditor/tagform/TextRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ static TextRow getRow(@NonNull final TagFormFragment caller, @NonNull final Layo
final TextRow row = (TextRow) inflater.inflate(R.layout.tag_form_text_row, rowLayout, false);
final String key = field.getKey();
final String hint = preset != null ? field.getHint() : null;
final String defaultValue = field.getDefaultValue();
row.valueType = preset != null ? preset.getValueType(key) : null;
final boolean isName = Tags.isLikeAName(key);
final Context context = rowLayout.getContext();
Expand Down Expand Up @@ -218,25 +217,6 @@ static TextRow getRow(@NonNull final TagFormFragment caller, @NonNull final Layo
dialog.show();
});
}
if (ValueType.INTEGER == valueType) {
ourValueView.setFocusable(false);
ourValueView.setFocusableInTouchMode(false);
ourValueView.setOnClickListener(v -> {
final View finalView = v;
finalView.setEnabled(false); // debounce
IntegerValueFragment.show(caller, hint != null ? hint : key, key, ((TextView) v).getText().toString(), values, preset, allTags);
});
}
if (Tags.DIRECTION_KEYS.contains(key)
&& (preset == null || !(preset.hasKeyValue(Tags.KEY_HIGHWAY, Tags.VALUE_MINI_ROUNDABOUT) && Tags.KEY_DIRECTION.equals(key)))) {
ourValueView.setFocusable(false);
ourValueView.setFocusableInTouchMode(false);
ourValueView.setOnClickListener(v -> {
final View finalView = v;
finalView.setEnabled(false); // debounce
DirectionValueFragment.show(caller, hint != null ? hint : key, key, ((TextView) v).getText().toString(), values, preset, allTags);
});
}
ourValueView.setOnFocusChangeListener((v, hasFocus) -> {
Log.d(DEBUG_TAG, "onFocusChange");
String rowValue = row.getValue();
Expand Down
Loading

0 comments on commit c3ef77a

Please sign in to comment.