Add "Download Map" Top Sheet card

This commit is contained in:
Nazar 2019-09-19 20:11:10 +03:00
parent 27614fb0d8
commit 609f4d45ae
32 changed files with 613 additions and 54 deletions

View file

@ -707,6 +707,10 @@ public class OsmandRegions {
public BinaryMapDataObject getSmallestBinaryMapDataObjectAt(LatLon latLon) throws IOException { public BinaryMapDataObject getSmallestBinaryMapDataObjectAt(LatLon latLon) throws IOException {
List<BinaryMapDataObject> mapDataObjects = getBinaryMapDataObjectsAt(latLon); List<BinaryMapDataObject> mapDataObjects = getBinaryMapDataObjectsAt(latLon);
return getSmallestBinaryMapDataObjectAt(mapDataObjects);
}
public BinaryMapDataObject getSmallestBinaryMapDataObjectAt(List<BinaryMapDataObject> mapDataObjects) throws IOException {
BinaryMapDataObject res = null; BinaryMapDataObject res = null;
double smallestArea = -1; double smallestArea = -1;
for (BinaryMapDataObject o : mapDataObjects) { for (BinaryMapDataObject o : mapDataObjects) {

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="-100%p" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="0" android:toYDelta="-100%p"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_dialogtop_portrait" />
</item>
<item>
<shape>
<solid android:color="@color/list_background_color_dark" />
<corners android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_dialogtop_portrait" />
</item>
<item>
<shape>
<solid android:color="@color/list_background_color_light" />
<corners android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_dialogtop_landscape"/>
</item>
<item>
<shape>
<solid android:color="@color/list_background_color_dark"/>
<corners android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_dialogtop_landscape"/>
</item>
<item>
<shape>
<solid android:color="@color/list_background_color_light"/>
<corners android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
</item>
</layer-list>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/touch_outside"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"/>
</android.support.design.widget.CoordinatorLayout>

View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:background="?attr/list_background_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/list_content_padding"
android:layout_marginRight="@dimen/list_content_padding"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
osmand:typeface="@string/font_roboto_regular"
android:layout_marginTop="@dimen/list_content_padding"
android:layout_weight="1"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/download_detaile_map" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/card_content_padding_large"
android:src="@drawable/img_download" />
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/fileSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
osmand:typeface="@string/font_roboto_medium"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
tools:text="139mb" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginBottom="@dimen/content_padding_small">
<include
android:id="@+id/btnClose"
layout="@layout/bottom_sheet_dialog_button" />
<View
android:id="@+id/buttons_divider"
android:layout_width="@dimen/content_padding"
android:layout_height="match_parent" />
<include
android:id="@+id/btnDownload"
layout="@layout/bottom_sheet_dialog_button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -13,6 +13,8 @@
<dimen name="map_route_planning_land_width">510dp</dimen> <dimen name="map_route_planning_land_width">510dp</dimen>
<dimen name="map_route_planning_land_width_minus_shadow">496dp</dimen> <dimen name="map_route_planning_land_width_minus_shadow">496dp</dimen>
<dimen name="card_content_padding_large">42dp</dimen>
<dimen name="map_address_height">60dp</dimen> <dimen name="map_address_height">60dp</dimen>
<dimen name="map_button_size">78dp</dimen> <dimen name="map_button_size">78dp</dimen>
<dimen name="map_small_button_size">66dp</dimen> <dimen name="map_small_button_size">66dp</dimen>

View file

@ -19,6 +19,8 @@
<dimen name="card_button_progress_size_small">24dp</dimen> <dimen name="card_button_progress_size_small">24dp</dimen>
<dimen name="card_padding">12dp</dimen> <dimen name="card_padding">12dp</dimen>
<dimen name="dlg_button_rect_rad">3dp</dimen> <dimen name="dlg_button_rect_rad">3dp</dimen>
<dimen name="card_content_padding_large">28dp</dimen>
<dimen name="widget_turn_lane_size">36dp</dimen> <dimen name="widget_turn_lane_size">36dp</dimen>
<dimen name="widget_turn_lane_border">6dp</dimen> <dimen name="widget_turn_lane_border">6dp</dimen>

View file

@ -13,6 +13,7 @@
--> -->
<string name="plugins_settings">Plugin settings</string> <string name="plugins_settings">Plugin settings</string>
<string name="logcat_buffer">Logcat buffer</string> <string name="logcat_buffer">Logcat buffer</string>
<string name="download_detaile_map">Download detailed %s map, to view this area.</string>
<string name="application_profile_changed">Application profile changed to \"%s\"</string> <string name="application_profile_changed">Application profile changed to \"%s\"</string>
<string name="switch_profile">Switch profile</string> <string name="switch_profile">Switch profile</string>
<string name="configure_profile">Configure profile</string> <string name="configure_profile">Configure profile</string>

View file

@ -647,6 +647,11 @@
<item name="android:windowExitAnimation">@anim/shrink_from_top</item> <item name="android:windowExitAnimation">@anim/shrink_from_top</item>
</style> </style>
<style name="Animations.PopUpMenu.Top">
<item name="android:windowEnterAnimation">@anim/slide_in_top</item>
<item name="android:windowExitAnimation">@anim/slide_out_top</item>
</style>
<style name="Animations.PopUpMenu.Bottom"> <style name="Animations.PopUpMenu.Bottom">
<item name="android:windowEnterAnimation">@anim/slide_in_bottom</item> <item name="android:windowEnterAnimation">@anim/slide_in_bottom</item>
<item name="android:windowExitAnimation">@anim/slide_out_bottom</item> <item name="android:windowExitAnimation">@anim/slide_out_bottom</item>

View file

@ -500,6 +500,7 @@ public class AppInitializer implements IProgress {
app.travelDbHelper = startupInit(app.travelDbHelper, TravelDbHelper.class); app.travelDbHelper = startupInit(app.travelDbHelper, TravelDbHelper.class);
app.lockHelper = startupInit(new LockHelper(app), LockHelper.class); app.lockHelper = startupInit(new LockHelper(app), LockHelper.class);
app.getDownloadThread().runReloadIndexFiles();
initOpeningHoursParser(); initOpeningHoursParser();
} }

View file

@ -133,7 +133,7 @@ public class MapActivityLayers {
mapVectorLayer = new MapVectorLayer(mapTileLayer, false); mapVectorLayer = new MapVectorLayer(mapTileLayer, false);
mapView.addLayer(mapVectorLayer, 0.5f); mapView.addLayer(mapVectorLayer, 0.5f);
downloadedRegionsLayer = new DownloadedRegionsLayer(); downloadedRegionsLayer = new DownloadedRegionsLayer(activity);
mapView.addLayer(downloadedRegionsLayer, 0.5f); mapView.addLayer(downloadedRegionsLayer, 0.5f);
// 0.9 gpx layer // 0.9 gpx layer

View file

@ -11,10 +11,10 @@ import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import java.text.MessageFormat; import java.text.MessageFormat;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
public class OsmandRestoreOrExitDialog extends BottomSheetDialogFragment { public class OsmandRestoreOrExitDialog extends OsmAndSheetDialogFragment {
private String clientAppTitle = ""; private String clientAppTitle = "";

View file

@ -33,7 +33,7 @@ import net.osmand.plus.helpers.AndroidUiHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFragment { public abstract class MenuBottomSheetDialogFragment extends OsmAndSheetDialogFragment {
private static final String USED_ON_MAP_KEY = "used_on_map"; private static final String USED_ON_MAP_KEY = "used_on_map";
private static final int DEFAULT_VALUE = -1; private static final int DEFAULT_VALUE = -1;

View file

@ -10,6 +10,7 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -20,7 +21,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
public abstract class BottomSheetDialogFragment extends DialogFragment { public abstract class OsmAndSheetDialogFragment extends DialogFragment {
private OnDialogFragmentResultListener dialogFragmentResultListener; private OnDialogFragmentResultListener dialogFragmentResultListener;
@ -32,13 +33,13 @@ public abstract class BottomSheetDialogFragment extends DialogFragment {
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
int themeId = settings.isLightContent() ? R.style.OsmandLightTheme_BottomSheet : R.style.OsmandDarkTheme_BottomSheet; int themeId = settings.isLightContent() ? R.style.OsmandLightTheme_BottomSheet : R.style.OsmandDarkTheme_BottomSheet;
BottomSheetDialog dialog = new BottomSheetDialog(context, themeId); OsmandSheetDialog dialog = new OsmandSheetDialog(context, themeId, getSheetDialogType());
dialog.setCanceledOnTouchOutside(true); dialog.setCanceledOnTouchOutside(getCancelOnTouchOutside());
dialog.setInteractWithOutside(getInteractWithOutside());
Window window = dialog.getWindow(); Window window = dialog.getWindow();
if (!settings.DO_NOT_USE_ANIMATIONS.get() && window != null) { if (window != null && !settings.DO_NOT_USE_ANIMATIONS.get()) {
window.getAttributes().windowAnimations = R.style.Animations_PopUpMenu_Bottom; window.getAttributes().windowAnimations = getSheetDialogType().getAnimationStyleResId();
} }
return dialog; return dialog;
} }
@ -60,6 +61,16 @@ public abstract class BottomSheetDialogFragment extends DialogFragment {
dialogFragmentResultListener = null; dialogFragmentResultListener = null;
} }
@Override
public void onStart() {
super.onStart();
final Window window = getDialog().getWindow();
FragmentActivity activity = requireActivity();
if (window != null) {
window.setDimAmount(getBackgroundDimAmount());
}
}
@Nullable @Nullable
public OnDialogFragmentResultListener getResultListener() { public OnDialogFragmentResultListener getResultListener() {
return dialogFragmentResultListener; return dialogFragmentResultListener;
@ -99,4 +110,20 @@ public abstract class BottomSheetDialogFragment extends DialogFragment {
return null; return null;
} }
} }
protected SheetDialogType getSheetDialogType() {
return SheetDialogType.BOTTOM;
}
protected boolean getCancelOnTouchOutside() {
return true;
}
protected boolean getInteractWithOutside() {
return false;
}
protected float getBackgroundDimAmount() {
return 0.3f;
}
} }

View file

@ -1,5 +1,6 @@
package net.osmand.plus.base; package net.osmand.plus.base;
import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
@ -7,8 +8,10 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
@ -16,22 +19,28 @@ import android.widget.FrameLayout;
import net.osmand.plus.R; import net.osmand.plus.R;
public class BottomSheetDialog extends Dialog { import static net.osmand.plus.base.SheetDialogType.*;
public class OsmandSheetDialog extends Dialog {
private boolean cancelable = true; private boolean cancelable = true;
private boolean canceledOnTouchOutside = true; private boolean canceledOnTouchOutside = true;
private boolean interactWithOutside = false;
private boolean canceledOnTouchOutsideSet; private boolean canceledOnTouchOutsideSet;
private SheetDialogType dialogType;
public BottomSheetDialog(@NonNull Context context) { public OsmandSheetDialog(@NonNull Context context) {
this(context, 0); this(context, 0, BOTTOM);
} }
public BottomSheetDialog(@NonNull Context context, int themeResId) { public OsmandSheetDialog(@NonNull Context context, int themeResId, SheetDialogType dialogType) {
super(context, themeResId); super(context, themeResId);
this.dialogType = dialogType;
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
} }
protected BottomSheetDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) { protected OsmandSheetDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
super(context, cancelable, cancelListener); super(context, cancelable, cancelListener);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
this.cancelable = cancelable; this.cancelable = cancelable;
@ -80,11 +89,23 @@ public class BottomSheetDialog extends Dialog {
canceledOnTouchOutside = cancel; canceledOnTouchOutside = cancel;
canceledOnTouchOutsideSet = true; canceledOnTouchOutsideSet = true;
} }
public void setInteractWithOutside(boolean interactWithOutside) {
this.interactWithOutside = interactWithOutside;
}
@NonNull @NonNull
private View wrapInContainer(int layoutResId, View view, LayoutParams params) { private View wrapInContainer(int layoutResId, View view, LayoutParams params) {
final View res = View.inflate(getContext(), R.layout.bottom_sheet_dialog, null); final FrameLayout res = new FrameLayout(getContext());
final FrameLayout container = (FrameLayout) res.findViewById(R.id.content_container); final View touchOutside = new View(getContext());
final FrameLayout container = getContainer(dialogType);
ViewGroup.LayoutParams fullScreenParams = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
res.setLayoutParams(fullScreenParams);
touchOutside.setLayoutParams(fullScreenParams);
res.addView(touchOutside);
res.addView(container);
if (layoutResId != 0 && view == null) { if (layoutResId != 0 && view == null) {
view = getLayoutInflater().inflate(layoutResId, container, false); view = getLayoutInflater().inflate(layoutResId, container, false);
@ -95,7 +116,7 @@ public class BottomSheetDialog extends Dialog {
container.addView(view, params); container.addView(view, params);
} }
res.findViewById(R.id.touch_outside).setOnClickListener(new View.OnClickListener() { touchOutside.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (cancelable && isShowing() && shouldWindowCloseOnTouchOutside()) { if (cancelable && isShowing() && shouldWindowCloseOnTouchOutside()) {
@ -103,6 +124,19 @@ public class BottomSheetDialog extends Dialog {
} }
} }
}); });
touchOutside.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (interactWithOutside) {
Activity ownerActivity = getOwnerActivity();
if (ownerActivity != null) {
ownerActivity.dispatchTouchEvent(event);
}
}
return false;
}
});
container.setOnTouchListener(new View.OnTouchListener() { container.setOnTouchListener(new View.OnTouchListener() {
@Override @Override
@ -114,6 +148,28 @@ public class BottomSheetDialog extends Dialog {
return res; return res;
} }
private FrameLayout getContainer(SheetDialogType dialogType) {
if (dialogType == null) {
return null;
}
int width = LayoutParams.MATCH_PARENT;
int height = LayoutParams.WRAP_CONTENT;
int gravity = 0;
switch (dialogType) {
case TOP:
gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
break;
case BOTTOM:
gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
break;
}
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);
params.gravity = gravity;
FrameLayout container = new FrameLayout(getContext());
container.setLayoutParams(params);
return container;
}
private boolean shouldWindowCloseOnTouchOutside() { private boolean shouldWindowCloseOnTouchOutside() {
if (!canceledOnTouchOutsideSet) { if (!canceledOnTouchOutsideSet) {

View file

@ -0,0 +1,19 @@
package net.osmand.plus.base;
import net.osmand.plus.R;
public enum SheetDialogType {
TOP(R.style.Animations_PopUpMenu_Top),
BOTTOM(R.style.Animations_PopUpMenu_Bottom);
SheetDialogType(int animationStyleResId) {
this.animationStyleResId = animationStyleResId;
}
private int animationStyleResId;
public int getAnimationStyleResId() {
return animationStyleResId;
}
}

View file

@ -15,11 +15,11 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import java.util.Calendar; import java.util.Calendar;
public class RateUsBottomSheetDialog extends BottomSheetDialogFragment { public class RateUsBottomSheetDialog extends OsmAndSheetDialogFragment {
private RateUsBottomSheetDialog.FragmentState state = RateUsBottomSheetDialog.FragmentState.INITIAL_STATE; private RateUsBottomSheetDialog.FragmentState state = RateUsBottomSheetDialog.FragmentState.INITIAL_STATE;
@Nullable @Nullable
@Override @Override

View file

@ -50,7 +50,7 @@ import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TabActivity; import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.base.BasicProgressAsyncTask; import net.osmand.plus.base.BasicProgressAsyncTask;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment; import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment;
@ -708,7 +708,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
public static class AskMapDownloadFragment extends BottomSheetDialogFragment { public static class AskMapDownloadFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "AskMapDownloadFragment"; public static final String TAG = "AskMapDownloadFragment";
private static final String KEY_ASK_MAP_DOWNLOAD_ITEM_FILENAME = "key_ask_map_download_item_filename"; private static final String KEY_ASK_MAP_DOWNLOAD_ITEM_FILENAME = "key_ask_map_download_item_filename";
@ -790,7 +790,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
public static class GoToMapFragment extends BottomSheetDialogFragment { public static class GoToMapFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "GoToMapFragment"; public static final String TAG = "GoToMapFragment";
private static final String KEY_GOTO_MAP_REGION_CENTER = "key_goto_map_region_center"; private static final String KEY_GOTO_MAP_REGION_CENTER = "key_goto_map_region_center";

View file

@ -24,14 +24,14 @@ import net.osmand.plus.OnDismissDialogFragmentListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.dashboard.DashChooseAppDirFragment; import net.osmand.plus.dashboard.DashChooseAppDirFragment;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread;
import java.io.File; import java.io.File;
public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment { public class DataStoragePlaceDialogFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "DataStoragePlaceDialogFragment"; public static final String TAG = "DataStoragePlaceDialogFragment";
private static final String STORAGE_READOLNY_KEY = "storage_readolny_key"; private static final String STORAGE_READOLNY_KEY = "storage_readolny_key";

View file

@ -0,0 +1,211 @@
package net.osmand.plus.download.ui;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.base.SheetDialogType;
import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
public class DownloadMapDialogFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "DownloadMapDialogFragment";
private final static String USED_ON_MAP = "USED_ON_MAP";
private final static String REGION_NAME = "REGION_NAME";
protected DownloadValidationManager downloadValidationManager;
protected boolean usedOnMap;
protected boolean nightMode;
private View btnClose;
private View btnDownload;
private TextView tvDescription;
private TextView tvSize;
private IndexItem currentIndexItem;
private String currentRegionName;
private String sizeDescription;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
readBundle(getArguments());
nightMode = isNightMode(getMyApplication());
View mainView = View.inflate(new ContextThemeWrapper(getContext(), nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme), R.layout.card_download_detailed_map, null);
if (!AndroidUiHelper.isOrientationPortrait(requireActivity())) {
mainView.setBackgroundResource(getLandscapeBottomSidesBgResId());
} else {
mainView.setBackgroundResource(getPortraitBgResId());
}
downloadValidationManager = new DownloadValidationManager(getMyApplication());
tvDescription = mainView.findViewById(R.id.description);
tvSize = mainView.findViewById(R.id.fileSize);
btnClose = mainView.findViewById(R.id.btnClose);
btnDownload = mainView.findViewById(R.id.btnDownload);
UiUtilities.setupDialogButton(nightMode, btnClose, UiUtilities.DialogButtonType.SECONDARY, getString(R.string.shared_string_close));
UiUtilities.setupDialogButton(nightMode, btnDownload, UiUtilities.DialogButtonType.PRIMARY, getString(R.string.shared_string_download));
refreshView();
return mainView;
}
@Override
public void onStart() {
super.onStart();
final Window window = getDialog().getWindow();
FragmentActivity activity = requireActivity();
if (window != null && !AndroidUiHelper.isOrientationPortrait(activity)) {
WindowManager.LayoutParams params = window.getAttributes();
params.width = activity.getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
public void refreshData(final String newRegionName, final IndexItem newIndexItem) {
getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
currentRegionName = newRegionName;
currentIndexItem = newIndexItem;
refreshView();
}
});
}
private void refreshView() {
if (currentRegionName != null) {
String descriptionText = String.format(getString(R.string.download_detaile_map), currentRegionName);
int startIndex = descriptionText.indexOf(currentRegionName);
int endIndex = startIndex + currentRegionName.length();
SpannableStringBuilder description = new SpannableStringBuilder(descriptionText);
Typeface typeface = FontCache.getRobotoMedium(getMyApplication());
description.setSpan(new CustomTypefaceSpan(typeface), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvDescription.setText(description);
}
if (currentIndexItem != null) {
String size = currentIndexItem.getSizeDescription(getMyApplication()).toLowerCase();
tvSize.setText(size);
btnDownload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downloadValidationManager.startDownload(getActivity(), currentIndexItem);
dismiss();
}
});
}
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
}
protected void readBundle(Bundle bundle) {
if (bundle != null) {
usedOnMap = bundle.getBoolean(USED_ON_MAP);
currentRegionName = bundle.getString(REGION_NAME);
}
}
public static DownloadMapDialogFragment newInstance(FragmentManager fragmentManager, IndexItem indexItem, String name, boolean usedOnMap) {
Bundle bundle = new Bundle();
bundle.putString(REGION_NAME, name);
bundle.putBoolean(USED_ON_MAP, usedOnMap);
DownloadMapDialogFragment fragment = new DownloadMapDialogFragment();
fragment.setArguments(bundle);
fragment.setCurrentIndexItem(indexItem);
return fragment;
}
public static void showInstance(FragmentManager fragmentManager, IndexItem indexItem, String name, boolean usedOnMap) {
DownloadMapDialogFragment fragment = newInstance(fragmentManager, indexItem, name, usedOnMap);
fragmentManager.beginTransaction()
.add(fragment, TAG).commitAllowingStateLoss();
}
public static void hideInstance(FragmentManager fragmentManager) {
DownloadMapDialogFragment fragment = (DownloadMapDialogFragment) fragmentManager.findFragmentByTag(TAG);
if (fragment != null) {
fragment.dismiss();
}
}
private boolean isNightMode(@NonNull OsmandApplication app) {
if (usedOnMap) {
return app.getDaynightHelper().isNightModeForMapControls();
}
return !app.getSettings().isLightContent();
}
@Override
protected SheetDialogType getSheetDialogType() {
return SheetDialogType.TOP;
}
public void setCurrentIndexItem(IndexItem currentIndexItem) {
this.currentIndexItem = currentIndexItem;
}
@DrawableRes
protected int getPortraitBgResId() {
return nightMode ? R.drawable.bg_top_menu_dark : R.drawable.bg_top_menu_light;
}
@DrawableRes
protected int getLandscapeBottomSidesBgResId() {
return nightMode ? R.drawable.bg_top_sheet_bottom_sides_landscape_dark : R.drawable.bg_top_sheet_bottom_sides_landscape_light;
}
@Override
protected boolean getCancelOnTouchOutside() {
return false;
}
@Override
protected boolean getInteractWithOutside() {
return true;
}
@Override
protected float getBackgroundDimAmount() {
return 0;
}
}

View file

@ -0,0 +1,35 @@
package net.osmand.plus.download.ui;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.ui.DownloadMapDialogFragment;
public class DownloadMapDialogManager {
private IndexItem currentIndexItem;
public void showDialog(AppCompatActivity activity, IndexItem newIndexItem, String newRegionName, boolean usedOnMap) {
if (newIndexItem != null) {
if (!newIndexItem.equals(this.currentIndexItem)) {
currentIndexItem = newIndexItem;
FragmentManager fragmentManager = activity.getSupportFragmentManager();
DownloadMapDialogFragment dialogFragment =
(DownloadMapDialogFragment) fragmentManager.findFragmentByTag(DownloadMapDialogFragment.TAG);
if (dialogFragment != null) {
//refresh dialog data
dialogFragment.refreshData(newRegionName, newIndexItem);
} else {
//create a new dialog
DownloadMapDialogFragment.showInstance(activity.getSupportFragmentManager(), newIndexItem, newRegionName, usedOnMap);
}
}
}
}
public void hideDialog(AppCompatActivity activity) {
currentIndexItem = null;
DownloadMapDialogFragment.hideInstance(activity.getSupportFragmentManager());
}
}

View file

@ -22,11 +22,12 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem; import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.widgets.tools.ExtendedBottomSheetBehavior; import net.osmand.plus.widgets.tools.ExtendedBottomSheetBehavior;
import net.osmand.plus.widgets.tools.ExtendedBottomSheetBehavior.BottomSheetCallback; import net.osmand.plus.widgets.tools.ExtendedBottomSheetBehavior.BottomSheetCallback;
public class AdditionalActionsBottomSheetDialogFragment extends net.osmand.plus.base.BottomSheetDialogFragment { public class AdditionalActionsBottomSheetDialogFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "AdditionalActionsBottomSheetDialogFragment"; public static final String TAG = "AdditionalActionsBottomSheetDialogFragment";

View file

@ -26,7 +26,7 @@ import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivityLayers; import net.osmand.plus.activities.MapActivityLayers;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.views.MapInfoLayer; import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.MapTileLayer; import net.osmand.plus.views.MapTileLayer;
@ -272,7 +272,7 @@ public class MapillaryPlugin extends OsmandPlugin {
return false; return false;
} }
public static class MapillaryFirstDialogFragment extends BottomSheetDialogFragment { public static class MapillaryFirstDialogFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "MapillaryFirstDialogFragment"; public static final String TAG = "MapillaryFirstDialogFragment";
private static final String KEY_SHOW_WIDGET = "key_show_widget"; private static final String KEY_SHOW_WIDGET = "key_show_widget";

View file

@ -15,10 +15,10 @@ import android.widget.ImageView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment { public class OptionsBottomSheetDialogFragment extends OsmAndSheetDialogFragment {
public final static String TAG = "OptionsBottomSheetDialogFragment"; public final static String TAG = "OptionsBottomSheetDialogFragment";
public final static String GROUPS_MARKERS_MENU = "groups_markers_menu"; public final static String GROUPS_MARKERS_MENU = "groups_markers_menu";

View file

@ -24,7 +24,7 @@ import net.osmand.IndexConstants;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.widgets.OsmandTextFieldBoxes; import net.osmand.plus.widgets.OsmandTextFieldBoxes;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import java.io.File; import java.io.File;
@ -33,7 +33,7 @@ import java.util.Date;
import static net.osmand.plus.helpers.ImportHelper.GPX_SUFFIX; import static net.osmand.plus.helpers.ImportHelper.GPX_SUFFIX;
import static net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY; import static net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY;
public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragment { public class SaveAsTrackBottomSheetDialogFragment extends OsmAndSheetDialogFragment {
public final static String TAG = "SaveAsTrackBottomSheetDialogFragment"; public final static String TAG = "SaveAsTrackBottomSheetDialogFragment";
public static final String COORDINATE_INPUT_MODE_KEY = "coordinate_input_mode_key"; public static final String COORDINATE_INPUT_MODE_KEY = "coordinate_input_mode_key";

View file

@ -19,11 +19,11 @@ import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.myplaces.AvailableGPXFragment; import net.osmand.plus.myplaces.AvailableGPXFragment;
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo; import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
public class OnSaveCurrentTrackFragment extends BottomSheetDialogFragment { public class OnSaveCurrentTrackFragment extends OsmAndSheetDialogFragment {
public static final String TAG = "OnSaveCurrentTrackBottomSheetFragment"; public static final String TAG = "OnSaveCurrentTrackBottomSheetFragment";
public static final String SAVED_TRACK_KEY = "saved_track_filename"; public static final String SAVED_TRACK_KEY = "saved_track_filename";

View file

@ -8,6 +8,7 @@ import android.graphics.Paint.Join;
import android.graphics.Paint.Style; import android.graphics.Paint.Style;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.text.TextPaint; import android.text.TextPaint;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.WindowManager; import android.view.WindowManager;
@ -26,6 +27,8 @@ import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.ui.DownloadMapDialogManager;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu; import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu;
@ -51,6 +54,8 @@ public class DownloadedRegionsLayer extends OsmandMapLayer implements IContextMe
private OsmandApplication app; private OsmandApplication app;
private OsmandMapTileView view; private OsmandMapTileView view;
private AppCompatActivity mapActivity;
private DownloadMapDialogManager downloadDialogManager;
private Paint paintDownloaded; private Paint paintDownloaded;
private Path pathDownloaded; private Path pathDownloaded;
private Paint paintSelected; private Paint paintSelected;
@ -73,6 +78,13 @@ public class DownloadedRegionsLayer extends OsmandMapLayer implements IContextMe
private static int ZOOM_TO_SHOW_BORDERS = 7; private static int ZOOM_TO_SHOW_BORDERS = 7;
private static int ZOOM_TO_SHOW_SELECTION_ST = 3; private static int ZOOM_TO_SHOW_SELECTION_ST = 3;
private static int ZOOM_TO_SHOW_SELECTION = 8; private static int ZOOM_TO_SHOW_SELECTION = 8;
private static int ZOOM_MIN_TO_SHOW_DOWNLOAD_DIALOG = 9;
private static int ZOOM_MAX_TO_SHOW_DOWNLOAD_DIALOG = 11;
public DownloadedRegionsLayer(AppCompatActivity activity) {
this.mapActivity = activity;
this.downloadDialogManager = new DownloadMapDialogManager();
}
public static class DownloadMapObject { public static class DownloadMapObject {
private BinaryMapDataObject dataObject; private BinaryMapDataObject dataObject;
@ -180,6 +192,10 @@ public class DownloadedRegionsLayer extends OsmandMapLayer implements IContextMe
if(zoom < ZOOM_TO_SHOW_SELECTION_ST) { if(zoom < ZOOM_TO_SHOW_SELECTION_ST) {
return; return;
} }
//check has location got a map to download
checkMapToDownload(zoom, data.results);
// draw objects // draw objects
if (osmandRegions.isInitialized() && zoom >= ZOOM_TO_SHOW_SELECTION_ST && zoom < ZOOM_TO_SHOW_SELECTION) { if (osmandRegions.isInitialized() && zoom >= ZOOM_TO_SHOW_SELECTION_ST && zoom < ZOOM_TO_SHOW_SELECTION) {
final List<BinaryMapDataObject> currentObjects = new LinkedList<>(); final List<BinaryMapDataObject> currentObjects = new LinkedList<>();
@ -332,6 +348,61 @@ public class DownloadedRegionsLayer extends OsmandMapLayer implements IContextMe
return empty; return empty;
} }
private void checkMapToDownload(int zoom, List<BinaryMapDataObject> currentObjects) {
boolean found = false;
if (zoom >= ZOOM_MIN_TO_SHOW_DOWNLOAD_DIALOG && zoom <= ZOOM_MAX_TO_SHOW_DOWNLOAD_DIALOG
&& currentObjects != null) {
IndexItem indexItem = null;
String name = null;
WorldRegion regionData = null;
int cx = view.getCurrentRotatedTileBox().getCenter31X();
int cy = view.getCurrentRotatedTileBox().getCenter31Y();
for (int i = 0; i < currentObjects.size(); i++) {
final BinaryMapDataObject o = currentObjects.get(i);
if (!osmandRegions.contain(o, cx, cy)) {
continue;
}
String fullName = osmandRegions.getFullName(o);
regionData = osmandRegions.getRegionData(fullName);
if (regionData != null && regionData.isRegionMapDownload()) {
String regionDownloadName = regionData.getRegionDownloadName();
if (regionDownloadName != null && checkIfObjectDownloaded(regionDownloadName)) {
downloadDialogManager.hideDialog(getActivity());
return;
}
}
}
BinaryMapDataObject smallestRegion = null;
try {
smallestRegion = app.getRegions().getSmallestBinaryMapDataObjectAt(currentObjects);
} catch (IOException e) {
downloadDialogManager.hideDialog(mapActivity);
}
String fullName = osmandRegions.getFullName(smallestRegion);
regionData = osmandRegions.getRegionData(fullName);
DownloadIndexesThread downloadThread = app.getDownloadThread();
List<IndexItem> indexItems = downloadThread.getIndexes().getIndexItems(regionData);
for (IndexItem item : indexItems) {
if (item.getType() == DownloadActivityType.NORMAL_FILE
&& !(item.isDownloaded() || downloadThread.isDownloading(item))) {
found = true;
indexItem = item;
name = regionData.getLocaleName();
break;
}
}
if (found) {
downloadDialogManager.showDialog(getActivity(), indexItem, name, true);
} else {
downloadDialogManager.hideDialog(getActivity());
}
} else {
downloadDialogManager.hideDialog(getActivity());
}
}
@Override @Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) { public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
if(view.getMainLayer() instanceof MapTileLayer) { if(view.getMainLayer() instanceof MapTileLayer) {
@ -556,5 +627,9 @@ public class DownloadedRegionsLayer extends OsmandMapLayer implements IContextMe
public void clearSelectedObject() { public void clearSelectedObject() {
selectedObjects = new LinkedList<>(); selectedObjects = new LinkedList<>();
} }
protected AppCompatActivity getActivity() {
return mapActivity;
}
} }

View file

@ -19,10 +19,10 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings.WikiArticleShowImages; import net.osmand.plus.OsmandSettings.WikiArticleShowImages;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.OsmAndSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
public class WikivoyageShowPicturesDialogFragment extends BottomSheetDialogFragment { public class WikivoyageShowPicturesDialogFragment extends OsmAndSheetDialogFragment {
public static final String TAG = WikivoyageShowPicturesDialogFragment.class.getSimpleName(); public static final String TAG = WikivoyageShowPicturesDialogFragment.class.getSimpleName();