Skip to content

Commit

Permalink
Re-jig the welcome dialog to allow some initial setup
Browse files Browse the repository at this point in the history
This adds options to use the current best imagery, set auto-download,
setup for pen or mouse usage and start authorization immediately after
the modal has been closed.

Fixes #2430

Fixes #1506
  • Loading branch information
simonpoole committed Feb 28, 2024
1 parent a0d598f commit 9b5bbf7
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 86 deletions.
6 changes: 5 additions & 1 deletion src/androidTest/java/de/blau/android/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ public static void grantPermissons(@NonNull UiDevice device) {
* @param ctx Android context
*/
public static void dismissStartUpDialogs(@NonNull UiDevice device, @NonNull Context ctx) {
clickText(device, true, ctx.getResources().getString(R.string.okay), false, false);
if (findText(device, false, ctx.getResources().getString(R.string.welcome_title))) {
clickText(device, true, ctx.getResources().getString(R.string.next), true, false);
clickResource(device, false, device.getCurrentPackageName() + ":id/authorize", false);
clickText(device, true, ctx.getResources().getString(R.string.welcome_start), true, false);
}
}

/**
Expand Down
155 changes: 114 additions & 41 deletions src/main/java/de/blau/android/dialogs/Newbie.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,59 @@
package de.blau.android.dialogs;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.app.AppCompatDialog;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.PagerTabStrip;
import androidx.preference.PreferenceManager;
import de.blau.android.App;
import de.blau.android.Authorize;
import de.blau.android.HelpViewer;
import de.blau.android.Main;
import de.blau.android.R;
import de.blau.android.osm.ViewBox;
import de.blau.android.prefs.AdvancedPrefDatabase;
import de.blau.android.prefs.Preferences;
import de.blau.android.resources.DataStyle;
import de.blau.android.resources.TileLayerSource;
import de.blau.android.resources.TileLayerSource.Category;
import de.blau.android.resources.TileLayerSource.TileType;
import de.blau.android.util.ImmersiveDialogFragment;
import de.blau.android.util.OnPageSelectedListener;
import de.blau.android.util.ThemeUtils;
import de.blau.android.util.Util;
import de.blau.android.views.ExtendedViewPager;
import de.blau.android.views.layers.MapTilesLayer;

/**
* Display a dialog giving new users minimal instructions
*
*/
public class Newbie extends ImmersiveDialogFragment {

private static final String DEBUG_TAG = Newbie.class.getSimpleName();

private static final String TAG = "fragment_newbie";

private Main main;
private static final String PAGER_POS_KEY = "pagerPos";
private static final String AUTHORIZE_KEY = "authorize";
private static final String PEN_SETUP_KEY = "penSetup";
private static final String AUTO_DOWNLOAD_KEY = "autoDownload";
private static final String USE_IMAGERY_KEY = "useImagery";

private static final int SETTINGS_PAGE_INDEX = 1;
private static final int WELCOME_PAGE_INDEX = 0;

/**
* Display a dialog giving new users minimal instructions
Expand Down Expand Up @@ -83,55 +99,83 @@ public void onAttach(Context context) {
if (!(context instanceof Main)) {
throw new ClassCastException(context.toString() + " can only be called from Main");
}
main = (Main) context;
}

@NonNull
@Override
public AppCompatDialog onCreateDialog(Bundle savedInstanceState) {
final FragmentActivity activity = getActivity();
if (!(activity instanceof Main)) {
throw new ClassCastException(activity.toString() + " can only be called from Main");
}
Builder builder = new AlertDialog.Builder(activity);
builder.setIcon(null);
builder.setTitle(R.string.welcome_title);
final LayoutInflater inflater = ThemeUtils.getLayoutInflater(activity);
final View layout = inflater.inflate(R.layout.welcome_tabs, null);
final SwitchCompat displayImagery = layout.findViewById(R.id.use_imagery);
final SwitchCompat autoDownload = layout.findViewById(R.id.auto_download);
final SwitchCompat penSetup = layout.findViewById(R.id.pen_setup);
final SwitchCompat authorize = layout.findViewById(R.id.authorize);
final ExtendedViewPager pager = (ExtendedViewPager) layout.findViewById(R.id.pager);
pager.setAdapter(new ViewPagerAdapter(activity, layout, new int[] { R.id.welcome_page, R.id.settings_page },
new int[] { R.string.confirm_upload_edits_page, R.string.menu_tags }));
// set saved state before the on page change listener is set
if (savedInstanceState != null) {
displayImagery.setChecked(savedInstanceState.getBoolean(USE_IMAGERY_KEY));
autoDownload.setChecked(savedInstanceState.getBoolean(AUTO_DOWNLOAD_KEY));
penSetup.setChecked(savedInstanceState.getBoolean(PEN_SETUP_KEY));
authorize.setChecked(savedInstanceState.getBoolean(AUTHORIZE_KEY, true));
pager.setCurrentItem(savedInstanceState.getInt(PAGER_POS_KEY, 0));
}
pager.addOnPageChangeListener((OnPageSelectedListener) position -> {
AlertDialog dialog = ((AlertDialog) getDialog());
if (dialog != null) {
Button positive = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
Button negative = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
positive.clearFocus();
if (position == 0) {
positive.setText(R.string.next);
positive.setOnClickListener((View v) -> {
pager.setCurrentItem(2);
});
negative.setText(R.string.skip);
negative.setOnClickListener((View v) -> getDialog().dismiss());
}
if (position == 1) {
positive.setText("Start mapping!");
positive.setOnClickListener((View v) -> {
Context ctx = v.getContext();
if (ctx instanceof Main) {
getDialog().dismiss();
((Main) ctx).gotoCurrentLocation();
((Main) ctx).setFollowGPS(true);
}
});
negative.setText(R.string.back);
negative.setOnClickListener((View v) -> {
pager.setCurrentItem(0);
});
}
if (dialog == null) {
Log.e(DEBUG_TAG, "Dialog null");
return;
}
Button positive = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
Button negative = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
positive.clearFocus();
if (position == WELCOME_PAGE_INDEX) {
positive.setText(R.string.next);
positive.setOnClickListener((View v) -> pager.setCurrentItem(SETTINGS_PAGE_INDEX));
negative.setText(R.string.skip);
negative.setOnClickListener((View v) -> getDialog().dismiss());
}
if (position == SETTINGS_PAGE_INDEX) {
positive.setText(R.string.welcome_start);
positive.setOnClickListener((View v) -> {
((Main) activity).gotoCurrentLocation();
((Main) activity).setFollowGPS(true);

Preferences prefs = App.getPreferences(activity);
if (displayImagery.isChecked()) {
setBestBackground(activity);
}

prefs.setPanAndZoomAutoDownload(autoDownload.isChecked());

boolean penConfig = penSetup.isChecked();
prefs.setLargeDragArea(!penConfig);
prefs.setWayNodeDragging(penConfig);
prefs.setDataStyle(penConfig ? Preferences.DEFAULT_PEN_MAP_STYLE : Preferences.DEFAULT_MAP_STYLE);

((Main) activity).getMap().setPrefs(activity, prefs);

Newbie.dismissDialog(activity);

if (authorize.isChecked()) {
Authorize.startForResult(activity, null);
}
});
negative.setText(R.string.back);
negative.setOnClickListener((View v) -> pager.setCurrentItem(0));
}
});

String message = getString(R.string.welcome_message);
if (main.isFullScreen()) {
if (((Main) activity).isFullScreen()) {
message = message + getString(R.string.welcome_message_fullscreen);
}
((TextView) layout.findViewById(R.id.welcome_message)).setText(Util.fromHtml(message));
Expand All @@ -144,18 +188,47 @@ public AppCompatDialog onCreateDialog(Bundle savedInstanceState) {
dialog.setOnShowListener((DialogInterface d) -> {
Button neutral = dialog.getButton(DialogInterface.BUTTON_NEUTRAL);
neutral.setOnClickListener((View v) -> {
Context ctx = v.getContext();
Context ctx = getActivity();
if (ctx instanceof FragmentActivity) {
HelpViewer.start((FragmentActivity) ctx, R.string.help_introduction);
} else {
System.out.println("Not a fragment activity");
return;
}
Log.e(DEBUG_TAG, "Not a fragment activity");
});
Button positive = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positive.setOnClickListener((View v) -> {
pager.setCurrentItem(1);
});
positive.setOnClickListener((View v) -> pager.setCurrentItem(SETTINGS_PAGE_INDEX));
});
return dialog;
}

/**
* Set the best background for the current ViewBox
*
* @param activity the current activity
*/
private void setBestBackground(@NonNull final FragmentActivity activity) {
final String[] ids = TileLayerSource.getIds(App.getLogic().getMap().getViewBox(), true, Category.photo, null);
if (ids.length > 0) {
TileLayerSource tileSource = TileLayerSource.get(activity, ids[0], false);
MapTilesLayer<?> tileLayer = ((Main) activity).getMap().getBackgroundLayer();
tileLayer.setRendererInfo(tileSource);
try (AdvancedPrefDatabase db = new AdvancedPrefDatabase(activity)) {
db.setLayerContentId(tileLayer.getIndex(), tileSource.getId());
}
} else {
Log.w(DEBUG_TAG, "No applicable imagery found!");
}
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(DEBUG_TAG, "onSaveInstanceState");
Dialog dialog = getDialog();
outState.putBoolean(USE_IMAGERY_KEY, ((SwitchCompat) dialog.findViewById(R.id.use_imagery)).isChecked());
outState.putBoolean(AUTO_DOWNLOAD_KEY, ((SwitchCompat) dialog.findViewById(R.id.auto_download)).isChecked());
outState.putBoolean(PEN_SETUP_KEY, ((SwitchCompat) dialog.findViewById(R.id.pen_setup)).isChecked());
outState.putBoolean(AUTHORIZE_KEY, ((SwitchCompat) dialog.findViewById(R.id.authorize)).isChecked());
outState.putInt(PAGER_POS_KEY, ((ExtendedViewPager) dialog.findViewById(R.id.pager)).getCurrentItem());
}
}
29 changes: 25 additions & 4 deletions src/main/java/de/blau/android/prefs/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class Preferences {
private final boolean isAntiAliasingEnabled;
private final boolean isKeepScreenOnEnabled;
private final boolean useBackForUndo;
private final boolean largeDragArea;
private boolean largeDragArea;
private final boolean tagFormEnabled;
private String scaleLayer;
private String mapProfile;
Expand Down Expand Up @@ -122,7 +122,7 @@ public class Preferences {
private final int maxOffsetDistance;
private final Set<String> enabledValidations;
private final int autoNameCap;
private final boolean wayNodeDragging;
private boolean wayNodeDragging;
private final boolean splitWindowForPropertyEditor;
private final boolean useImperialUnits;
private final boolean supportPresetLabels;
Expand All @@ -140,7 +140,8 @@ public class Preferences {
private final double maxCircleSegment;
private final double minCircleSegment;

private static final String DEFAULT_MAP_PROFILE = "Color Round Nodes";
public static final String DEFAULT_MAP_STYLE = "Color Round Nodes";
public static final String DEFAULT_PEN_MAP_STYLE = "Pen Round Nodes";

private final SharedPreferences prefs;

Expand Down Expand Up @@ -434,6 +435,16 @@ public boolean largeDragArea() {
return largeDragArea;
}

/**
* Enable or disable the large drag area
*
* @param enabled if true enable the large drag area
*/
public void setLargeDragArea(boolean enabled) {
largeDragArea = enabled;
prefs.edit().putBoolean(r.getString(R.string.config_largeDragArea_key), enabled).commit();
}

/**
* Get kind of scale that should be displayed
*
Expand Down Expand Up @@ -463,7 +474,7 @@ public String getDataStyle() {
// check if we actually still have the profile
if (DataStyle.getStyle(mapProfile) == null) {
Log.w(DEBUG_TAG, "Style " + mapProfile + " missing, replacing by default");
setDataStyle(DataStyle.getStyle(DEFAULT_MAP_PROFILE) == null ? DataStyle.getBuiltinStyleName() : DEFAULT_MAP_PROFILE);
setDataStyle(DataStyle.getStyle(DEFAULT_MAP_STYLE) == null ? DataStyle.getBuiltinStyleName() : DEFAULT_MAP_STYLE);
}
return mapProfile;
}
Expand Down Expand Up @@ -1674,6 +1685,16 @@ public boolean isWayNodeDraggingEnabled() {
return wayNodeDragging;
}

/**
* Enable or disable the way node dragging
*
* @param enabled if true enable way node dragging
*/
public void setWayNodeDragging(boolean enabled) {
wayNodeDragging = enabled;
prefs.edit().putBoolean(r.getString(R.string.config_wayNodeDragging_key), enabled).commit();
}

/**
* Check if we should try to use split window functionality for the PropertyEditor
*
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/blau/android/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ public void handleTag(boolean opening, String tag, Editable output, XMLReader xm
output.append("\n");
}
if ("li".equals(tag) && opening) {
output.append("\n\t");
output.append("\n\t<b>&bull;</b>");
}
}
}
Expand Down
Loading

0 comments on commit 9b5bbf7

Please sign in to comment.