diff --git a/OsmAnd/res/layout/card_multi_state.xml b/OsmAnd/res/layout/card_multi_state.xml
index 63002473c19..4f2fefcabc7 100644
--- a/OsmAnd/res/layout/card_multi_state.xml
+++ b/OsmAnd/res/layout/card_multi_state.xml
@@ -46,6 +46,7 @@
tools:text="Solid" />
diff --git a/OsmAnd/res/layout/map_button_icons_card.xml b/OsmAnd/res/layout/map_button_icons_card.xml
index 0fe9bfaddc0..11acf66c1f0 100644
--- a/OsmAnd/res/layout/map_button_icons_card.xml
+++ b/OsmAnd/res/layout/map_button_icons_card.xml
@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:background="?attr/card_and_list_background_basic"
android:orientation="vertical">
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/min_max_container.xml b/OsmAnd/res/layout/min_max_container.xml
new file mode 100644
index 00000000000..391d8d17064
--- /dev/null
+++ b/OsmAnd/res/layout/min_max_container.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/slider_with_buttons.xml b/OsmAnd/res/layout/slider_with_buttons.xml
index 5775deb0ea9..f05803e95a7 100644
--- a/OsmAnd/res/layout/slider_with_buttons.xml
+++ b/OsmAnd/res/layout/slider_with_buttons.xml
@@ -8,61 +8,61 @@
android:orientation="vertical"
android:paddingBottom="@dimen/content_padding_half">
+
+
+ android:orientation="vertical">
-
+ android:orientation="horizontal"
+ android:paddingHorizontal="@dimen/content_padding_round_medium">
-
+
+
+
+
+
+
+
-
-
+ android:orientation="vertical">
-
+
-
+
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index e75b808b505..21f62a232f8 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,9 @@
Thx - Hardy
-->
+ Each button would keep its own size.
+ Each button would keep its own corner radius.
+ Each button would keep its own background opacity.
Selected profile \"%s\"
Interpolation
Location interpolation percentage
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/ButtonAppearanceParams.kt b/OsmAnd/src/net/osmand/plus/quickaction/ButtonAppearanceParams.kt
index 49cf34e0270..e1d0d52dffa 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/ButtonAppearanceParams.kt
+++ b/OsmAnd/src/net/osmand/plus/quickaction/ButtonAppearanceParams.kt
@@ -44,5 +44,7 @@ data class ButtonAppearanceParams(
internal const val ROUND_RADIUS_DP = 36
internal const val RECTANGULAR_RADIUS_DP = 2
+
+ internal const val ORIGINAL_VALUE = -1
}
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/ButtonSizeCard.java b/OsmAnd/src/net/osmand/plus/quickaction/ButtonSizeCard.java
index 76af69a2d09..a26ed2e6caa 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/ButtonSizeCard.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/ButtonSizeCard.java
@@ -1,6 +1,7 @@
package net.osmand.plus.quickaction;
import static com.google.android.material.slider.LabelFormatter.LABEL_FLOATING;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.ORIGINAL_VALUE;
import android.view.View;
@@ -8,9 +9,15 @@
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.card.base.multistate.CardState;
import net.osmand.plus.utils.ColorUtilities;
import net.osmand.plus.utils.UiUtilities;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
public class ButtonSizeCard extends SliderButtonsCard {
public static final int MIN_BUTTON_SIZE = 40;
@@ -19,15 +26,22 @@ public class ButtonSizeCard extends SliderButtonsCard {
private final ButtonAppearanceParams appearanceParams;
- public ButtonSizeCard(@NonNull MapActivity activity, @NonNull ButtonAppearanceParams appearanceParams) {
- super(activity);
+ public ButtonSizeCard(@NonNull MapActivity activity,
+ @NonNull ButtonAppearanceParams appearanceParams, boolean showOriginal) {
+ super(activity, showOriginal);
this.appearanceParams = appearanceParams;
}
protected void setupHeader(@NonNull View view) {
super.setupHeader(view);
title.setText(R.string.shared_string_size);
- description.setText(getFormattedValue(appearanceParams.getSize()));
+ valueTv.setText(getFormattedValue(appearanceParams.getSize()));
+ }
+
+ @Override
+ protected void setupDescription(@NonNull @NotNull View view) {
+ super.setupDescription(view);
+ description.setText(R.string.default_buttons_corners_original_description);
}
protected void setupSlider(@NonNull View view) {
@@ -37,22 +51,57 @@ protected void setupSlider(@NonNull View view) {
slider.setValueTo(MAX_BUTTON_SIZE);
slider.setValueFrom(MIN_BUTTON_SIZE);
slider.setStepSize(BUTTON_SIZE_STEP);
- slider.setValue(appearanceParams.getSize());
slider.setLabelBehavior(LABEL_FLOATING);
slider.setLabelFormatter(ButtonSizeCard.this::getFormattedValue);
+
+ if (!isOriginalValue()) {
+ slider.setValue(appearanceParams.getSize());
+ }
}
protected void onValueSelected(float value) {
super.onValueSelected(value);
appearanceParams.setSize((int) value);
- description.setText(getFormattedValue(appearanceParams.getSize()));
+ valueTv.setText(getFormattedValue(appearanceParams.getSize()));
notifyCardPressed();
}
+ @Override
+ protected boolean isOriginalValue() {
+ return appearanceParams.getSize() == ORIGINAL_VALUE;
+ }
+
@NonNull
protected String getFormattedValue(float value) {
+ if (value == ORIGINAL_VALUE) {
+ return getString(R.string.shared_string_original);
+ }
return getString(R.string.ltr_or_rtl_combine_via_space, (int) value, getString(R.string.shared_string_dp));
}
+
+ @NonNull
+ @Override
+ protected List getCardStates() {
+ List list = new ArrayList<>();
+
+ list.add(new CardState(R.string.shared_string_original).setTag(ORIGINAL_VALUE));
+
+ for (int i = MIN_BUTTON_SIZE; i <= MAX_BUTTON_SIZE; i += BUTTON_SIZE_STEP) {
+ list.add(new CardState(getFormattedValue(i))
+ .setShowTopDivider(i == MIN_BUTTON_SIZE)
+ .setTag(i));
+ }
+ return list;
+ }
+
+ @Override
+ protected void setSelectedState(@NonNull CardState cardState) {
+ if (cardState.getTag() instanceof Integer value) {
+ appearanceParams.setSize(value);
+ }
+ updateContent();
+ notifyCardPressed();
+ }
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/CornerRadiusCard.java b/OsmAnd/src/net/osmand/plus/quickaction/CornerRadiusCard.java
index c5285f80811..ad9f4c94b7c 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/CornerRadiusCard.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/CornerRadiusCard.java
@@ -2,6 +2,7 @@
import static com.google.android.material.slider.LabelFormatter.LABEL_FLOATING;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.ORIGINAL_VALUE;
import android.view.View;
@@ -9,24 +10,37 @@
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.card.base.multistate.CardState;
import net.osmand.plus.utils.ColorUtilities;
import net.osmand.plus.utils.UiUtilities;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
public class CornerRadiusCard extends SliderButtonsCard {
public static final int[] CORNER_RADIUS_VALUES = {3, 6, 9, 12, 36};
private final ButtonAppearanceParams appearanceParams;
- public CornerRadiusCard(@NonNull MapActivity activity, @NonNull ButtonAppearanceParams appearanceParams) {
- super(activity);
+ public CornerRadiusCard(@NonNull MapActivity activity,
+ @NonNull ButtonAppearanceParams appearanceParams, boolean showOriginal) {
+ super(activity, showOriginal);
this.appearanceParams = appearanceParams;
}
protected void setupHeader(@NonNull View view) {
super.setupHeader(view);
title.setText(R.string.corner_radius);
- description.setText(getFormattedValue(appearanceParams.getCornerRadius()));
+ valueTv.setText(getFormattedValue(appearanceParams.getCornerRadius()));
+ }
+
+ @Override
+ protected void setupDescription(@NonNull @NotNull View view) {
+ super.setupDescription(view);
+ description.setText(R.string.default_buttons_corners_original_description);
}
protected void setupSlider(@NonNull View view) {
@@ -36,9 +50,12 @@ protected void setupSlider(@NonNull View view) {
slider.setValueTo(CORNER_RADIUS_VALUES.length - 1);
slider.setValueFrom(0);
slider.setStepSize(1);
- slider.setValue(getSelectedIndex());
slider.setLabelBehavior(LABEL_FLOATING);
slider.setLabelFormatter(value -> CornerRadiusCard.this.getFormattedValue(CORNER_RADIUS_VALUES[(int) value]));
+
+ if (!isOriginalValue()) {
+ slider.setValue(getSelectedIndex());
+ }
}
protected void onValueSelected(float value) {
@@ -46,11 +63,16 @@ protected void onValueSelected(float value) {
int index = (int) value;
appearanceParams.setCornerRadius(CORNER_RADIUS_VALUES[index]);
- description.setText(getFormattedValue(appearanceParams.getCornerRadius()));
+ valueTv.setText(getFormattedValue(appearanceParams.getCornerRadius()));
notifyCardPressed();
}
+ @Override
+ protected boolean isOriginalValue() {
+ return appearanceParams.getCornerRadius() == ORIGINAL_VALUE;
+ }
+
private int getSelectedIndex() {
int value = appearanceParams.getCornerRadius();
for (int i = 0; i < CORNER_RADIUS_VALUES.length; i++) {
@@ -63,6 +85,34 @@ private int getSelectedIndex() {
@NonNull
protected String getFormattedValue(float value) {
+ if (value == ORIGINAL_VALUE) {
+ return getString(R.string.shared_string_original);
+ }
return getString(R.string.ltr_or_rtl_combine_via_space, (int) value, getString(R.string.shared_string_dp));
}
+
+ @NonNull
+ @Override
+ protected List getCardStates() {
+ List list = new ArrayList<>();
+
+ list.add(new CardState(R.string.shared_string_original).setTag(ORIGINAL_VALUE));
+
+ for (int i = 0; i < CORNER_RADIUS_VALUES.length; i++) {
+ int value = CORNER_RADIUS_VALUES[i];
+ list.add(new CardState(getFormattedValue(value))
+ .setShowTopDivider(i == 0)
+ .setTag(value));
+ }
+ return list;
+ }
+
+ @Override
+ protected void setSelectedState(@NonNull CardState cardState) {
+ if (cardState.getTag() instanceof Integer value) {
+ appearanceParams.setCornerRadius(value);
+ }
+ updateContent();
+ notifyCardPressed();
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonAppearanceFragment.java
index b4a5a7604ce..6a163b1001d 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonAppearanceFragment.java
@@ -133,11 +133,11 @@ private void setupCards(@NonNull View view) {
mapButtonCard = new MapButtonCard(activity, buttonState, appearanceParams);
addCard(container, mapButtonCard);
addCard(container, new ButtonIconsCard(activity, iconController));
- addCard(container, new CornerRadiusCard(activity, appearanceParams));
+ addCard(container, new CornerRadiusCard(activity, appearanceParams, false));
container.addView(themedInflater.inflate(R.layout.simple_divider_item, container, false));
- addCard(container, new ButtonSizeCard(activity, appearanceParams));
+ addCard(container, new ButtonSizeCard(activity, appearanceParams, false));
container.addView(themedInflater.inflate(R.layout.simple_divider_item, container, false));
- addCard(container, new OpacitySliderCard(activity, appearanceParams));
+ addCard(container, new OpacitySliderCard(activity, appearanceParams, false));
}
private void addCard(@NonNull ViewGroup container, @NonNull BaseCard card) {
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java
index b95bf4a040f..3d3e5aaccd2 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java
@@ -1,5 +1,6 @@
package net.osmand.plus.quickaction;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.ORIGINAL_VALUE;
import static net.osmand.plus.quickaction.QuickActionType.CREATE_CATEGORY;
import static net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState.DEFAULT_BUTTON_ID;
@@ -21,6 +22,7 @@
import net.osmand.plus.quickaction.actions.special.OpenWunderLINQDatagridAction;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
+import net.osmand.plus.settings.backend.preferences.CommonPreference;
import net.osmand.plus.views.mapwidgets.configure.buttons.*;
import net.osmand.util.Algorithms;
@@ -99,9 +101,14 @@ public static QuickActionType getCategoryActionTypeFromId(int typeId) {
private final OsmandApplication app;
private final OsmandSettings settings;
+ private final Collator collator = OsmAndCollator.primaryCollator();
private final QuickActionSerializer serializer = new QuickActionSerializer();
private final Gson gson = new GsonBuilder().registerTypeAdapter(QuickAction.class, serializer).create();
+ private final CommonPreference defaultSizePref;
+ private final CommonPreference defaultOpacityPref;
+ private final CommonPreference defaultCornerRadiusPref;
+
private Map3DButtonState map3DButtonState;
private MyLocationButtonState myLocationButtonState;
private NavigationMenuButtonState navigationMenuButtonState;
@@ -117,11 +124,15 @@ public static QuickActionType getCategoryActionTypeFromId(int typeId) {
private Map quickActionTypesInt = new TreeMap<>();
private Map quickActionTypesStr = new TreeMap<>();
private Set updatesListeners = new HashSet<>();
- private final Collator collator = OsmAndCollator.primaryCollator();
+
public MapButtonsHelper(@NonNull OsmandApplication app) {
this.app = app;
this.settings = app.getSettings();
+ this.defaultSizePref = settings.registerIntPreference("default_map_button_size", ORIGINAL_VALUE).makeProfile().cache();
+ this.defaultOpacityPref = settings.registerFloatPreference("default_map_button_opacity", ORIGINAL_VALUE).makeProfile().cache();
+ this.defaultCornerRadiusPref = settings.registerIntPreference("default_map_button_corner_radius", ORIGINAL_VALUE).makeProfile().cache();
+
updateActionTypes();
initDefaultButtons();
}
@@ -597,6 +608,21 @@ public QuickActionButtonState getButtonStateByAction(@NonNull QuickAction action
return null;
}
+ @NonNull
+ public CommonPreference getDefaultSizePref() {
+ return defaultSizePref;
+ }
+
+ @NonNull
+ public CommonPreference getDefaultOpacityPref() {
+ return defaultOpacityPref;
+ }
+
+ @NonNull
+ public CommonPreference getDefaultCornerRadiusPref() {
+ return defaultCornerRadiusPref;
+ }
+
@NonNull
public String createNewButtonStateId() {
return DEFAULT_BUTTON_ID + "_" + System.currentTimeMillis();
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/OpacitySliderCard.java b/OsmAnd/src/net/osmand/plus/quickaction/OpacitySliderCard.java
index df3e2534141..fa6e86eb08d 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/OpacitySliderCard.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/OpacitySliderCard.java
@@ -1,8 +1,12 @@
package net.osmand.plus.quickaction;
import static com.google.android.material.slider.LabelFormatter.LABEL_FLOATING;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.ORIGINAL_VALUE;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.TRANSPARENT_ALPHA;
+import android.content.Context;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -10,9 +14,16 @@
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.ProgressHelper;
+import net.osmand.plus.card.base.multistate.CardState;
+import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.utils.ColorUtilities;
import net.osmand.plus.utils.UiUtilities;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
public class OpacitySliderCard extends SliderButtonsCard {
public static final int MIN_OPACITY = 0;
@@ -20,25 +31,25 @@ public class OpacitySliderCard extends SliderButtonsCard {
private final ButtonAppearanceParams appearanceParams;
- @Override
- public int getCardLayoutId() {
- return R.layout.map_button_opacity_card;
- }
+ private float selectedOpacity;
- public OpacitySliderCard(@NonNull MapActivity activity, @NonNull ButtonAppearanceParams appearanceParams) {
- super(activity);
+ public OpacitySliderCard(@NonNull MapActivity activity,
+ @NonNull ButtonAppearanceParams appearanceParams, boolean showOriginal) {
+ super(activity, showOriginal);
+ this.selectedOpacity = appearanceParams.getOpacity();
this.appearanceParams = appearanceParams;
}
+ @NonNull
@Override
- protected void updateContent() {
- setupHeader(view);
- setupSlider(view);
+ public View inflate(@NonNull Context ctx) {
+ View view = super.inflate(ctx);
+ addMinMaxRow(view.findViewById(R.id.slider_container));
+ return view;
}
- @Override
- protected void setupHeader(@NonNull View view) {
- super.setupHeader(view);
+ private void addMinMaxRow(@NonNull ViewGroup container) {
+ View view = themedInflater.inflate(R.layout.min_max_container, container, false);
TextView valueMin = view.findViewById(R.id.value_min);
TextView valueMax = view.findViewById(R.id.value_max);
@@ -46,9 +57,23 @@ protected void setupHeader(@NonNull View view) {
valueMin.setText(getFormattedValue(MIN_OPACITY));
valueMax.setText(getFormattedValue(MAX_OPACITY));
+ container.addView(view);
+ }
+
+ @Override
+ protected void setupHeader(@NonNull View view) {
+ super.setupHeader(view);
+
+ title.setText(R.string.background_opacity);
updateDescription();
}
+ @Override
+ protected void setupDescription(@NonNull @NotNull View view) {
+ super.setupDescription(view);
+ description.setText(R.string.default_buttons_corners_original_description);
+ }
+
@Override
protected void setupSlider(@NonNull View view) {
super.setupSlider(view);
@@ -56,23 +81,63 @@ protected void setupSlider(@NonNull View view) {
slider.setValueTo(MAX_OPACITY);
slider.setValueFrom(MIN_OPACITY);
- slider.setValue(appearanceParams.getOpacity());
slider.setLabelBehavior(LABEL_FLOATING);
slider.setLabelFormatter(OpacitySliderCard.this::getFormattedValue);
+
+ if (!isOriginalValue()) {
+ slider.setValue(appearanceParams.getOpacity());
+ }
+ }
+
+ @Override
+ protected void setupButtons(@NonNull @NotNull View view) {
+ super.setupButtons(view);
+
+ AndroidUiHelper.updateVisibility(increaseButton, false);
+ AndroidUiHelper.updateVisibility(decreaseButton, false);
}
protected void onValueSelected(float value) {
+ selectedOpacity = value;
appearanceParams.setOpacity(value);
updateDescription();
notifyCardPressed();
}
+ @Override
+ protected boolean isOriginalValue() {
+ return appearanceParams.getOpacity() == ORIGINAL_VALUE;
+ }
+
+ @NonNull
+ @Override
+ protected List getCardStates() {
+ List list = new ArrayList<>();
+ float value = selectedOpacity != ORIGINAL_VALUE ? selectedOpacity : TRANSPARENT_ALPHA;
+ list.add(new CardState(R.string.shared_string_original).setTag(ORIGINAL_VALUE));
+ list.add(new CardState(R.string.shared_string_custom).setTag(value).setShowTopDivider(true));
+
+ return list;
+ }
+
private void updateDescription() {
- description.setText(getFormattedValue(appearanceParams.getOpacity()));
+ valueTv.setText(getFormattedValue(appearanceParams.getOpacity()));
}
@NonNull
protected String getFormattedValue(float value) {
+ if (value == ORIGINAL_VALUE) {
+ return getString(R.string.shared_string_original);
+ }
return ProgressHelper.normalizeProgressPercent((int) (value * 100)) + "%";
}
+
+ @Override
+ protected void setSelectedState(@NonNull CardState cardState) {
+ if (cardState.getTag() instanceof Number value) {
+ appearanceParams.setOpacity(value.floatValue());
+ }
+ updateContent();
+ notifyCardPressed();
+ }
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/SliderButtonsCard.java b/OsmAnd/src/net/osmand/plus/quickaction/SliderButtonsCard.java
index 965fef5b406..6d896a875f5 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/SliderButtonsCard.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/SliderButtonsCard.java
@@ -12,37 +12,63 @@
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.card.base.multistate.CardState;
+import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.routepreparationmenu.cards.MapBaseCard;
import net.osmand.plus.utils.AndroidUtils;
import net.osmand.plus.utils.ColorUtilities;
+import net.osmand.plus.widgets.popup.PopUpMenu;
+import net.osmand.plus.widgets.popup.PopUpMenuDisplayData;
+import net.osmand.plus.widgets.popup.PopUpMenuItem;
+
+import java.util.ArrayList;
+import java.util.List;
public abstract class SliderButtonsCard extends MapBaseCard {
protected Slider slider;
protected TextView title;
+ protected TextView valueTv;
protected TextView description;
protected ImageButton increaseButton;
protected ImageButton decreaseButton;
+ protected boolean showOriginal;
+
@Override
public int getCardLayoutId() {
return R.layout.slider_with_buttons;
}
- public SliderButtonsCard(@NonNull MapActivity activity) {
+ public SliderButtonsCard(@NonNull MapActivity activity, boolean showOriginal) {
super(activity, false);
+ this.showOriginal = showOriginal;
}
@Override
protected void updateContent() {
setupHeader(view);
setupSlider(view);
+ setupDescription(view);
setupButtons(view);
}
protected void setupHeader(@NonNull View view) {
- title = view.findViewById(R.id.title);
- description = view.findViewById(R.id.description);
+ View container = view.findViewById(R.id.header_container);
+ title = container.findViewById(R.id.card_title);
+ valueTv = container.findViewById(R.id.title);
+
+ View selector = view.findViewById(R.id.card_selector);
+ if (showOriginal) {
+ selector.setOnClickListener(v -> showMenu(selector));
+ }
+ AndroidUiHelper.updateVisibility(selector.findViewById(R.id.drop_down_icon), showOriginal);
+ }
+
+ protected void setupDescription(@NonNull View view) {
+ View container = view.findViewById(R.id.description_container);
+ description = container.findViewById(R.id.summary);
+ AndroidUiHelper.updateVisibility(container, showOriginal && isOriginalValue());
}
protected void setupSlider(@NonNull View view) {
@@ -52,6 +78,7 @@ protected void setupSlider(@NonNull View view) {
onValueSelected(value);
}
});
+ AndroidUiHelper.updateVisibility(view.findViewById(R.id.slider_container), !showOriginal || !isOriginalValue());
}
protected void setupButtons(@NonNull View view) {
@@ -80,9 +107,36 @@ protected void onValueSelected(float value) {
decreaseButton.setEnabled(value > slider.getValueFrom());
}
+ public void showMenu(@NonNull View view) {
+ List items = new ArrayList<>();
+ for (CardState state : getCardStates()) {
+ items.add(new PopUpMenuItem.Builder(app)
+ .setTitle(state.toHumanString(app))
+ .showTopDivider(state.isShowTopDivider())
+ .setTitleColor(ColorUtilities.getPrimaryTextColor(app, nightMode))
+ .setTag(state)
+ .create()
+ );
+ }
+ PopUpMenuDisplayData data = new PopUpMenuDisplayData();
+ data.anchorView = view;
+ data.menuItems = items;
+ data.nightMode = nightMode;
+ data.onItemClickListener = item -> setSelectedState((CardState) item.getTag());
+ PopUpMenu.show(data);
+ }
+
+
+ protected abstract boolean isOriginalValue();
+
@NonNull
protected abstract String getFormattedValue(float value);
+ @NonNull
+ protected abstract List getCardStates();
+
+ protected abstract void setSelectedState(@NonNull CardState cardState);
+
@NonNull
protected Drawable getPersistentPrefIcon(@DrawableRes int iconId) {
Drawable enabled = getColoredIcon(iconId, ColorUtilities.getActiveColorId(nightMode));
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java
index 1e51d77c74c..bf94ca070cf 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java
@@ -128,12 +128,17 @@ public View build() {
@NonNull
public View build(@NonNull Context ctx) {
- themedInflater = UiUtilities.getInflater(ctx, nightMode);
- view = themedInflater.inflate(getCardLayoutId(), null);
+ view = inflate(ctx);
update();
return view;
}
+ @NonNull
+ public View inflate(@NonNull Context ctx) {
+ themedInflater = UiUtilities.getInflater(ctx, nightMode);
+ return themedInflater.inflate(getCardLayoutId(), null);
+ }
+
public OsmandApplication getMyApplication() {
return app;
}
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultButtonsAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultButtonsAppearanceFragment.java
new file mode 100644
index 00000000000..f68a4320a5b
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultButtonsAppearanceFragment.java
@@ -0,0 +1,267 @@
+package net.osmand.plus.views.mapwidgets.configure.buttons;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.view.ViewCompat;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import net.osmand.plus.R;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.base.BaseOsmAndFragment;
+import net.osmand.plus.helpers.AndroidUiHelper;
+import net.osmand.plus.quickaction.ButtonAppearanceParams;
+import net.osmand.plus.quickaction.ButtonSizeCard;
+import net.osmand.plus.quickaction.CornerRadiusCard;
+import net.osmand.plus.quickaction.MapButtonsHelper;
+import net.osmand.plus.quickaction.OpacitySliderCard;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
+import net.osmand.plus.settings.backend.preferences.CommonPreference;
+import net.osmand.plus.utils.AndroidUtils;
+import net.osmand.plus.utils.ColorUtilities;
+import net.osmand.plus.utils.UiUtilities;
+import net.osmand.plus.widgets.dialogbutton.DialogButton;
+import net.osmand.util.Algorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultButtonsAppearanceFragment extends BaseOsmAndFragment implements CardListener {
+
+ public static final String TAG = DefaultButtonsAppearanceFragment.class.getSimpleName();
+
+ private CommonPreference defaultSizePref;
+ private CommonPreference defaultOpacityPref;
+ private CommonPreference defaultCornerRadiusPref;
+
+ private ButtonAppearanceParams appearanceParams;
+ private ButtonAppearanceParams originalAppearanceParams;
+
+ private List cards;
+ private DialogButton applyButton;
+
+ public boolean getContentStatusBarNightMode() {
+ return nightMode;
+ }
+
+ @Override
+ public int getStatusBarColorId() {
+ AndroidUiHelper.setStatusBarContentColor(getView(), nightMode);
+ return ColorUtilities.getListBgColorId(nightMode);
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ MapButtonsHelper helper = app.getMapButtonsHelper();
+ defaultSizePref = helper.getDefaultSizePref();
+ defaultOpacityPref = helper.getDefaultOpacityPref();
+ defaultCornerRadiusPref = helper.getDefaultCornerRadiusPref();
+
+ appearanceParams = createAppearanceParams();
+ originalAppearanceParams = createAppearanceParams();
+
+ if (savedInstanceState != null) {
+ appearanceParams.readBundle(savedInstanceState);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ updateNightMode();
+ View view = themedInflater.inflate(R.layout.map_button_appearance_fragment, container, false);
+ AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view);
+
+ setupToolbar(view);
+ setupCards(view);
+ setupApplyButton(view);
+
+ updateContent();
+
+ return view;
+ }
+
+ private void setupToolbar(@NonNull View view) {
+ Toolbar toolbar = view.findViewById(R.id.toolbar);
+ ViewCompat.setElevation(view.findViewById(R.id.appbar), 5.0f);
+ toolbar.setBackgroundColor(ColorUtilities.getAppBarSecondaryColor(view.getContext(), nightMode));
+
+ TextView title = toolbar.findViewById(R.id.toolbar_title);
+ title.setText(R.string.default_appearance);
+ title.setTextColor(ColorUtilities.getPrimaryTextColor(view.getContext(), nightMode));
+
+ ImageView closeButton = toolbar.findViewById(R.id.close_button);
+ closeButton.setImageDrawable(getContentIcon(R.drawable.ic_action_close));
+ closeButton.setOnClickListener(v -> {
+ FragmentActivity activity = getActivity();
+ if (activity != null) {
+ activity.onBackPressed();
+ }
+ });
+ ImageView resetButton = toolbar.findViewById(R.id.action_button);
+ resetButton.setOnClickListener(v -> resetAppearance());
+ resetButton.setImageDrawable(getContentIcon(R.drawable.ic_action_reset));
+ resetButton.setContentDescription(getString(R.string.shared_string_reset));
+ AndroidUiHelper.updateVisibility(resetButton, true);
+ }
+
+ private void setupCards(@NonNull View view) {
+ cards = new ArrayList<>();
+
+ ViewGroup container = view.findViewById(R.id.cards_container);
+ container.removeAllViews();
+
+ MapActivity activity = requireMapActivity();
+ addCard(container, new CornerRadiusCard(activity, appearanceParams, true));
+ container.addView(themedInflater.inflate(R.layout.list_item_divider, container, false));
+ addCard(container, new ButtonSizeCard(activity, appearanceParams, true));
+ container.addView(themedInflater.inflate(R.layout.list_item_divider, container, false));
+ addCard(container, new OpacitySliderCard(activity, appearanceParams, true));
+ }
+
+ private void addCard(@NonNull ViewGroup container, @NonNull BaseCard card) {
+ cards.add(card);
+ card.setListener(this);
+ container.addView(card.build());
+ }
+
+ private void setupApplyButton(@NonNull View view) {
+ applyButton = view.findViewById(R.id.apply_button);
+ applyButton.setOnClickListener(v -> {
+ saveChanges(false);
+ showAllModesSnackbar();
+
+ FragmentActivity activity = getActivity();
+ if (activity != null) {
+ activity.onBackPressed();
+ }
+ });
+ }
+
+ private void showAllModesSnackbar() {
+ View containerView = getView();
+ if (containerView != null) {
+ String name = settings.getApplicationMode().toHumanString();
+ String text = app.getString(R.string.changes_applied_to_profile, name);
+ SpannableString message = UiUtilities.createSpannableString(text, Typeface.BOLD, name);
+ Snackbar snackbar = Snackbar.make(containerView, message, Snackbar.LENGTH_LONG)
+ .setAction(R.string.apply_to_all_profiles, view -> saveChanges(true));
+ UiUtilities.setupSnackbarVerticalLayout(snackbar);
+ UiUtilities.setupSnackbar(snackbar, nightMode);
+ snackbar.show();
+ }
+ }
+
+ private void saveChanges(boolean applyToAllProfiles) {
+ if (applyToAllProfiles) {
+ settings.setPreferenceForAllModes(defaultSizePref.getId(), appearanceParams.getSize());
+ settings.setPreferenceForAllModes(defaultOpacityPref.getId(), appearanceParams.getOpacity());
+ settings.setPreferenceForAllModes(defaultCornerRadiusPref.getId(), appearanceParams.getCornerRadius());
+ } else {
+ defaultSizePref.set(appearanceParams.getSize());
+ defaultOpacityPref.set(appearanceParams.getOpacity());
+ defaultCornerRadiusPref.set(appearanceParams.getCornerRadius());
+ }
+ }
+
+ private void updateContent() {
+ updateCards();
+ updateButtons();
+ }
+
+ private void updateCards() {
+ for (BaseCard card : cards) {
+ card.update();
+ }
+ }
+
+ private void updateButtons() {
+ applyButton.setEnabled(!Algorithms.objectEquals(originalAppearanceParams, appearanceParams));
+ }
+
+ private void resetAppearance() {
+ appearanceParams.setSize(defaultSizePref.getDefaultValue());
+ appearanceParams.setOpacity(defaultOpacityPref.getDefaultValue());
+ appearanceParams.setCornerRadius(defaultCornerRadiusPref.getDefaultValue());
+ updateContent();
+ }
+
+ @NonNull
+ private ButtonAppearanceParams createAppearanceParams() {
+ return new ButtonAppearanceParams(null, defaultSizePref.get(),
+ defaultOpacityPref.get(), defaultCornerRadiusPref.get());
+ }
+
+ @Override
+ public void onCardPressed(@NonNull BaseCard card) {
+ updateButtons();
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ appearanceParams.saveToBundle(outState);
+ originalAppearanceParams.saveToBundle(outState);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ MapActivity activity = getMapActivity();
+ if (activity != null) {
+ activity.disableDrawer();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ MapActivity activity = getMapActivity();
+ if (activity != null) {
+ activity.enableDrawer();
+ }
+ }
+
+ @Nullable
+ public MapActivity getMapActivity() {
+ FragmentActivity activity = getActivity();
+ return activity instanceof MapActivity ? ((MapActivity) activity) : null;
+ }
+
+ @NonNull
+ public MapActivity requireMapActivity() {
+ FragmentActivity activity = getActivity();
+ if (!(activity instanceof MapActivity)) {
+ throw new IllegalStateException("Fragment " + this + " not attached to an activity.");
+ }
+ return (MapActivity) activity;
+ }
+
+ public static void showInstance(@NonNull FragmentManager manager) {
+ if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) {
+ DefaultButtonsAppearanceFragment fragment = new DefaultButtonsAppearanceFragment();
+ manager.beginTransaction()
+ .replace(R.id.fragmentContainer, fragment, TAG)
+ .addToBackStack(TAG)
+ .commitAllowingStateLoss();
+ }
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultMapButtonsFragment.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultMapButtonsFragment.java
index 66a8b29b750..5332e64b069 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultMapButtonsFragment.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/DefaultMapButtonsFragment.java
@@ -1,5 +1,6 @@
package net.osmand.plus.views.mapwidgets.configure.buttons;
+import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
@@ -69,8 +70,22 @@ public void onItemClick(@NonNull MapButtonState buttonState) {
protected void showOptionsMenu(@NonNull View view) {
List items = new ArrayList<>();
- items.add(new PopUpMenuItem.Builder(view.getContext())
+ Context context = view.getContext();
+
+ items.add(new PopUpMenuItem.Builder(context)
+ .setTitleId(R.string.shared_string_appearance)
+ .setIcon(getContentIcon(R.drawable.ic_action_appearance))
+ .setOnClickListener(v -> {
+ FragmentActivity activity = getActivity();
+ if (activity != null) {
+ FragmentManager manager = activity.getSupportFragmentManager();
+ DefaultButtonsAppearanceFragment.showInstance(manager);
+ }
+ }).create());
+
+ items.add(new PopUpMenuItem.Builder(context)
.setTitle(getString(R.string.reset_to_default))
+ .showTopDivider(true)
.setIcon(getContentIcon(R.drawable.ic_action_reset))
.setOnClickListener(v -> {
FragmentActivity activity = getActivity();
@@ -80,7 +95,7 @@ protected void showOptionsMenu(@NonNull View view) {
}
}).create());
- items.add(new PopUpMenuItem.Builder(view.getContext())
+ items.add(new PopUpMenuItem.Builder(context)
.setTitle(getString(R.string.copy_from_other_profile))
.setIcon(getContentIcon(R.drawable.ic_action_copy))
.setOnClickListener(v -> {
@@ -96,7 +111,6 @@ protected void showOptionsMenu(@NonNull View view) {
displayData.anchorView = view;
displayData.menuItems = items;
displayData.nightMode = nightMode;
- displayData.layoutId = R.layout.simple_popup_menu_item;
PopUpMenu.show(displayData);
}
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonCard.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonCard.java
index 881c003a50e..3ec3bde9c55 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonCard.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonCard.java
@@ -10,6 +10,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.quickaction.ButtonAppearanceParams;
@@ -28,7 +29,7 @@ public class MapButtonCard extends MapBaseCard {
private MapButton mapButton;
public MapButtonCard(@NonNull MapActivity mapActivity, @NonNull MapButtonState buttonState,
- @Nullable ButtonAppearanceParams customAppearanceParams) {
+ @Nullable ButtonAppearanceParams customAppearanceParams) {
super(mapActivity, false);
this.buttonState = buttonState;
this.customAppearanceParams = customAppearanceParams;
@@ -45,7 +46,7 @@ protected void updateContent() {
container.removeAllViews();
setupButton(container);
- setupButtonBackground(container);
+ setupButtonBackground(container, nightMode);
}
public void setupButton(@NonNull ViewGroup container) {
@@ -71,7 +72,8 @@ public void updateButton(@NonNull ButtonAppearanceParams appearanceParams) {
}
}
- private void setupButtonBackground(@NonNull View view) {
+ public static void setupButtonBackground(@NonNull View view, boolean nightMode) {
+ OsmandApplication app = (OsmandApplication) view.getContext().getApplicationContext();
RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer();
if (renderer != null) {
MapRenderRepositories maps = app.getResourceManager().getRenderer();
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonState.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonState.java
index e6ca647e305..a0dbe391c38 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonState.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/configure/buttons/MapButtonState.java
@@ -1,6 +1,7 @@
package net.osmand.plus.views.mapwidgets.configure.buttons;
import static net.osmand.plus.quickaction.ButtonAppearanceParams.BIG_SIZE_DP;
+import static net.osmand.plus.quickaction.ButtonAppearanceParams.ORIGINAL_VALUE;
import static net.osmand.plus.quickaction.ButtonAppearanceParams.ROUND_RADIUS_DP;
import static net.osmand.plus.quickaction.ButtonAppearanceParams.TRANSPARENT_ALPHA;
@@ -18,6 +19,7 @@
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.quickaction.ButtonAppearanceParams;
+import net.osmand.plus.quickaction.MapButtonsHelper;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
@@ -60,11 +62,11 @@ public MapButtonState(@NonNull OsmandApplication app, @NonNull String id) {
this.allPreferences = new ArrayList<>();
this.iconPref = addPreference(settings.registerStringPreference(id + "_icon", null)).makeProfile().cache();
- this.sizePref = addPreference(settings.registerIntPreference(id + "_size", -1)).makeProfile().cache();
- this.opacityPref = addPreference(settings.registerFloatPreference(id + "_opacity", -1)).makeProfile().cache();
- this.cornerRadiusPref = addPreference(settings.registerIntPreference(id + "_corner_radius", -1)).makeProfile().cache();
- this.portraitPositionPref = addPreference(settings.registerLongPreference(id + "_position_portrait", -1)).makeProfile().cache();
- this.landscapePositionPref = addPreference(settings.registerLongPreference(id + "_position_landscape", -1)).makeProfile().cache();
+ this.sizePref = addPreference(settings.registerIntPreference(id + "_size", ORIGINAL_VALUE)).makeProfile().cache();
+ this.opacityPref = addPreference(settings.registerFloatPreference(id + "_opacity", ORIGINAL_VALUE)).makeProfile().cache();
+ this.cornerRadiusPref = addPreference(settings.registerIntPreference(id + "_corner_radius", ORIGINAL_VALUE)).makeProfile().cache();
+ this.portraitPositionPref = addPreference(settings.registerLongPreference(id + "_position_portrait", ORIGINAL_VALUE)).makeProfile().cache();
+ this.landscapePositionPref = addPreference(settings.registerLongPreference(id + "_position_landscape", ORIGINAL_VALUE)).makeProfile().cache();
this.positionSize = setupButtonPosition(new ButtonPositionSize(getId()));
this.defaultPositionSize = setupButtonPosition(new ButtonPositionSize(getId()));