Add custom track colors
This commit is contained in:
parent
30a7ebcb30
commit
094bd14c62
7 changed files with 437 additions and 18 deletions
|
@ -563,6 +563,7 @@ dependencies {
|
||||||
implementation ("com.github.HITGIF:TextFieldBoxes:1.4.5"){
|
implementation ("com.github.HITGIF:TextFieldBoxes:1.4.5"){
|
||||||
exclude group: 'com.android.support'
|
exclude group: 'com.android.support'
|
||||||
}
|
}
|
||||||
|
implementation 'com.jaredrummler:colorpicker:1.1.0'
|
||||||
|
|
||||||
huaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar')
|
huaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar')
|
||||||
freehuaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar')
|
freehuaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar')
|
||||||
|
|
63
OsmAnd/res/layout/custom_color_picker.xml
Normal file
63
OsmAnd/res/layout/custom_color_picker.xml
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout 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="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding">
|
||||||
|
|
||||||
|
<com.jaredrummler.android.colorpicker.ColorPickerView
|
||||||
|
android:id="@+id/color_picker_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:paddingBottom="@dimen/content_padding_small"
|
||||||
|
app:cpv_alphaChannelVisible="true" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.jaredrummler.android.colorpicker.ColorPanelView
|
||||||
|
android:id="@+id/color_panel_new"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:cpv_colorShape="square" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="@dimen/content_padding"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/color_hex_text_input"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:boxBackgroundColor="@color/material_text_input_layout_bg"
|
||||||
|
app:hintEnabled="false"
|
||||||
|
app:prefixText="#">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/color_hex_edit_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:maxLines="4"
|
||||||
|
android:minHeight="@dimen/bottom_sheet_list_item_height"
|
||||||
|
android:paddingStart="@dimen/content_padding_small"
|
||||||
|
android:paddingLeft="@dimen/content_padding_small"
|
||||||
|
android:paddingEnd="@dimen/content_padding_small"
|
||||||
|
android:paddingRight="@dimen/content_padding_small"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
tools:text="F1FF00" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.FlowLayout
|
<com.google.android.material.internal.FlowLayout
|
||||||
android:id="@+id/select_color"
|
android:id="@+id/select_color"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -2197,6 +2197,7 @@ public class OsmandSettings {
|
||||||
public final CommonPreference<String> CURRENT_TRACK_WIDTH = new StringPreference("current_track_width", "").makeGlobal().cache();
|
public final CommonPreference<String> CURRENT_TRACK_WIDTH = new StringPreference("current_track_width", "").makeGlobal().cache();
|
||||||
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference("current_track_show_arrows", false).makeGlobal().cache();
|
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference("current_track_show_arrows", false).makeGlobal().cache();
|
||||||
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference("current_track_show_start_finish", true).makeGlobal().cache();
|
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference("current_track_show_start_finish", true).makeGlobal().cache();
|
||||||
|
public final ListStringPreference CUSTOM_TRACK_COLORS = (ListStringPreference) new ListStringPreference("custom_track_colors", null, ",").makeGlobal();
|
||||||
|
|
||||||
// this value string is synchronized with settings_pref.xml preference name
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
public final CommonPreference<Integer> SAVE_TRACK_INTERVAL = new IntPreference("save_track_interval", 5000).makeProfile();
|
public final CommonPreference<Integer> SAVE_TRACK_INTERVAL = new IntPreference("save_track_interval", 5000).makeProfile();
|
||||||
|
|
228
OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java
Normal file
228
OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import com.jaredrummler.android.colorpicker.ColorPanelView;
|
||||||
|
import com.jaredrummler.android.colorpicker.ColorPickerView;
|
||||||
|
import com.jaredrummler.android.colorpicker.ColorPickerView.OnColorChangedListener;
|
||||||
|
|
||||||
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implements OnColorChangedListener {
|
||||||
|
|
||||||
|
private static final String TAG = CustomColorBottomSheet.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final Log log = PlatformUtil.getLog(CustomColorBottomSheet.class);
|
||||||
|
|
||||||
|
private static final String NEW_SELECTED_COLOR = "new_selected_color";
|
||||||
|
private static final String PREV_SELECTED_COLOR = "prev_selected_color";
|
||||||
|
|
||||||
|
private ColorPickerView colorPicker;
|
||||||
|
private ColorPanelView newColorPanel;
|
||||||
|
|
||||||
|
private EditText hexEditText;
|
||||||
|
private boolean fromEditText;
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
private int prevColor;
|
||||||
|
@ColorInt
|
||||||
|
private int newColor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createMenuItems(Bundle savedInstanceState) {
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
newColor = savedInstanceState.getInt(NEW_SELECTED_COLOR);
|
||||||
|
prevColor = savedInstanceState.getInt(PREV_SELECTED_COLOR);
|
||||||
|
} else {
|
||||||
|
Bundle args = getArguments();
|
||||||
|
if (args != null) {
|
||||||
|
prevColor = args.getInt(PREV_SELECTED_COLOR);
|
||||||
|
newColor = prevColor != -1 ? prevColor : Color.RED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items.add(new TitleItem(getString(R.string.select_color)));
|
||||||
|
|
||||||
|
BaseBottomSheetItem item = new SimpleBottomSheetItem.Builder()
|
||||||
|
.setCustomView(createPickerView())
|
||||||
|
.create();
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
outState.putInt(NEW_SELECTED_COLOR, newColor);
|
||||||
|
outState.putInt(PREV_SELECTED_COLOR, prevColor);
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private View createPickerView() {
|
||||||
|
LayoutInflater themedInflater = UiUtilities.getMaterialInflater(getActivity(), nightMode);
|
||||||
|
View colorView = themedInflater.inflate(R.layout.custom_color_picker, null);
|
||||||
|
colorPicker = colorView.findViewById(R.id.color_picker_view);
|
||||||
|
newColorPanel = colorView.findViewById(R.id.color_panel_new);
|
||||||
|
hexEditText = colorView.findViewById(R.id.color_hex_edit_text);
|
||||||
|
|
||||||
|
setHex(newColor);
|
||||||
|
newColorPanel.setColor(newColor);
|
||||||
|
colorPicker.setColor(newColor, true);
|
||||||
|
colorPicker.setOnColorChangedListener(this);
|
||||||
|
hexEditText.addTextChangedListener(new TextWatcher() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (hexEditText.isFocused()) {
|
||||||
|
int color = parseColorString(s.toString());
|
||||||
|
if (color != colorPicker.getColor()) {
|
||||||
|
fromEditText = true;
|
||||||
|
colorPicker.setColor(color, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return colorView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onColorChanged(int newColor) {
|
||||||
|
this.newColor = newColor;
|
||||||
|
if (newColorPanel != null) {
|
||||||
|
newColorPanel.setColor(newColor);
|
||||||
|
}
|
||||||
|
if (!fromEditText && hexEditText != null) {
|
||||||
|
setHex(newColor);
|
||||||
|
Activity activity = getActivity();
|
||||||
|
if (activity != null && hexEditText.hasFocus()) {
|
||||||
|
AndroidUtils.hideSoftKeyboard(activity, hexEditText);
|
||||||
|
hexEditText.clearFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fromEditText = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHex(int color) {
|
||||||
|
hexEditText.setText(String.format("%08X", color));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getRightBottomButtonTextId() {
|
||||||
|
return R.string.shared_string_apply;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRightBottomButtonClick() {
|
||||||
|
Fragment target = getTargetFragment();
|
||||||
|
if (target instanceof ColorPickerListener) {
|
||||||
|
((ColorPickerListener) target).onColorSelected(prevColor, newColor);
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, int prevColor) {
|
||||||
|
try {
|
||||||
|
if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(CustomColorBottomSheet.TAG) == null) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(PREV_SELECTED_COLOR, prevColor);
|
||||||
|
|
||||||
|
CustomColorBottomSheet customColorBottomSheet = new CustomColorBottomSheet();
|
||||||
|
customColorBottomSheet.setArguments(args);
|
||||||
|
customColorBottomSheet.setTargetFragment(target, 0);
|
||||||
|
customColorBottomSheet.show(fragmentManager, CustomColorBottomSheet.TAG);
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int parseColorString(String colorString) throws NumberFormatException {
|
||||||
|
int a, r, g, b = 0;
|
||||||
|
if (colorString.startsWith("#")) {
|
||||||
|
colorString = colorString.substring(1);
|
||||||
|
}
|
||||||
|
if (colorString.length() == 0) {
|
||||||
|
r = 0;
|
||||||
|
a = 255;
|
||||||
|
g = 0;
|
||||||
|
} else if (colorString.length() <= 2) {
|
||||||
|
a = 255;
|
||||||
|
r = 0;
|
||||||
|
b = Integer.parseInt(colorString, 16);
|
||||||
|
g = 0;
|
||||||
|
} else if (colorString.length() == 3) {
|
||||||
|
a = 255;
|
||||||
|
r = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||||
|
g = Integer.parseInt(colorString.substring(1, 2), 16);
|
||||||
|
b = Integer.parseInt(colorString.substring(2, 3), 16);
|
||||||
|
} else if (colorString.length() == 4) {
|
||||||
|
a = 255;
|
||||||
|
r = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||||
|
g = r;
|
||||||
|
r = 0;
|
||||||
|
b = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||||
|
} else if (colorString.length() == 5) {
|
||||||
|
a = 255;
|
||||||
|
r = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||||
|
g = Integer.parseInt(colorString.substring(1, 3), 16);
|
||||||
|
b = Integer.parseInt(colorString.substring(3, 5), 16);
|
||||||
|
} else if (colorString.length() == 6) {
|
||||||
|
a = 255;
|
||||||
|
r = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||||
|
g = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||||
|
b = Integer.parseInt(colorString.substring(4, 6), 16);
|
||||||
|
} else if (colorString.length() == 7) {
|
||||||
|
a = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||||
|
r = Integer.parseInt(colorString.substring(1, 3), 16);
|
||||||
|
g = Integer.parseInt(colorString.substring(3, 5), 16);
|
||||||
|
b = Integer.parseInt(colorString.substring(5, 7), 16);
|
||||||
|
} else if (colorString.length() == 8) {
|
||||||
|
a = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||||
|
r = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||||
|
g = Integer.parseInt(colorString.substring(4, 6), 16);
|
||||||
|
b = Integer.parseInt(colorString.substring(6, 8), 16);
|
||||||
|
} else {
|
||||||
|
b = -1;
|
||||||
|
g = -1;
|
||||||
|
r = -1;
|
||||||
|
a = -1;
|
||||||
|
}
|
||||||
|
return Color.argb(a, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ColorPickerListener {
|
||||||
|
|
||||||
|
void onColorSelected(@ColorInt int prevColor, @ColorInt int newColor);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,7 @@ import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
|
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
|
||||||
import net.osmand.plus.track.SplitTrackAsyncTask.SplitTrackListener;
|
import net.osmand.plus.track.SplitTrackAsyncTask.SplitTrackListener;
|
||||||
import net.osmand.render.RenderingRulesStorage;
|
import net.osmand.render.RenderingRulesStorage;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -57,9 +58,9 @@ import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
|
||||||
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD;
|
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD;
|
||||||
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM;
|
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM;
|
||||||
|
|
||||||
public class TrackAppearanceFragment extends ContextMenuScrollFragment implements CardListener {
|
public class TrackAppearanceFragment extends ContextMenuScrollFragment implements CardListener, ColorPickerListener {
|
||||||
|
|
||||||
public static final String TAG = TrackAppearanceFragment.class.getSimpleName();
|
public static final String TAG = TrackAppearanceFragment.class.getName();
|
||||||
|
|
||||||
private static final Log log = PlatformUtil.getLog(TrackAppearanceFragment.class);
|
private static final Log log = PlatformUtil.getLog(TrackAppearanceFragment.class);
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
|
|
||||||
private TrackWidthCard trackWidthCard;
|
private TrackWidthCard trackWidthCard;
|
||||||
private SplitIntervalCard splitIntervalCard;
|
private SplitIntervalCard splitIntervalCard;
|
||||||
|
private TrackColoringCard trackColoringCard;
|
||||||
|
|
||||||
private ImageView trackIcon;
|
private ImageView trackIcon;
|
||||||
|
|
||||||
|
@ -324,6 +326,11 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onColorSelected(int prevColor, int newColor) {
|
||||||
|
trackColoringCard.onColorSelected(prevColor, newColor);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int applyPosY(int currentY, boolean needCloseMenu, boolean needMapAdjust, int previousMenuState, int newMenuState, int dZoom, boolean animated) {
|
protected int applyPosY(int currentY, boolean needCloseMenu, boolean needMapAdjust, int previousMenuState, int newMenuState, int dZoom, boolean animated) {
|
||||||
int y = super.applyPosY(currentY, needCloseMenu, needMapAdjust, previousMenuState, newMenuState, dZoom, animated);
|
int y = super.applyPosY(currentY, needCloseMenu, needMapAdjust, previousMenuState, newMenuState, dZoom, animated);
|
||||||
|
@ -555,7 +562,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
directionArrowsCard.setListener(this);
|
directionArrowsCard.setListener(this);
|
||||||
cardsContainer.addView(directionArrowsCard.build(mapActivity));
|
cardsContainer.addView(directionArrowsCard.build(mapActivity));
|
||||||
|
|
||||||
TrackColoringCard trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo);
|
trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo, this);
|
||||||
trackColoringCard.setListener(this);
|
trackColoringCard.setListener(this);
|
||||||
cardsContainer.addView(trackColoringCard.build(mapActivity));
|
cardsContainer.addView(trackColoringCard.build(mapActivity));
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package net.osmand.plus.track;
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.ColorInt;
|
import androidx.annotation.ColorInt;
|
||||||
|
@ -14,10 +15,14 @@ import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
import androidx.appcompat.content.res.AppCompatResources;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.internal.FlowLayout;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.UiUtilities;
|
import net.osmand.plus.UiUtilities;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
@ -25,16 +30,22 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem;
|
||||||
import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType;
|
import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType;
|
||||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
import net.osmand.plus.widgets.FlowLayout;
|
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.getAppearanceItems;
|
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.getAppearanceItems;
|
||||||
|
|
||||||
public class TrackColoringCard extends BaseCard {
|
public class TrackColoringCard extends BaseCard implements ColorPickerListener {
|
||||||
|
|
||||||
|
public static final int INVALID_VALUE = -1;
|
||||||
|
|
||||||
private final static String SOLID_COLOR = "solid_color";
|
private final static String SOLID_COLOR = "solid_color";
|
||||||
|
private static final Log log = PlatformUtil.getLog(TrackColoringCard.class);
|
||||||
|
|
||||||
private TrackDrawInfo trackDrawInfo;
|
private TrackDrawInfo trackDrawInfo;
|
||||||
|
|
||||||
|
@ -42,10 +53,15 @@ public class TrackColoringCard extends BaseCard {
|
||||||
private TrackAppearanceItem selectedAppearanceItem;
|
private TrackAppearanceItem selectedAppearanceItem;
|
||||||
private List<TrackAppearanceItem> appearanceItems;
|
private List<TrackAppearanceItem> appearanceItems;
|
||||||
|
|
||||||
public TrackColoringCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo) {
|
private List<Integer> customColors;
|
||||||
|
private Fragment target;
|
||||||
|
|
||||||
|
public TrackColoringCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo, Fragment target) {
|
||||||
super(mapActivity);
|
super(mapActivity);
|
||||||
|
this.target = target;
|
||||||
this.trackDrawInfo = trackDrawInfo;
|
this.trackDrawInfo = trackDrawInfo;
|
||||||
appearanceItems = getGradientAppearanceItems();
|
appearanceItems = getGradientAppearanceItems();
|
||||||
|
customColors = getCustomColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,6 +83,25 @@ public class TrackColoringCard extends BaseCard {
|
||||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider());
|
AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Integer> getCustomColors() {
|
||||||
|
List<Integer> colors = new ArrayList<>();
|
||||||
|
List<String> colorNames = app.getSettings().CUSTOM_TRACK_COLORS.getStringsList();
|
||||||
|
if (colorNames != null) {
|
||||||
|
for (String colorHex : colorNames) {
|
||||||
|
try {
|
||||||
|
if (!Algorithms.isEmpty(colorHex)) {
|
||||||
|
int color = Algorithms.parseColor(colorHex);
|
||||||
|
colors.add(color);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
private List<TrackAppearanceItem> getGradientAppearanceItems() {
|
private List<TrackAppearanceItem> getGradientAppearanceItems() {
|
||||||
List<TrackAppearanceItem> items = new ArrayList<>();
|
List<TrackAppearanceItem> items = new ArrayList<>();
|
||||||
items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle));
|
items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle));
|
||||||
|
@ -80,6 +115,16 @@ public class TrackColoringCard extends BaseCard {
|
||||||
|
|
||||||
private void createColorSelector() {
|
private void createColorSelector() {
|
||||||
FlowLayout selectColor = view.findViewById(R.id.select_color);
|
FlowLayout selectColor = view.findViewById(R.id.select_color);
|
||||||
|
selectColor.removeAllViews();
|
||||||
|
|
||||||
|
for (int color : customColors) {
|
||||||
|
selectColor.addView(createColorItemView(color, selectColor, true));
|
||||||
|
}
|
||||||
|
if (customColors.size() < 6) {
|
||||||
|
selectColor.addView(createAddCustomColorItemView(selectColor));
|
||||||
|
}
|
||||||
|
selectColor.addView(createDividerView(selectColor));
|
||||||
|
|
||||||
List<Integer> colors = new ArrayList<>();
|
List<Integer> colors = new ArrayList<>();
|
||||||
for (AppearanceListItem appearanceListItem : getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) {
|
for (AppearanceListItem appearanceListItem : getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) {
|
||||||
if (!colors.contains(appearanceListItem.getColor())) {
|
if (!colors.contains(appearanceListItem.getColor())) {
|
||||||
|
@ -87,20 +132,13 @@ public class TrackColoringCard extends BaseCard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int color : colors) {
|
for (int color : colors) {
|
||||||
selectColor.addView(createColorItemView(color, selectColor), new FlowLayout.LayoutParams(0, 0));
|
selectColor.addView(createColorItemView(color, selectColor, false));
|
||||||
}
|
}
|
||||||
updateColorSelector(trackDrawInfo.getColor(), selectColor);
|
updateColorSelector(trackDrawInfo.getColor(), selectColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private View createColorItemView(@ColorInt final int color, final FlowLayout rootView) {
|
private View createColorItemView(@ColorInt final int color, final FlowLayout rootView, boolean customColor) {
|
||||||
FrameLayout colorItemView = (FrameLayout) UiUtilities.getInflater(rootView.getContext(), nightMode)
|
View colorItemView = createCircleView(rootView);
|
||||||
.inflate(R.layout.point_editor_button, rootView, false);
|
|
||||||
ImageView outline = colorItemView.findViewById(R.id.outline);
|
|
||||||
outline.setImageDrawable(
|
|
||||||
UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.bg_point_circle_contour),
|
|
||||||
ContextCompat.getColor(app,
|
|
||||||
nightMode ? R.color.stroked_buttons_and_links_outline_dark
|
|
||||||
: R.color.stroked_buttons_and_links_outline_light)));
|
|
||||||
ImageView backgroundCircle = colorItemView.findViewById(R.id.background);
|
ImageView backgroundCircle = colorItemView.findViewById(R.id.background);
|
||||||
backgroundCircle.setImageDrawable(UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.bg_point_circle), color));
|
backgroundCircle.setImageDrawable(UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.bg_point_circle), color));
|
||||||
backgroundCircle.setOnClickListener(new View.OnClickListener() {
|
backgroundCircle.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -116,10 +154,68 @@ public class TrackColoringCard extends BaseCard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (customColor) {
|
||||||
|
backgroundCircle.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity != null) {
|
||||||
|
CustomColorBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), target, color);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
colorItemView.setTag(color);
|
colorItemView.setTag(color);
|
||||||
return colorItemView;
|
return colorItemView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private View createAddCustomColorItemView(FlowLayout rootView) {
|
||||||
|
View colorItemView = createCircleView(rootView);
|
||||||
|
ImageView backgroundCircle = colorItemView.findViewById(R.id.background);
|
||||||
|
|
||||||
|
int bgColorId = nightMode ? R.color.activity_background_color_dark : R.color.activity_background_color_light;
|
||||||
|
Drawable backgroundIcon = app.getUIUtilities().getIcon(R.drawable.bg_point_circle, bgColorId);
|
||||||
|
|
||||||
|
ImageView icon = colorItemView.findViewById(R.id.icon);
|
||||||
|
icon.setVisibility(View.VISIBLE);
|
||||||
|
int activeColorResId = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
|
||||||
|
icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_add, activeColorResId));
|
||||||
|
|
||||||
|
backgroundCircle.setImageDrawable(backgroundIcon);
|
||||||
|
backgroundCircle.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity != null) {
|
||||||
|
CustomColorBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), target, TrackColoringCard.INVALID_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return colorItemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View createDividerView(FlowLayout rootView) {
|
||||||
|
LayoutInflater themedInflater = UiUtilities.getInflater(view.getContext(), nightMode);
|
||||||
|
View divider = themedInflater.inflate(R.layout.simple_divider_item, rootView, false);
|
||||||
|
|
||||||
|
LinearLayout dividerContainer = new LinearLayout(view.getContext());
|
||||||
|
dividerContainer.addView(divider);
|
||||||
|
dividerContainer.setPadding(0, AndroidUtils.dpToPx(app, 1), 0, AndroidUtils.dpToPx(app, 5));
|
||||||
|
|
||||||
|
return dividerContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View createCircleView(ViewGroup rootView) {
|
||||||
|
LayoutInflater themedInflater = UiUtilities.getInflater(view.getContext(), nightMode);
|
||||||
|
View circleView = themedInflater.inflate(R.layout.point_editor_button, rootView, false);
|
||||||
|
ImageView outline = circleView.findViewById(R.id.outline);
|
||||||
|
int colorId = nightMode ? R.color.stroked_buttons_and_links_outline_dark : R.color.stroked_buttons_and_links_outline_light;
|
||||||
|
Drawable contourIcon = app.getUIUtilities().getIcon(R.drawable.bg_point_circle_contour, colorId);
|
||||||
|
outline.setImageDrawable(contourIcon);
|
||||||
|
return circleView;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateColorSelector(int color, View rootView) {
|
private void updateColorSelector(int color, View rootView) {
|
||||||
View oldColor = rootView.findViewWithTag(trackDrawInfo.getColor());
|
View oldColor = rootView.findViewWithTag(trackDrawInfo.getColor());
|
||||||
if (oldColor != null) {
|
if (oldColor != null) {
|
||||||
|
@ -175,6 +271,29 @@ public class TrackColoringCard extends BaseCard {
|
||||||
updateColorSelector();
|
updateColorSelector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onColorSelected(int prevColor, int newColor) {
|
||||||
|
if (prevColor == INVALID_VALUE && customColors.size() < 6) {
|
||||||
|
customColors.add(newColor);
|
||||||
|
} else if (!Algorithms.isEmpty(customColors)) {
|
||||||
|
int index = customColors.indexOf(prevColor);
|
||||||
|
if (index != INVALID_VALUE) {
|
||||||
|
customColors.set(index, newColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveCustomColors();
|
||||||
|
updateContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCustomColors() {
|
||||||
|
List<String> colorNames = new ArrayList<>();
|
||||||
|
for (Integer color : customColors) {
|
||||||
|
String colorHex = Algorithms.colorToString(color);
|
||||||
|
colorNames.add(colorHex);
|
||||||
|
}
|
||||||
|
app.getSettings().CUSTOM_TRACK_COLORS.setStringsList(colorNames);
|
||||||
|
}
|
||||||
|
|
||||||
private class TrackColoringAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
private class TrackColoringAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
||||||
|
|
||||||
private List<TrackAppearanceItem> items;
|
private List<TrackAppearanceItem> items;
|
||||||
|
|
Loading…
Reference in a new issue