[android] Add the outdoor style button into the layers selection

Signed-off-by: Roman Tsisyk <roman@tsisyk.com>
This commit is contained in:
Roman Tsisyk 2023-12-17 21:57:36 +02:00
parent 906a8e0b44
commit 8df3689034
16 changed files with 96 additions and 171 deletions

View file

@ -1670,6 +1670,18 @@ Java_app_organicmaps_Framework_nativeIsIsolinesLayerEnabled(JNIEnv * env, jclass
return static_cast<jboolean>(frm()->LoadIsolinesEnabled());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeSetOutdoorsLayerEnabled(JNIEnv * env, jclass, jboolean enabled)
{
frm()->SaveOutdoorsEnabled(enabled);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_Framework_nativeIsOutdoorsLayerEnabled(JNIEnv * env, jclass)
{
return static_cast<jboolean>(frm()->LoadOutdoorsEnabled());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeSaveSettingSchemeEnabled(JNIEnv * env, jclass, jboolean enabled)
{

View file

@ -38,7 +38,7 @@ import java.util.Locale;
public class Framework
{
@Retention(RetentionPolicy.SOURCE)
@IntDef({MAP_STYLE_CLEAR, MAP_STYLE_DARK, MAP_STYLE_VEHICLE_CLEAR, MAP_STYLE_VEHICLE_DARK})
@IntDef({MAP_STYLE_CLEAR, MAP_STYLE_DARK, MAP_STYLE_VEHICLE_CLEAR, MAP_STYLE_VEHICLE_DARK, MAP_STYLE_OUTDOORS_CLEAR, MAP_STYLE_OUTDOORS_DARK})
public @interface MapStyle {}
@ -46,6 +46,8 @@ public class Framework
public static final int MAP_STYLE_DARK = 1;
public static final int MAP_STYLE_VEHICLE_CLEAR = 3;
public static final int MAP_STYLE_VEHICLE_DARK = 4;
public static final int MAP_STYLE_OUTDOORS_CLEAR = 5;
public static final int MAP_STYLE_OUTDOORS_DARK = 6;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ROUTER_TYPE_VEHICLE, ROUTER_TYPE_PEDESTRIAN, ROUTER_TYPE_BICYCLE, ROUTER_TYPE_TRANSIT, ROUTER_TYPE_RULER })
@ -365,6 +367,10 @@ public class Framework
public static native boolean nativeIsIsolinesLayerEnabled();
public static native void nativeSetOutdoorsLayerEnabled(boolean enabled);
public static native boolean nativeIsOutdoorsLayerEnabled();
@NonNull
public static native MapObject nativeDeleteBookmarkFromMapObject();

View file

@ -187,7 +187,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
private PlacePageViewModel mPlacePageViewModel;
private MapButtonsViewModel mMapButtonsViewModel;
private MapButtonsController.LayoutMode mPreviousMapLayoutMode;
private Mode mPreviousLayerMode;
@Nullable
private WindowInsetsCompat mCurrentWindowInsets;
@ -475,8 +474,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
// We don't need to manually handle removing the observers it follows the activity lifecycle
mMapButtonsViewModel.getBottomButtonsHeight().observe(this, this::onMapBottomButtonsHeightChange);
mMapButtonsViewModel.getLayoutMode().observe(this, this::initNavigationButtons);
mPreviousLayerMode = mMapButtonsViewModel.getMapLayerMode().getValue();
mMapButtonsViewModel.getMapLayerMode().observe(this, this::onLayerChange);
mSearchController = new FloatingSearchToolbarController(this, this);
mSearchController.getToolbar()
@ -2133,13 +2130,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
shareMyLocation();
}
public void onLayerChange(Mode mode)
{
if (mPreviousLayerMode != mode)
closeFloatingPanels();
mPreviousLayerMode = mode;
}
@Override
@Nullable
public ArrayList<MenuBottomSheetItem> getMenuBottomSheetItems(String id)

View file

@ -44,6 +44,11 @@ public class LayerBottomSheetItem
int buttonTextResource = R.string.layers_title;
switch (mode)
{
case OUTDOORS:
disabledResource = R.attr.outdoorsMenuDisabled;
enabledResource = R.attr.outdoorsMenuEnabled;
buttonTextResource = R.string.button_layer_outdoor;
break;
case SUBWAY:
disabledResource = R.attr.subwayMenuDisabled;
enabledResource = R.attr.subwayMenuEnabled;

View file

@ -8,6 +8,7 @@ public class LayersUtils
public static List<Mode> getAvailableLayers()
{
List<Mode> availableLayers = new ArrayList<>();
availableLayers.add(Mode.OUTDOORS);
availableLayers.add(Mode.ISOLINES);
availableLayers.add(Mode.SUBWAY);
return availableLayers;

View file

@ -25,7 +25,6 @@ import app.organicmaps.routing.RoutingController;
import app.organicmaps.util.Config;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.menu.MyPositionButton;
import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.badge.BadgeDrawable;
@ -44,7 +43,7 @@ public class MapButtonsController extends Fragment
@Nullable
private View mBottomButtonsFrame;
@Nullable
private MapLayersController mToggleMapLayerController;
private FloatingActionButton mToggleMapLayerButton;
@Nullable
private MyPositionButton mNavMyPosition;
@ -60,7 +59,6 @@ public class MapButtonsController extends Fragment
private final Observer<Integer> mPlacePageDistanceToTopObserver = this::move;
private final Observer<Boolean> mButtonHiddenObserver = this::setButtonsHidden;
private final Observer<Integer> mMyPositionModeObserver = this::updateNavMyPositionButton;
private final Observer<Mode> mMapLayerModeObserver = this::toggleMapLayer;
private final Observer<SearchWheel.SearchOption> mSearchOptionObserver = this::onSearchOptionChange;
@ -107,14 +105,11 @@ public class MapButtonsController extends Fragment
mNavMyPosition = new MyPositionButton(myPosition, (v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.myPosition));
// Some buttons do not exist in navigation mode
final FloatingActionButton layersButton = mFrame.findViewById(R.id.layers_button);
if (layersButton != null)
mToggleMapLayerButton = mFrame.findViewById(R.id.layers_button);
if (mToggleMapLayerButton != null)
{
mToggleMapLayerController = new MapLayersController(
layersButton,
() -> mMapButtonClickListener.onMapButtonClick(MapButtons.toggleMapLayer),
requireActivity(),
mMapButtonsViewModel);
mToggleMapLayerButton.setOnClickListener(view -> mMapButtonClickListener.onMapButtonClick(MapButtons.toggleMapLayer));
mToggleMapLayerButton.setVisibility(View.VISIBLE);
}
final View menuButton = mFrame.findViewById(R.id.menu_button);
if (menuButton != null)
@ -148,8 +143,8 @@ public class MapButtonsController extends Fragment
mButtonsMap.put(MapButtons.bookmarks, bookmarksButton);
mButtonsMap.put(MapButtons.search, searchButton);
if (layersButton != null)
mButtonsMap.put(MapButtons.toggleMapLayer, layersButton);
if (mToggleMapLayerButton != null)
mButtonsMap.put(MapButtons.toggleMapLayer, mToggleMapLayerButton);
if (menuButton != null)
mButtonsMap.put(MapButtons.menu, menuButton);
if (helpButton != null)
@ -174,8 +169,8 @@ public class MapButtonsController extends Fragment
UiUtils.showIf(show && Config.showZoomButtons(), buttonView);
break;
case toggleMapLayer:
if (mToggleMapLayerController != null)
mToggleMapLayerController.showButton(show && !isInNavigationMode());
if (mToggleMapLayerButton != null)
UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton);
break;
case myPosition:
if (mNavMyPosition != null)
@ -293,17 +288,6 @@ public class MapButtonsController extends Fragment
return RoutingController.get().isPlanning() || RoutingController.get().isNavigating();
}
public void toggleMapLayer(@Nullable Mode mode)
{
if (mToggleMapLayerController != null)
{
if (mode == null)
mToggleMapLayerController.disableModes();
else
mToggleMapLayerController.enableMode(mode);
}
}
public void updateNavMyPositionButton(int newMode)
{
if (mNavMyPosition != null)
@ -323,7 +307,6 @@ public class MapButtonsController extends Fragment
mPlacePageViewModel.getPlacePageDistanceToTop().observe(activity, mPlacePageDistanceToTopObserver);
mMapButtonsViewModel.getButtonsHidden().observe(activity, mButtonHiddenObserver);
mMapButtonsViewModel.getMyPositionMode().observe(activity, mMyPositionModeObserver);
mMapButtonsViewModel.getMapLayerMode().observe(activity, mMapLayerModeObserver);
mMapButtonsViewModel.getSearchOption().observe(activity, mSearchOptionObserver);
}
@ -341,7 +324,6 @@ public class MapButtonsController extends Fragment
mPlacePageViewModel.getPlacePageDistanceToTop().removeObserver(mPlacePageDistanceToTopObserver);
mMapButtonsViewModel.getButtonsHidden().removeObserver(mButtonHiddenObserver);
mMapButtonsViewModel.getMyPositionMode().removeObserver(mMyPositionModeObserver);
mMapButtonsViewModel.getMapLayerMode().removeObserver(mMapLayerModeObserver);
mMapButtonsViewModel.getSearchOption().removeObserver(mSearchOptionObserver);
}

View file

@ -10,7 +10,6 @@ public class MapButtonsViewModel extends ViewModel
private final MutableLiveData<Float> mBottomButtonsHeight = new MutableLiveData<>(0f);
private final MutableLiveData<MapButtonsController.LayoutMode> mLayoutMode = new MutableLiveData<>(MapButtonsController.LayoutMode.regular);
private final MutableLiveData<Integer> mMyPositionMode = new MutableLiveData<>();
private final MutableLiveData<Mode> mMapLayerMode = new MutableLiveData<>();
private final MutableLiveData<SearchWheel.SearchOption> mSearchOption = new MutableLiveData<>();
public MutableLiveData<Boolean> getButtonsHidden()
@ -53,16 +52,6 @@ public class MapButtonsViewModel extends ViewModel
mMyPositionMode.setValue(mode);
}
public MutableLiveData<Mode> getMapLayerMode()
{
return mMapLayerMode;
}
public void setMapLayerMode(Mode mode)
{
mMapLayerMode.setValue(mode);
}
public MutableLiveData<SearchWheel.SearchOption> getSearchOption()
{
return mSearchOption;

View file

@ -1,102 +0,0 @@
package app.organicmaps.maplayer;
import android.app.Activity;
import android.widget.ImageButton;
import androidx.annotation.NonNull;
import app.organicmaps.R;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.UiUtils;
import java.util.List;
public class MapLayersController
{
@NonNull
private final Activity mActivity;
@NonNull
private final List<Mode> mLayers;
@NonNull
private final ImageButton mLayersButton;
@NonNull
OnShowMenuListener mOnShowMenuListener;
@NonNull
private Mode mCurrentLayer;
private final MapButtonsViewModel mMapButtonsViewModel;
public MapLayersController(@NonNull ImageButton layersButton, @NonNull OnShowMenuListener onShowMenuListener, @NonNull Activity activity, MapButtonsViewModel mapButtonsViewModel)
{
mActivity = activity;
mMapButtonsViewModel = mapButtonsViewModel;
mLayersButton = layersButton;
mLayersButton.setOnClickListener(view -> onLayersButtonClick());
mOnShowMenuListener = onShowMenuListener;
mLayers = LayersUtils.getAvailableLayers();
mCurrentLayer = getCurrentLayer();
// View model only expects a layer if it is active
mMapButtonsViewModel.setMapLayerMode(mCurrentLayer.isEnabled(activity) ? mCurrentLayer : null);
showButton(true);
}
@NonNull
private Mode getCurrentLayer()
{
for (Mode each : mLayers)
{
if (each.isEnabled(mActivity))
return each;
}
return mLayers.iterator().next();
}
private void setCurrentLayer(@NonNull Mode mode)
{
for (Mode each : mLayers)
{
if (each == mode)
mCurrentLayer = each;
else
each.setEnabled(mActivity, false);
}
}
private void setEnabled(boolean enabled)
{
mLayersButton.setSelected(enabled);
mCurrentLayer.setEnabled(mActivity, enabled);
int drawable = R.drawable.ic_layers;
if (enabled)
drawable = R.drawable.ic_layers_clear;
mLayersButton.setImageDrawable(Graphics.tint(mLayersButton.getContext(), drawable));
}
private void onLayersButtonClick()
{
if (mCurrentLayer.isEnabled(mActivity))
mMapButtonsViewModel.setMapLayerMode(null);
else
mOnShowMenuListener.onShow();
}
public void disableModes()
{
setEnabled(false);
}
public void enableMode(@NonNull Mode mode)
{
setCurrentLayer(mode);
showButton(true);
setEnabled(true);
}
public void showButton(boolean show)
{
UiUtils.showIf(show, mLayersButton);
}
public interface OnShowMenuListener
{
void onShow();
}
}

View file

@ -4,9 +4,11 @@ import android.content.Context;
import androidx.annotation.NonNull;
import app.organicmaps.Framework;
import app.organicmaps.maplayer.isolines.IsolinesManager;
import app.organicmaps.maplayer.subway.SubwayManager;
import app.organicmaps.maplayer.traffic.TrafficManager;
import app.organicmaps.util.ThemeSwitcher;
public enum Mode
{
@ -53,6 +55,21 @@ public enum Mode
{
IsolinesManager.from(context).setEnabled(isEnabled);
}
},
OUTDOORS
{
@Override
public boolean isEnabled(@NonNull Context context)
{
return Framework.nativeIsOutdoorsLayerEnabled();
}
@Override
public void setEnabled(@NonNull Context context, boolean isEnabled)
{
Framework.nativeSetOutdoorsLayerEnabled(isEnabled);
ThemeSwitcher.INSTANCE.restart(true);
}
};
public abstract boolean isEnabled(@NonNull Context context);

View file

@ -67,9 +67,9 @@ public class ToggleMapLayerFragment extends Fragment
Mode mode = item.getMode();
Context context = v.getContext();
SharedPropertiesUtils.setLayerMarkerShownForLayerMode(context, mode);
mode.setEnabled(context, !mode.isEnabled(context));
mAdapter.notifyDataSetChanged();
if (IsolinesManager.from(context).shouldShowNotification())
Utils.showSnackbar(context, v.getRootView(), R.string.isolines_toast_zooms_1_10);
mMapButtonsViewModel.setMapLayerMode(mode);
}
}

View file

@ -36,11 +36,6 @@ public class IsolinesManager
Framework.nativeSetIsolinesLayerEnabled(isEnabled);
}
public void toggle()
{
setEnabled(!isEnabled());
}
public void initialize()
{
registerListener();

View file

@ -90,24 +90,33 @@ public enum ThemeSwitcher
private void setThemeAndMapStyle(@NonNull String theme)
{
String oldTheme = Config.getCurrentUiTheme(mContext);
Config.setCurrentUiTheme(mContext, theme);
changeMapStyle(theme, oldTheme);
}
@androidx.annotation.UiThread
private void changeMapStyle(@NonNull String newTheme, @NonNull String oldTheme)
{
@Framework.MapStyle
int style = RoutingController.get().isVehicleNavigation()
? Framework.MAP_STYLE_VEHICLE_CLEAR : Framework.MAP_STYLE_CLEAR;
if (ThemeUtils.isNightTheme(mContext, newTheme))
style = RoutingController.get().isVehicleNavigation()
? Framework.MAP_STYLE_VEHICLE_DARK : Framework.MAP_STYLE_DARK;
int oldStyle = Framework.nativeGetMapStyle();
if (!newTheme.equals(oldTheme))
@Framework.MapStyle
int style;
if (ThemeUtils.isNightTheme(mContext, theme))
{
SetMapStyle(style);
if (RoutingController.get().isVehicleNavigation())
style = Framework.MAP_STYLE_VEHICLE_DARK;
else if (Framework.nativeIsOutdoorsLayerEnabled())
style = Framework.MAP_STYLE_OUTDOORS_DARK;
else
style = Framework.MAP_STYLE_DARK;
}
else
{
if (RoutingController.get().isVehicleNavigation())
style = Framework.MAP_STYLE_VEHICLE_CLEAR;
else if (Framework.nativeIsOutdoorsLayerEnabled())
style = Framework.MAP_STYLE_OUTDOORS_CLEAR;
else
style = Framework.MAP_STYLE_CLEAR;
}
if (!theme.equals(oldTheme))
{
Config.setCurrentUiTheme(mContext, theme);
DownloaderStatusIcon.clearCache();
final Activity a = MwmApplication.from(mContext).getTopActivity();

View file

@ -45,9 +45,11 @@
<attr name="trafficMenuDisabled" format="reference"/>
<attr name="subwayMenuDisabled" format="reference"/>
<attr name="isoLinesMenuDisabled" format="reference"/>
<attr name="outdoorsMenuDisabled" format="reference"/>
<attr name="trafficMenuEnabled" format="reference"/>
<attr name="subwayMenuEnabled" format="reference"/>
<attr name="isoLinesMenuEnabled" format="reference"/>
<attr name="outdoorsMenuEnabled" format="reference"/>
<attr name="accentColorSelector" format="color"/>
<attr name="bookingFilterTitleColor" format="color"/>
<attr name="adsRemovalOptionsBg" format="reference"/>

View file

@ -89,9 +89,11 @@
<item name="transitPedestrianBackground">@color/black_4</item>
<item name="transitRulerBackground">@color/black_4</item>
<item name="transitStepDivider">@drawable/dot_divider</item>
<item name="outdoorsMenuEnabled">@drawable/ic_layers_outdoors_active</item>
<item name="trafficMenuEnabled">@drawable/ic_layers_traffic_active</item>
<item name="subwayMenuEnabled">@drawable/ic_layers_subway_active</item>
<item name="isoLinesMenuEnabled">@drawable/ic_layers_isoline_active</item>
<item name="outdoorsMenuDisabled">@drawable/ic_layers_outdoors_inactive</item>
<item name="trafficMenuDisabled">@drawable/ic_layers_traffic_inactive</item>
<item name="subwayMenuDisabled">@drawable/ic_layers_subway_inactive</item>
<item name="isoLinesMenuDisabled">@drawable/ic_layers_isoline_inactive</item>

View file

@ -101,6 +101,7 @@ char const kAllowAutoZoom[] = "AutoZoom";
char const kTrafficEnabledKey[] = "TrafficEnabled";
char const kTransitSchemeEnabledKey[] = "TransitSchemeEnabled";
char const kIsolinesEnabledKey[] = "IsolinesEnabled";
char const kOutdoorsEnabledKey[] = "OutdoorsEnabled";
char const kTrafficSimplifiedColorsKey[] = "TrafficSimplifiedColors";
char const kLargeFontsSize[] = "LargeFontsSize";
char const kTranslitMode[] = "TransliterationMode";
@ -2496,6 +2497,19 @@ void Framework::SaveIsolinesEnabled(bool enabled)
settings::Set(kIsolinesEnabledKey, enabled);
}
bool Framework::LoadOutdoorsEnabled()
{
bool enabled;
if (!settings::Get(kOutdoorsEnabledKey, enabled))
enabled = false;
return enabled;
}
void Framework::SaveOutdoorsEnabled(bool enabled)
{
settings::Set(kOutdoorsEnabledKey, enabled);
}
void Framework::EnableChoosePositionMode(bool enable, bool enableBounds, bool applyPosition,
m2::PointD const & position)
{

View file

@ -700,6 +700,9 @@ public:
bool LoadIsolinesEnabled();
void SaveIsolinesEnabled(bool enabled);
bool LoadOutdoorsEnabled();
void SaveOutdoorsEnabled(bool enabled);
dp::ApiVersion LoadPreferredGraphicsAPI();
void SavePreferredGraphicsAPI(dp::ApiVersion apiVersion);