terrain ui work in progress

This commit is contained in:
veliymolfar 2020-03-06 18:51:04 +02:00
parent 5d2bfca53e
commit 65d9f5f910
9 changed files with 349 additions and 109 deletions

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/terrain_empty_hint_bg" />
<corners android:radius="3dp" />
</shape>
</item>
</selector>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -9,7 +10,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
@ -173,11 +174,20 @@
</LinearLayout>
<androidx.appcompat.widget.AppCompatSeekBar
<com.google.android.material.slider.Slider
android:id="@+id/transparency_slider"
style="@style/Widget.MaterialComponents.Slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_header_settings_top_margin" />
android:layout_marginTop="@dimen/list_header_settings_top_margin"
android:stepSize="1"
android:theme="@style/Theme.MaterialComponents"
android:valueFrom="0"
android:valueTo="100"
app:haloRadius="@dimen/slider_thumb_halo_size"
app:thumbRadius="@dimen/slider_thumb_size"
app:tickColor="@android:color/transparent"
app:trackHeight="@dimen/slider_track_height" />
<View
android:layout_width="match_parent"
@ -228,6 +238,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding">
@ -242,17 +253,24 @@
tools:text="3" />
<com.google.android.material.slider.Slider
android:id="@+id/zoom_slider"
style="@style/Widget.MaterialComponents.Slider"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_weight="1" />
android:layout_weight="1"
android:stepSize="1"
android:theme="@style/Theme.MaterialComponents"
android:valueFrom="2"
android:valueTo="22"
app:haloRadius="@dimen/slider_thumb_halo_size"
app:thumbRadius="@dimen/slider_thumb_size"
app:trackHeight="@dimen/slider_track_height" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/zoom_value_max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:gravity="end"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="19" />
@ -358,16 +376,72 @@
android:background="?attr/bg_color"
android:orientation="vertical">
<ImageView
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding_small">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/empty_state_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/img_empty_state_terrain" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:layout_margin="@dimen/content_padding_half"
android:background="@drawable/bg_dark_transp"
android:gravity="start|bottom"
android:padding="@dimen/map_button_margin"
android:text="@string/shared_string_hillshade"
android:textColor="@color/color_white" />
</FrameLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:layout_margin="@dimen/content_padding_half"
android:background="@drawable/bg_dark_transp"
android:gravity="start|bottom"
android:padding="@dimen/map_button_margin"
android:text="@string/shared_string_slope"
android:textColor="@color/color_white" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/empty_state_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding"
android:gravity="start"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="@string/terrain_empty_state_text" />

View file

@ -460,5 +460,6 @@
<color name="terrain_active_button">#1A237BFF</color>
<color name="terrain_active_button_stroke">#80237BFF</color>
<color name="terrain_empty_hint_bg">#80000000</color>
</resources>

View file

@ -127,7 +127,6 @@
<dimen name="map_minwidth_widget">100dp</dimen>
<dimen name="map_widget_text_size">23sp</dimen>
<dimen name="map_top_widget_text_size">22sp</dimen>
<dimen name="map_widget_text_size_small">15sp</dimen>
@ -356,4 +355,8 @@
<dimen name="setting_list_item_large_height">72dp</dimen>
<dimen name="setting_list_item_small_height">42dp</dimen>
<dimen name="slider_thumb_size">8dp</dimen>
<dimen name="slider_thumb_halo_size">12dp</dimen>
<dimen name="slider_track_height">2dp</dimen>
</resources>

View file

@ -16,7 +16,7 @@
<string name="saving_new_profile">Saving new profile</string>
<string name="profile_backup_failed">Could not back up profile.</string>
<string name="shared_string_hillshade">Hillshade</string>
<string name="terrain_empty_state_text">Turn on to view the layer with shading relief or a map of the slope of the slopes. \n\nYou can find out why such cards are needed and how they work on our website</string>
<string name="terrain_empty_state_text">Enable to view hillshade or slope map. You can read more about this map types on our site</string>
<string name="shared_string_legend">Legend</string>
<string name="shared_string_zoom_levels">Zoom levels</string>
<string name="shared_string_transparency">Transparency</string>

View file

@ -2097,6 +2097,18 @@ public class OsmandSettings {
public final CommonPreference<Boolean> HILLSHADE = new BooleanPreference("hillshade_layer", true).makeProfile();
public final CommonPreference<Integer> HILLSHADE_MIN_ZOOM = new IntPreference("hillshade_min_zoom", 3).makeProfile();
public final CommonPreference<Integer> HILLSHADE_MAX_ZOOM = new IntPreference("hillshade_max_zoom", 19).makeProfile();
public final CommonPreference<Integer> HILLSHADE_TRANSPARENCY = new IntPreference("hillshade_transparency", 100).makeProfile();
public final CommonPreference<Integer> SLOPE_MIN_ZOOM = new IntPreference("slope_min_zoom", 3).makeProfile();
public final CommonPreference<Integer> SLOPE_MAX_ZOOM = new IntPreference("slope_max_zoom", 19).makeProfile();
public final CommonPreference<Integer> SLOPE_TRANSPARENCY = new IntPreference("slope_transparency", 100).makeProfile();
public final CommonPreference<Boolean> TERRAIN = new BooleanPreference("terrain_layer", true).makeProfile();
public final CommonPreference<TerrainMode> TERRAIN_MODE = new EnumIntPreference<>("terrain_mode", TerrainMode.HILLSHADE, TerrainMode.values()).makeProfile();

View file

@ -38,6 +38,7 @@ public class HillshadeLayer extends MapTileLayer {
private final static int MAX_TRANSPARENCY_ZOOM = 17;
private final static int DEFAULT_ALPHA = 100;
private final static int MAX_TRANSPARENCY_ALPHA = 20;
private SRTMPlugin srtmPlugin;
private QuadTree<String> indexedResources = new QuadTree<String>(new QuadRect(0, 0, 1 << (ZOOM_BOUNDARY+1), 1 << (ZOOM_BOUNDARY+1)), 8, 0.55f);
@ -47,6 +48,7 @@ public class HillshadeLayer extends MapTileLayer {
indexHillshadeFiles(app);
setAlpha(DEFAULT_ALPHA);
setMap(createTileSource(activity));
this.srtmPlugin = srtmPlugin;
}
@Override
@ -54,7 +56,7 @@ public class HillshadeLayer extends MapTileLayer {
if (tileBox.getZoom() >= MAX_TRANSPARENCY_ZOOM) {
setAlpha(MAX_TRANSPARENCY_ALPHA);
} else {
setAlpha(DEFAULT_ALPHA);
setAlpha(srtmPlugin.getHillshadeTransparency());
}
super.onPrepareBufferImage(canvas, tileBox, drawSettings);
}

View file

@ -129,6 +129,7 @@ public class SRTMPlugin extends OsmandPlugin {
public String getHelpFileName() {
return "feature_articles/contour-lines-plugin.html";
}
@Override
public boolean init(@NonNull final OsmandApplication app, Activity activity) {
OsmandSettings settings = app.getSettings();
@ -174,6 +175,72 @@ public class SRTMPlugin extends OsmandPlugin {
settings.TERRAIN_MODE.set(mode);
}
public void setTransparency(int transparency) {
switch (getTerrainMode()) {
case HILLSHADE:
settings.HILLSHADE_TRANSPARENCY.set(transparency);
break;
case SLOPE:
settings.SLOPE_TRANSPARENCY.set(transparency);
break;
}
}
public void setZoomValues(int minZoom, int maxZoom) {
switch (getTerrainMode()) {
case HILLSHADE:
settings.HILLSHADE_MIN_ZOOM.set(minZoom);
settings.HILLSHADE_MAX_ZOOM.set(maxZoom);
break;
case SLOPE:
settings.SLOPE_MIN_ZOOM.set(minZoom);
settings.SLOPE_MAX_ZOOM.set(maxZoom);
break;
}
}
public int getTransparency() {
switch (getTerrainMode()) {
case HILLSHADE:
return settings.HILLSHADE_TRANSPARENCY.get();
case SLOPE:
return settings.SLOPE_TRANSPARENCY.get();
}
return 100;
}
public int getHillshadeTransparency(){
return settings.HILLSHADE_TRANSPARENCY.get();
}
public int getHillshadeMinZoom(){
return settings.HILLSHADE_MIN_ZOOM.get();
}
public int getHillshadeMaxZoom(){
return settings.HILLSHADE_MAX_ZOOM.get();
}
public int getMinZoom() {
switch (getTerrainMode()) {
case HILLSHADE:
return settings.HILLSHADE_MIN_ZOOM.get();
case SLOPE:
return settings.SLOPE_MIN_ZOOM.get();
}
return 2;
}
public int getMaxZoom() {
switch (getTerrainMode()) {
case HILLSHADE:
return settings.HILLSHADE_MAX_ZOOM.get();
case SLOPE:
return settings.SLOPE_MAX_ZOOM.get();
}
return 19;
}
public static boolean isContourLinesLayerEnabled(OsmandApplication app) {
boolean contourLinesEnabled = false;

View file

@ -1,9 +1,8 @@
package net.osmand.plus.srtmplugin;
import android.content.Intent;
import android.graphics.Color;
import android.content.res.ColorStateList;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
@ -12,7 +11,6 @@ import android.text.style.ClickableSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -20,11 +18,12 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatSeekBar;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import com.google.android.material.slider.Slider;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
@ -33,25 +32,19 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import java.io.IOException;
import org.apache.commons.logging.Log;
import java.util.List;
import static net.osmand.plus.srtmplugin.ContourLinesMenu.closeDashboard;
public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickListener {
public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickListener,
Slider.OnSliderTouchListener, Slider.OnChangeListener {
public static final String TAG = TerrainFragment.class.getSimpleName();
// TODO replace with correct string
private static final String SLOPES_WIKI_URL = "https://osmand.net/features/contour-lines-plugin";
private static final Log LOG = PlatformUtil.getLog(TerrainFragment.class.getSimpleName());
private static final String SLOPES_WIKI_URL = "https://en.wikipedia.org/wiki/Grade_(slope)";
private static final String PLUGIN_URL = "https://osmand.net/features/contour-lines-plugin";
private OsmandApplication app;
@ -63,28 +56,33 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
private boolean terrainEnabled;
private int colorProfile;
private ColorStateList colorProfileStateList;
private ColorStateList colorProfileInactiveStateList;
private TextView downloadDescriptionTv;
private TextView emptyStateDescriptionTv;
private TextView downloadDescriptionTv;
private TextView transparencyValueTv;
private TextView slopeReadMoreTv;
private TextView descriptionTv;
private TextView hillshadeBtn;
private TextView minZoomTv;
private TextView maxZoomTv;
private TextView slopeBtn;
private TextView titleTv;
private TextView stateTv;
private TextView slopeBtn;
private TextView hillshadeBtn;
private FrameLayout slopeBtnContainer;
private FrameLayout hillshadeBtnContainer;
private FrameLayout slopeBtnContainer;
private SwitchCompat switchCompat;
private ImageView iconIv;
private LinearLayout legendContainer;
private LinearLayout emptyState;
private LinearLayout legendContainer;
private LinearLayout contentContainer;
private LinearLayout downloadContainer;
private View legendTopDivider;
private View legendBottomDivider;
private View titleBottomDivider;
private AppCompatSeekBar transparencySlider;
private View legendTopDivider;
private Slider transparencySlider;
private Slider zoomSlider;
public TerrainFragment() {
@ -100,6 +98,9 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
srtmEnabled = OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null
|| InAppPurchaseHelper.isSubscribedToLiveUpdates(app);
colorProfile = settings.getApplicationMode().getIconColorInfo().getColor(nightMode);
colorProfileStateList = ColorStateList.valueOf(ContextCompat.getColor(app, colorProfile));
colorProfileInactiveStateList = ColorStateList
.valueOf(UiUtilities.getColorWithAlpha(colorProfile, 0.6f));
terrainEnabled = srtmPlugin.isTerrainLayerEnabled();
super.onCreate(savedInstanceState);
}
@ -126,29 +127,54 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
stateTv = root.findViewById(R.id.state_tv);
iconIv = root.findViewById(R.id.icon_iv);
slopeBtn = root.findViewById(R.id.slope_btn);
zoomSlider = root.findViewById(R.id.zoom_slider);
minZoomTv = root.findViewById(R.id.zoom_value_min);
maxZoomTv = root.findViewById(R.id.zoom_value_max);
hillshadeBtn = root.findViewById(R.id.hillshade_btn);
slopeBtnContainer = root.findViewById(R.id.slope_btn_container);
hillshadeBtnContainer = root.findViewById(R.id.hillshade_btn_container);
downloadContainer = root.findViewById(R.id.download_container);
hillshadeBtnContainer = root.findViewById(R.id.hillshade_btn_container);
titleTv.setText(R.string.shared_string_terrain);
String emptyStateText = String.format(
getString(R.string.ltr_or_rtl_combine_via_colon),
getString(R.string.terrain_empty_state_text),
PLUGIN_URL
);
setupClickableText(emptyStateDescriptionTv, emptyStateText, PLUGIN_URL, PLUGIN_URL);
String wikiString = getString(R.string.shared_string_wikipedia);
String readMoreText = String.format(
getString(R.string.slope_read_more),
wikiString
);
String emptyStateText = String.format(
getString(R.string.ltr_or_rtl_combine_via_space),
getString(R.string.terrain_empty_state_text),
PLUGIN_URL
);
setupClickableText(slopeReadMoreTv, readMoreText, wikiString, SLOPES_WIKI_URL);
setupClickableText(emptyStateDescriptionTv, emptyStateText, PLUGIN_URL, PLUGIN_URL);
switchCompat.setChecked(terrainEnabled);
hillshadeBtn.setOnClickListener(this);
switchCompat.setOnClickListener(this);
slopeBtn.setOnClickListener(this);
hillshadeBtn.setOnClickListener(this);
transparencySlider.setTrackColorInactive(colorProfileInactiveStateList);
transparencySlider.setTrackColorActive(colorProfileStateList);
transparencySlider.setHaloColor(colorProfileInactiveStateList);
transparencySlider.setThumbColor(colorProfileStateList);
transparencySlider.setLabelBehavior(Slider.LABEL_GONE);
zoomSlider.setTrackColorInactive(colorProfileInactiveStateList);
zoomSlider.setTrackColorActive(colorProfileStateList);
zoomSlider.setHaloColor(colorProfileInactiveStateList);
zoomSlider.setThumbColor(colorProfileStateList);
zoomSlider.setLabelBehavior(Slider.LABEL_GONE);
zoomSlider.setTickColor(nightMode
? ColorStateList.valueOf(R.color.color_white)
: ColorStateList.valueOf(R.color.color_black));
transparencySlider.addOnSliderTouchListener(this);
zoomSlider.addOnSliderTouchListener(this);
transparencySlider.addOnChangeListener(this);
zoomSlider.addOnChangeListener(this);
UiUtilities.setupCompoundButton(switchCompat, nightMode, UiUtilities.CompoundButtonType.PROFILE_DEPENDENT);
updateUiMode();
return root;
}
@ -170,15 +196,63 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
}
}
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {
}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
switch (slider.getId()) {
case R.id.transparency_slider:
srtmPlugin.setTransparency((int) slider.getValue());
break;
case R.id.zoom_slider:
List<Float> values = slider.getValues();
srtmPlugin.setZoomValues(values.get(0).intValue(), values.get(1).intValue());
break;
}
MapActivity mapActivity = (MapActivity) getActivity();
srtmPlugin.updateLayers(mapActivity.getMapView(), mapActivity);
}
@Override
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
if (fromUser) {
switch (slider.getId()) {
case R.id.transparency_slider:
String transparency = (int) value + "%";
transparencyValueTv.setText(transparency);
break;
case R.id.zoom_slider:
List<Float> values = slider.getValues();
minZoomTv.setText(String.valueOf(values.get(0).intValue()));
maxZoomTv.setText(String.valueOf(values.get(1).intValue()));
break;
}
}
}
private void updateUiMode() {
TerrainMode mode = srtmPlugin.getTerrainMode();
if (terrainEnabled) {
int transparencyValue = srtmPlugin.getTransparency();
String transparency = transparencyValue + "%";
int minZoom = srtmPlugin.getMinZoom();
int maxZoom = srtmPlugin.getMaxZoom();
iconIv.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_hillshade_dark, colorProfile));
stateTv.setText(R.string.shared_string_enabled);
transparencySlider.setValue(transparencyValue);
transparencyValueTv.setText(transparency);
zoomSlider.setValues((float) minZoom, (float) maxZoom);
minZoomTv.setText(String.valueOf(minZoom));
maxZoomTv.setText(String.valueOf(maxZoom));
switch (mode) {
case HILLSHADE:
descriptionTv.setText(R.string.hillshade_description);
downloadDescriptionTv.setText(R.string.hillshade_download_description);
// zoomSlider.setValueFrom();
// zoomSlider.setValueTo();
break;
case SLOPE:
descriptionTv.setText(R.string.slope_description);
@ -255,7 +329,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
? getResources().getColor(R.color.active_color_primary_dark)
: getResources().getColor(R.color.active_color_primary_light));
} catch (RuntimeException e) {
// LOG.error("Error trying to find index of " + clickableText + " " + e);
LOG.error("Error trying to find index of " + clickableText + " " + e);
}
}
@ -273,6 +347,4 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
updateUiMode();
}
}
}