Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mode switching to the main menu and some other minor rearrangement #2499

Merged
merged 1 commit into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/docs/help/en/Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need to use a non-standard OSM API entry, or use [offline data](https://v

To avoid accidental edits Vespucci starts in "locked" mode, a mode that only allows zooming and moving the map. Tap the ![Locked](../images/locked.png) icon to unlock the screen.

A long press on the lock icon will display a menu currently offering 4 options:
A long press on the lock icon or the _Modes_ menu in the map display overflow menu will display a menu offering 4 options:

* **Normal** - the default editing mode, new objects can be added, existing ones edited, moved and removed. Simple white lock icon displayed.
* **Tag only** - selecting an existing object will start the Property Editor, new objects can be added via the green "+" button, or long press, but no other geometry operations are enabled. White lock icon with a "T" is displayed.
Expand Down
6 changes: 5 additions & 1 deletion documentation/docs/help/en/Main map display.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ Select either the transfer icon ![Transfer](../images/menu_transfer.png) or the

Show the user preference screens. The settings are split into two sets: the first screen contains the more commonly used preferences, the "Advanced preferences" contains the less used ones.

### ![Tools](../images/menu_tools.png) Tools
### ![Tools](../images/menu_tools.png) Tools

* **Apply stored offset to imagery** - apply stored offset, if it exists, for the current background layer
* **More imagery tools**
Expand Down Expand Up @@ -234,6 +234,10 @@ Search for a location and pan to it with the OpenStreetMap Nominatim or Photon s
Search for OSM objects in the loaded data using JOSMs search/filter expressions. See [JOSM filter documentation](http://vespucci.io/tutorials/object_search/) for more information. Besides searching in the loaded data alternatively you can create a
Overpass API query and use that to download data.

### Modes...

This menu allows mode selection as via the _lock button_ and enabling/disabling of the _simple mode_.

### Tag-Filter *(checkbox)*

Enable the tag based filter, the filter can be configured by tapping the filter button on the map display.
Expand Down
32 changes: 30 additions & 2 deletions src/androidTest/java/de/blau/android/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.junit.Assert;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Point;
Expand Down Expand Up @@ -66,7 +67,7 @@ public final class TestUtils {
private static final String DEBUG_TAG = TestUtils.class.getSimpleName();

private static final String VESPUCCI = "Vespucci";

/**
* Private constructor
*/
Expand Down Expand Up @@ -1583,7 +1584,7 @@ public static boolean findNotification(@NonNull UiDevice device, @NonNull String
public static boolean clickNotification(@NonNull UiDevice device, @NonNull String message) {
return clickNotification(device, VESPUCCI, message);
}

/**
* Click on a specific notification
*
Expand Down Expand Up @@ -1645,4 +1646,31 @@ public static void clickAwayTip(@NonNull UiDevice device, @NonNull Context ctx,
TestUtils.clickText(device, false, ctx.getString(R.string.okay), true, false); // TIP
}
}

/**
* Switch the simple mode checkbox/pref
*
* @param on if true it should be turned on if it is not on, if false turned off
*/
public static void switchSimpleMode(@NonNull UiDevice device, @NonNull Activity activity, boolean on) {
if (TestUtils.clickOverflowButton(device)) {
UiObject2 modesMenu = TestUtils.findObjectWithText(device, false, activity.getString(R.string.menu_modes), 5000, false);
modesMenu.click();
UiObject2 simpleMode = TestUtils.findObjectWithText(device, false, activity.getString(R.string.menu_simple_actions), 5000, false);
if (simpleMode != null) {
UiObject2 check = simpleMode.getParent().getParent().getChildren().get(1);
assertTrue(check.isCheckable());
if ((on && !check.isChecked()) || (!on && check.isChecked())) {
check.click();
} else {
device.pressBack();
}
} else {
Log.e("toggleSimpleMode", "Simple mode check not found");
device.pressBack();
}
} else {
Log.e("toggleSimpleMode", "no overflowbutton");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ public void teardown() {
@Test
public void newAddressLongClick() {
TestUtils.unlock(device);
TestUtils.clickOverflowButton(device);
TestUtils.clickText(device, false, main.getString(R.string.menu_simple_actions), true);
TestUtils.switchSimpleMode(device, main, true);
map.getDataLayer().setVisible(true);
TestUtils.zoomToLevel(device, main, 21);
TestUtils.longClickAtCoordinates(device, map, 8.3893454, 47.3901898, true);
Expand Down
29 changes: 2 additions & 27 deletions src/androidTest/java/de/blau/android/easyedit/LongClickTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,32 +71,7 @@ public void setup() {
TestUtils.loadTestData(main, "test2.osm");
App.getTaskStorage().reset();
TestUtils.stopEasyEdit(main);
switchSimpleMode(false);
}

/**
* Switch the simple mode checkbox/pref
*
* @param on if true it should be turned on if it is not on, if false turned off
*/
private void switchSimpleMode(boolean on) {
if (TestUtils.clickOverflowButton(device)) {
UiObject2 simpleMode = TestUtils.findObjectWithText(device, false, main.getString(R.string.menu_simple_actions), 5000, false);
if (simpleMode != null) {
UiObject2 check = simpleMode.getParent().getParent().getChildren().get(1);
assertTrue(check.isCheckable());
if ((on && !check.isChecked()) || (!on && check.isChecked())) {
check.click();
} else {
device.pressBack();
}
} else {
Log.e("toggleSimpleMode", "Simple mode check not found");
device.pressBack();
}
} else {
Log.e("toggleSimpleMode", "no overflowbutton");
}
TestUtils.switchSimpleMode(device, main, false);
}

/**
Expand All @@ -107,7 +82,7 @@ public void teardown() {
TestUtils.stopEasyEdit(main);
TestUtils.zoomToNullIsland(logic, map);
TestUtils.clickOverflowButton(device);
switchSimpleMode(true);
TestUtils.switchSimpleMode(device, main, true);
App.getTaskStorage().reset();
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/help/en/Introduction.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h3>Editing</h3>
<p><a id="lock"></a></p>
<h4>Lock, unlock, mode switching</h4>
<p>To avoid accidental edits Vespucci starts in &quot;locked&quot; mode, a mode that only allows zooming and moving the map. Tap the <img src="../images/locked.png" alt="Locked" /> icon to unlock the screen.</p>
<p>A long press on the lock icon will display a menu currently offering 4 options:</p>
<p>A long press on the lock icon or the <em>Modes</em> menu in the map display overflow menu will display a menu offering 4 options:</p>
<ul>
<li><strong>Normal</strong> - the default editing mode, new objects can be added, existing ones edited, moved and removed. Simple white lock icon displayed.</li>
<li><strong>Tag only</strong> - selecting an existing object will start the Property Editor, new objects can be added via the green &quot;+&quot; button, or long press, but no other geometry operations are enabled. White lock icon with a &quot;T&quot; is displayed.</li>
Expand Down
4 changes: 3 additions & 1 deletion src/main/assets/help/en/Main map display.html
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ <h3><img src="../images/menu_transfer.png" alt="Transfer" /> Transfer</h3>
</ul>
<h3><img src="../images/menu_config.png" alt="Preferences" /> Preferences</h3>
<p>Show the user preference screens. The settings are split into two sets: the first screen contains the more commonly used preferences, the &quot;Advanced preferences&quot; contains the less used ones.</p>
<h3><img src="../images/menu_tools.png" alt="Tools" /> Tools</h3>
<h3><img src="../images/menu_tools.png" alt="Tools" /> Tools</h3>
<ul>
<li><strong>Apply stored offset to imagery</strong> - apply stored offset, if it exists, for the current background layer</li>
<li><strong>More imagery tools</strong>
Expand All @@ -245,6 +245,8 @@ <h3><img src="../images/ic_menu_search_holo_light.png" alt="Find" /> Find</h3>
<p>Search for a location and pan to it with the OpenStreetMap Nominatim or Photon service <em>(requires network connectivity)</em></p>
<h3>Search for objects</h3>
<p>Search for OSM objects in the loaded data using JOSMs search/filter expressions. See <a href="http://vespucci.io/tutorials/object_search/">JOSM filter documentation</a> for more information. Besides searching in the loaded data alternatively you can create a Overpass API query and use that to download data.</p>
<h3>Modes...</h3>
<p>This menu allows mode selection as via the <em>lock button</em> and enabling/disabling of the <em>simple mode</em>.</p>
<h3>Tag-Filter <em>(checkbox)</em></h3>
<p>Enable the tag based filter, the filter can be configured by tapping the filter button on the map display.</p>
<h3>Preset-Filter <em>(checkbox)</em></h3>
Expand Down
74 changes: 49 additions & 25 deletions src/main/java/de/blau/android/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnGenericMotionListener;
Expand Down Expand Up @@ -1697,30 +1698,40 @@ private void setupLockButton() {
s.setSpan(new ForegroundColorSpan(ThemeUtils.getStyleAttribColorValue(Main.this, R.attr.colorAccent, 0)), 0, s.length(), 0);
}
MenuItem item = popup.getMenu().add(s);
item.setOnMenuItemClickListener(menuitem -> {
l.setMode(Main.this, newMode);
b.setTag(newMode.tag());
StateListDrawable mStates = new StateListDrawable();
mStates.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getDrawable(Main.this, newMode.iconResourceId()));
mStates.addState(new int[] {}, ContextCompat.getDrawable(Main.this, R.drawable.locked_opaque));
lock.setImageDrawable(mStates);
lock.hide(); // workaround https://issuetracker.google.com/issues/117476935
lock.show();
if (l.isLocked()) {
((FloatingActionButton) b).setImageState(new int[] { 0 }, false);
} else {
((FloatingActionButton) b).setImageState(new int[] { android.R.attr.state_pressed }, false);
}
updateActionbarEditMode();
return true;
});
setModeMenuListener(l, item, lock, newMode);
}
}
popup.show();
return true;
});
}

/**
* @param l
* @param item
* @param lock
* @param newMode
*/
private void setModeMenuListener(final Logic l, MenuItem item, final FloatingActionButton lock, final Mode newMode) {
item.setOnMenuItemClickListener(menuitem -> {
l.setMode(Main.this, newMode);
lock.setTag(newMode.tag());
StateListDrawable mStates = new StateListDrawable();
mStates.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getDrawable(Main.this, newMode.iconResourceId()));
mStates.addState(new int[] {}, ContextCompat.getDrawable(Main.this, R.drawable.locked_opaque));
lock.setImageDrawable(mStates);
lock.hide(); // workaround https://issuetracker.google.com/issues/117476935
lock.show();
if (l.isLocked()) {
lock.setImageState(new int[] { 0 }, false);
} else {
lock.setImageState(new int[] { android.R.attr.state_pressed }, false);
}
updateActionbarEditMode();
return true;
});
}

/**
* Unlock the main display
*/
Expand Down Expand Up @@ -1796,25 +1807,26 @@ public boolean onPrepareOptionsMenu(final Menu m) {
*/
@SuppressLint("InflateParams")
@Override
public boolean onCreateOptionsMenu(final Menu m) {
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(DEBUG_TAG, "onCreateOptionsMenu");
// determine how man icons have room
MenuUtil menuUtil = new MenuUtil(this);
Menu menu = m;
MenuCompat.setGroupDividerEnabled(menu, true);
if (getBottomBar() != null) {
menu = getBottomBar().getMenu();
Log.d(DEBUG_TAG, "inflated main menu on to bottom toolbar");
}
final boolean noSubMenus = getBottomBar() != null && Screen.isLarge(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& Flavors.LEGACY.equals(BuildConfig.FLAVOR);
if (menu.size() == 0) {
menu.clear();
final MenuInflater inflater = getMenuInflater();
if (getBottomBar() != null && Screen.isLarge(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Flavors.LEGACY.equals(BuildConfig.FLAVOR)) {
if (noSubMenus) {
inflater.inflate(R.menu.main_menu_nosubmenus, menu);
} else {
inflater.inflate(R.menu.main_menu, menu);
}
}
MenuCompat.setGroupDividerEnabled(menu, true);

boolean networkConnected = isConnected();
boolean locationPermissionGranted = isLocationPermissionGranted();
Expand Down Expand Up @@ -1905,7 +1917,8 @@ public boolean onCreateOptionsMenu(final Menu m) {
Log.d(DEBUG_TAG, "had to resync tagfilter pref");
}

final boolean supportsFilters = logic.getMode().supportsFilters();
final Mode mode = logic.getMode();
final boolean supportsFilters = mode.supportsFilters();
menu.findItem(R.id.menu_enable_tagfilter).setEnabled(supportsFilters).setChecked(prefs.getEnableTagFilter() && logic.getFilter() instanceof TagFilter);
menu.findItem(R.id.menu_enable_presetfilter).setEnabled(supportsFilters)
.setChecked(prefs.getEnablePresetFilter() && logic.getFilter() instanceof PresetFilter);
Expand Down Expand Up @@ -1939,10 +1952,21 @@ public boolean onCreateOptionsMenu(final Menu m) {
menu.findItem(R.id.menu_tools_install_egm).setVisible(!egmInstalled);
menu.findItem(R.id.menu_tools_remove_egm).setVisible(egmInstalled);

if (getBottomBar() != null) {
// menuUtil.evenlyDistributedToolbar(getBottomToolbar());
// per mode menu items
List<Mode> allModes = new ArrayList<>(Arrays.asList(Mode.values()));
final FloatingActionButton lock = getLock();
Menu modesMenu = noSubMenus ? menu : menu.findItem(R.id.menu_modes).getSubMenu();
modesMenu.removeGroup(R.id.menu_mode_group);
for (final Mode newMode : allModes) {
if (newMode.isSubModeOf() == null && newMode.isEnabled()) {
MenuItem modeItem = modesMenu.add(R.id.menu_mode_group, Menu.NONE, Menu.NONE, newMode.getName(Main.this));
modeItem.setCheckable(true);
setModeMenuListener(logic, modeItem, lock, newMode);
if (mode == newMode) {
modeItem.setChecked(true);
}
}
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/res/menu-v24/main_menu_nosubmenus.xml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@
android:id="@+id/menu_share"
android:title="@string/share_position"
app:showAsAction="never" />
<group android:id="@+id/menu_mode_group" android:checkableBehavior="single">
<!-- filled programmatically -->
</group>
<item
android:id="@+id/menu_simple_actions"
android:checkable="true"
Expand Down
27 changes: 19 additions & 8 deletions src/main/res/menu/main_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@
<item
android:id="@+id/menu_enable_gps_autodownload"
android:checkable="true"
android:title="@string/menu_enable_gps_autodownload" />
android:title="@string/menu_enable_gps_autodownload"/>
<item
android:id="@+id/menu_enable_pan_and_zoom_auto_download"
android:checkable="true"
android:title="@string/menu_enable_pan_and_zoom_auto_download" />
android:title="@string/menu_enable_pan_and_zoom_auto_download"/>
</group>
<item
android:id="@+id/menu_transfer_update"
Expand Down Expand Up @@ -241,7 +241,23 @@
android:id="@+id/menu_search_objects"
android:title="@string/search_objects_title"
app:showAsAction="never" />
<group android:checkableBehavior="single">
<item
android:id="@+id/menu_modes"
android:title="@string/menu_modes"
app:showAsAction="never">
<menu>
<group android:id="@+id/menu_mode_group" android:checkableBehavior="single" android:orderInCategory="101">
<!-- filled programmatically -->
</group>
<item
android:id="@+id/menu_simple_actions"
android:checkable="true"
android:title="@string/menu_simple_actions"
app:showAsAction="never"
android:orderInCategory="102"/>
</menu>
</item>
<group android:id="@+id/menu_filter_group" android:checkableBehavior="single">
<item
android:id="@+id/menu_enable_tagfilter"
android:checkable="true"
Expand All @@ -255,11 +271,6 @@
android:id="@+id/menu_share"
android:title="@string/share_position"
app:showAsAction="never" />
<item
android:id="@+id/menu_simple_actions"
android:checkable="true"
android:title="@string/menu_simple_actions"
app:showAsAction="never" />
<item
android:id="@+id/menu_help"
android:alphabeticShortcut="@string/shortcut_help"
Expand Down
1 change: 1 addition & 0 deletions src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,7 @@
<string name="menu_tools_import_data_style">Import data style…</string>
<string name="menu_tools_load_keys">Load keys from file…</string>
<!-- -->
<string name="menu_modes">Modes…</string>
<string name="menu_simple_actions">Simple mode</string>
<string name="menu_feedback">Provide feedback</string>
<string name="menu_preset_feedback">Provide preset feedback</string>
Expand Down
Loading