Compare commits

..

15 Commits

Author SHA1 Message Date
x7z4w
2f9ce76c28 Update .git-blame-ignore-revs
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:23:46 +00:00
x7z4w
ffe07d3337 [core] Implicit m2::Point hash
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:19:02 +00:00
x7z4w
546383d755 [generator] Implement hash for OsmElement::Tag
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:19:02 +00:00
x7z4w
bf30165b5f [core] Replace SmallMap
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:19:02 +00:00
x7z4w
0288b97b13 [core] Switch to ankerl::unordered_dense
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:18:55 +00:00
x7z4w
7e561d09d3 [drape] nits
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-14 20:13:26 +00:00
map-per
298518ae72 [Android] Fix crash when selectedCountry is null
Signed-off-by: map-per <map-per@gmx.de>
2025-12-13 22:58:25 +01:00
Jean-Baptiste
3bad6d25f0 [android] Remove usage of attr fonts styles
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-13 19:28:28 +01:00
Jean-Baptiste
d36361d669 [android] Fix aligment of items in AppBar
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-13 17:08:35 +01:00
Jean-Baptiste
688e20b1a6 [android] Revert M3 changes about main fonts styles
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-13 10:39:47 +01:00
Jean-Baptiste
85462161b2 [android] Fix theme not apply correctly
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-12 21:11:04 +01:00
Henry Sternberg
b929823f6b [routing] Avoid using parking aisles
Signed-off-by: Henry Sternberg <henry@bluelightmaps.com>
Co-authored-by: Henry Sternberg <henry@bluelightmaps.com>
Co-committed-by: Henry Sternberg <henry@bluelightmaps.com>
2025-12-12 15:37:21 +01:00
Jean-Baptiste
22dd799585 [android] Remove hardcoded MaterialComponents fonts styles
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-11 20:33:24 +01:00
Jean-Baptiste
6864d101e2 [android] Migrate text appearance to Material 3
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-11 19:36:54 +01:00
Jean-Baptiste
4bfb62b373 [android] Fix height of all day view
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-11 16:22:22 +01:00
351 changed files with 4730 additions and 2467 deletions

View File

@@ -2,3 +2,5 @@
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
1377b81bf1cac72bb6da192da7fed6696d5d5281
0288b97b1367bb971eded1018f560598ea274e6c
bf30165b5f5de0907c3c64524a3bf8121624b0b7

83
3party/ankerl/stl.h Normal file
View File

@@ -0,0 +1,83 @@
///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////
// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.
// Version 4.8.1
// https://github.com/martinus/unordered_dense
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 Martin Leitner-Ankerl <martin.ankerl@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef ANKERL_STL_H
#define ANKERL_STL_H
#include <array> // for array
#include <cstdint> // for uint64_t, uint32_t, std::uint8_t, UINT64_C
#include <cstring> // for size_t, memcpy, memset
#include <functional> // for equal_to, hash
#include <initializer_list> // for initializer_list
#include <iterator> // for pair, distance
#include <limits> // for numeric_limits
#include <memory> // for allocator, allocator_traits, shared_ptr
#include <optional> // for optional
#include <stdexcept> // for out_of_range
#include <string> // for basic_string
#include <string_view> // for basic_string_view, hash
#include <tuple> // for forward_as_tuple
#include <type_traits> // for enable_if_t, declval, conditional_t, ena...
#include <utility> // for forward, exchange, pair, as_const, piece...
#include <vector> // for vector
// <memory_resource> includes <mutex>, which fails to compile if
// targeting GCC >= 13 with the (rewritten) win32 thread model, and
// targeting Windows earlier than Vista (0x600). GCC predefines
// _REENTRANT when using the 'posix' model, and doesn't when using the
// 'win32' model.
#if defined __MINGW64__ && defined __GNUC__ && __GNUC__ >= 13 && !defined _REENTRANT
// _WIN32_WINNT is guaranteed to be defined here because of the
// <cstdint> inclusion above.
# ifndef _WIN32_WINNT
# error "_WIN32_WINNT not defined"
# endif
# if _WIN32_WINNT < 0x600
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 1 // NOLINT(cppcoreguidelines-macro-usage)
# endif
#endif
#ifndef ANKERL_MEMORY_RESOURCE_IS_BAD
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 0 // NOLINT(cppcoreguidelines-macro-usage)
#endif
#if defined(__has_include) && !defined(ANKERL_UNORDERED_DENSE_DISABLE_PMR)
# if __has_include(<memory_resource>) && !ANKERL_MEMORY_RESOURCE_IS_BAD()
# define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage)
# include <memory_resource> // for polymorphic_allocator
# elif __has_include(<experimental/memory_resource>)
# define ANKERL_UNORDERED_DENSE_PMR std::experimental::pmr // NOLINT(cppcoreguidelines-macro-usage)
# include <experimental/memory_resource> // for polymorphic_allocator
# endif
#endif
#if defined(_MSC_VER) && defined(_M_X64)
# include <intrin.h>
# pragma intrinsic(_umul128)
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,6 @@ import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

View File

@@ -253,7 +253,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mProgress.setMax(bytes);
// Start progress at 1% according to M3 guidelines
mProgress.setProgressCompat(bytes/100, true);
mProgress.setProgressCompat(bytes / 100, true);
}
else
finishFilesDownload(bytes);
@@ -372,7 +372,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
mProgress.setMax((int) item.totalSize);
// Start progress at 1% according to M3 guidelines
mProgress.setProgressCompat((int) (item.totalSize/100), true);
mProgress.setProgressCompat((int) (item.totalSize / 100), true);
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
MapManagerHelper.startDownload(mCurrentCountry);
@@ -424,17 +424,17 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
default -> throw new AssertionError("Unexpected result code = " + result);
};
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(titleId)
.setMessage(messageId)
.setCancelable(true)
.setOnCancelListener((dialog) -> setAction(PAUSE))
.setPositiveButton(R.string.try_again,
(dialog, which) -> {
setAction(TRY_AGAIN);
onTryAgainClicked();
})
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(titleId)
.setMessage(messageId)
.setCancelable(true)
.setOnCancelListener((dialog) -> setAction(PAUSE))
.setPositiveButton(R.string.try_again,
(dialog, which) -> {
setAction(TRY_AGAIN);
onTryAgainClicked();
})
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
}

View File

@@ -38,8 +38,9 @@ public class OsmUploadWork extends Worker
{
final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
}
final OneTimeWorkRequest wr = builder.build();
WorkManager.getInstance(context).beginUniqueWork("UploadOsmChanges", ExistingWorkPolicy.KEEP, wr).enqueue();

View File

@@ -17,7 +17,6 @@ import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
import app.organicmaps.R;
import app.organicmaps.sdk.util.log.Logger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

View File

@@ -10,7 +10,6 @@ import androidx.fragment.app.DialogFragment;
public class BaseMwmDialogFragment extends DialogFragment
{
protected int getStyle()
{
return STYLE_NORMAL;

View File

@@ -282,11 +282,13 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{
if (isEmptySearchResults())
{
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail);
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query,
R.drawable.ic_search_fail);
}
else if (isEmpty())
{
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message, R.drawable.ic_bookmarks);
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message,
R.drawable.ic_bookmarks);
}
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();

View File

@@ -23,7 +23,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.RecyclerClickListener;
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.imageview.ShapeableImageView;
@@ -458,10 +457,12 @@ public class Holders
String formattedDesc = desc.replace("\n", "<br>");
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
if (!TextUtils.isEmpty(spannedDesc)) {
if (!TextUtils.isEmpty(spannedDesc))
{
mDescText.setText(spannedDesc);
}
else {
else
{
mDescText.setText(R.string.list_description_empty);
}
}

View File

@@ -50,8 +50,8 @@ public final class IntentUtils
}
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
private static void processNavigationIntent(@NonNull CarContext carContext,
@NonNull Renderer surfaceRenderer, @NonNull Intent intent)
private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull Renderer surfaceRenderer,
@NonNull Intent intent)
{
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during
// navigation or route planning. Skip navigation intents during navigation

View File

@@ -31,7 +31,7 @@ public final class RoutingHelpers
default -> Distance.UNIT_METERS;
};
return Distance.create(distance.mDistance, displayUnit);
return Distance.create(distance.mDistance, displayUnit);
}
@NonNull
@@ -52,7 +52,7 @@ public final class RoutingHelpers
default -> LaneDirection.SHAPE_UNKNOWN;
};
return LaneDirection.create(shape, isRecommended);
return LaneDirection.create(shape, isRecommended);
}
@NonNull
@@ -77,7 +77,7 @@ public final class RoutingHelpers
case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT;
case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT;
};
final Maneuver.Builder builder = new Maneuver.Builder(maneuverType);
final Maneuver.Builder builder = new Maneuver.Builder(maneuverType);
if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW)
builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1);
builder.setIcon(new CarIcon.Builder(createManeuverIcon(context, carDirection, roundaboutExitNum)).build());
@@ -85,7 +85,8 @@ public final class RoutingHelpers
}
@NonNull
private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum)
private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection,
int roundaboutExitNum)
{
if (!CarDirection.isRoundAbout(carDirection) || roundaboutExitNum == 0)
{

View File

@@ -39,8 +39,7 @@ public final class UiHelpers
}
@NonNull
public static ActionStrip createMapActionStrip(@NonNull CarContext context,
@NonNull Renderer surfaceRenderer)
public static ActionStrip createMapActionStrip(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
{
final CarIcon iconPlus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_plus)).build();
final CarIcon iconMinus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_minus)).build();
@@ -59,15 +58,13 @@ public final class UiHelpers
}
@NonNull
public static MapController createMapController(@NonNull CarContext context,
@NonNull Renderer surfaceRenderer)
public static MapController createMapController(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
{
return new MapController.Builder().setMapActionStrip(createMapActionStrip(context, surfaceRenderer)).build();
}
@NonNull
public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen,
@NonNull Renderer surfaceRenderer)
public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer)
{
return createSettingsAction(mapScreen, surfaceRenderer, null);
}
@@ -81,8 +78,7 @@ public final class UiHelpers
}
@NonNull
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen,
@NonNull Renderer surfaceRenderer,
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer,
@Nullable OnScreenResultListener onScreenResultListener)
{
final CarContext context = mapScreen.getCarContext();
@@ -123,8 +119,7 @@ public final class UiHelpers
return null;
final Row.Builder builder = new Row.Builder();
builder.setImage(
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
if (isEmptyTT)
builder.setTitle(ohStr);

View File

@@ -125,7 +125,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
positiveButton.setOnClickListener(view -> {
final String result = mEtInput.getText().toString();
if (validateInput(requireActivity(), result)) {
if (validateInput(requireActivity(), result))
{
processInput(result);
editTextDialog.dismiss();
}

View File

@@ -4,7 +4,6 @@ import android.location.Location;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import app.organicmaps.MwmActivity;
@@ -49,7 +48,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
@Override
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
{
if (mCurrentCountry == null) {
if (mCurrentCountry == null)
{
updateOfflineExplanationVisibility();
return;
}
@@ -109,10 +109,13 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
return enqueued || progress || applying;
}
private void updateOfflineExplanationVisibility() {
if (mOfflineExplanation == null) return;
private void updateOfflineExplanationVisibility()
{
if (mOfflineExplanation == null)
return;
// hide once threshold reached; safe to call repeatedly.
app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD), mOfflineExplanation);
app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD),
mOfflineExplanation);
}
private void updateProgressState(boolean shouldAutoDownload)

View File

@@ -15,7 +15,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.GridLayout;
import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
@@ -398,7 +397,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList();
for (String socketType : SOCKET_TYPES)
{
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType,0,0);
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, 0, 0);
MaterialButton btn = (MaterialButton) inflater.inflate(R.layout.button_socket_type, typeBtns, false);
@@ -406,16 +405,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi")
int resIconId =
getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable", requireContext().getPackageName());
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
requireContext().getPackageName());
if (resIconId != 0)
{
btn.setIcon(getResources().getDrawable(resIconId));
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
btn.setText(getResources().getString(resTypeId));
@@ -463,13 +462,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change
countView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override
public void afterTextChanged(Editable s) {
public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), countInputLayout);
}
});
@@ -484,13 +486,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change
powerView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override
public void afterTextChanged(Editable s) {
public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), powerInputLayout);
}
});
@@ -498,74 +503,82 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
return new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.editor_socket)
.setView(dialogView)
.setPositiveButton(R.string.save,
(dialog, which) -> {
String socketType = "";
for (MaterialButton b : buttonList)
{
if (b.isChecked())
{
socketType = b.getTag(R.id.socket_type).toString();
break;
}
}
.setPositiveButton(
R.string.save,
(dialog, which) -> {
String socketType = "";
for (MaterialButton b : buttonList)
{
if (b.isChecked())
{
socketType = b.getTag(R.id.socket_type).toString();
break;
}
}
int countValue = 0; // 0 means 'unknown count'
try
{
countValue = Integer.parseInt(countView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
int countValue = 0; // 0 means 'unknown count'
try
{
countValue = Integer.parseInt(countView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
if (countValue < 0)
{
countValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
if (countValue < 0)
{
countValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
double powerValue = 0; // 0 means 'unknown power'
try
{
powerValue = Double.parseDouble(powerView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
double powerValue = 0; // 0 means 'unknown power'
try
{
powerValue = Double.parseDouble(powerView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
if (powerValue < 0)
{
powerValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
if (powerValue < 0)
{
powerValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
ChargeSocketDescriptor socket =
new ChargeSocketDescriptor(socketType, countValue, powerValue);
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, countValue, powerValue);
updateChargeSockets(socketIndex, socket);
})
updateChargeSockets(socketIndex, socket);
})
.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
}
// Helper method for validation logic
private boolean validatePositiveField(String text, TextInputLayout layout) {
if (text.isEmpty()) {
private boolean validatePositiveField(String text, TextInputLayout layout)
{
if (text.isEmpty())
{
layout.setError(null); // No error if empty (assuming 0 is the default)
return true;
}
try {
try
{
double value = Double.parseDouble(text);
if (value < 0) {
if (value < 0)
{
layout.setError(getString(R.string.error_value_must_be_positive));
return false;
} else {
layout.setError(null);
return true;
}
} catch (NumberFormatException e) {
else
{
layout.setError(null);
return true;
}
}
catch (NumberFormatException e)
{
layout.setError(getString(R.string.error_invalid_number));
return false;
}
@@ -585,7 +598,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
{
sockets[socketIndex] = socket;
}
else {
else
{
List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets));
list.add(socket);
sockets = list.toArray(new ChargeSocketDescriptor[0]);
@@ -603,7 +617,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor);
socketsGrid.removeAllViews();
for (int i = 0; i < sockets.length; i++) {
for (int i = 0; i < sockets.length; i++)
{
final int currentIndex = i;
ChargeSocketDescriptor socket = sockets[i];
@@ -614,27 +629,30 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
MaterialTextView power = itemView.findViewById(R.id.socket_power);
MaterialTextView count = itemView.findViewById(R.id.socket_count);
// load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi")
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
requireContext().getPackageName());
if (resIconId != 0) {
requireContext().getPackageName());
if (resIconId != 0)
{
icon.setImageResource(resIconId);
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
if (resTypeId != 0) {
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
type.setText(resTypeId);
}
if (socket.power() != 0) {
if (socket.power() != 0)
{
DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power())));
}
else if (socket.ignorePower()) {
else if (socket.ignorePower())
{
power.setVisibility(INVISIBLE);
}
@@ -643,7 +661,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
count.setText(getString(R.string.count_label, socket.count()));
}
itemView.setOnClickListener(v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show());
itemView.setOnClickListener(
v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show());
socketsGrid.addView(itemView);
}
@@ -789,9 +808,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
View lineContactBlock =
initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white,
R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI);
View blueskyContactBlock =
initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, R.drawable.ic_bluesky,
R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky,
R.drawable.ic_bluesky, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
R.drawable.ic_operator, R.string.editor_operator, 0);
@@ -1023,14 +1041,15 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
private void placeDisused()
{
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.editor_mark_business_vacant_title)
.setMessage(R.string.editor_mark_business_vacant_description)
.setPositiveButton(R.string.editor_submit, (dlg, which) -> {
Editor.nativeMarkPlaceAsDisused();
mParent.processEditedFeatures();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
.setTitle(R.string.editor_mark_business_vacant_title)
.setMessage(R.string.editor_mark_business_vacant_description)
.setPositiveButton(R.string.editor_submit,
(dlg, which) -> {
Editor.nativeMarkPlaceAsDisused();
mParent.processEditedFeatures();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
private void commitPlaceDoesntExists(@NonNull String text)

View File

@@ -13,7 +13,6 @@ import app.organicmaps.R;
import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.util.UiUtils;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textview.MaterialTextView;
@@ -69,8 +68,7 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
}
case TYPE_FOOTER ->
{
return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false),
mFragment);
return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false), mFragment);
}
default -> throw new IllegalArgumentException("Unsupported viewType: " + viewType);
}
@@ -134,26 +132,21 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
mSendNoteButton = itemView.findViewById(R.id.send_note_button);
mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked());
final ColorStateList bgButtonColor = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled
},
new int[]{
ContextCompat.getColor(
mSendNoteButton.getContext(), R.color.base_accent),
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)
});
new int[][] {
new int[] {android.R.attr.state_enabled}, // enabled
new int[] {-android.R.attr.state_enabled} // disabled
},
new int[] {ContextCompat.getColor(mSendNoteButton.getContext(), R.color.base_accent),
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)});
final ColorStateList textButtonColor = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled
},
new int[]{
ContextCompat.getColor(
mSendNoteButton.getContext(),
UiUtils.getStyledResourceId(mSendNoteButton.getContext(), android.R.attr.textColorPrimaryInverse)),
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)
});
new int[][] {
new int[] {android.R.attr.state_enabled}, // enabled
new int[] {-android.R.attr.state_enabled} // disabled
},
new int[] {ContextCompat.getColor(mSendNoteButton.getContext(),
UiUtils.getStyledResourceId(mSendNoteButton.getContext(),
android.R.attr.textColorPrimaryInverse)),
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)});
mSendNoteButton.setBackgroundTintList(bgButtonColor);
mSendNoteButton.setTextColor(textButtonColor);
mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() {

View File

@@ -2,19 +2,16 @@ package app.organicmaps.editor;
import android.content.res.Configuration;
import android.content.res.Resources;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.timepicker.MaterialTimePicker;
import com.google.android.material.timepicker.TimeFormat;
import app.organicmaps.R;
import app.organicmaps.sdk.editor.data.HoursMinutes;
import app.organicmaps.sdk.util.DateUtils;
import com.google.android.material.timepicker.MaterialTimePicker;
import com.google.android.material.timepicker.TimeFormat;
public class FromToTimePicker
{
@@ -32,18 +29,11 @@ public class FromToTimePicker
private boolean mIsFromTimePicked;
private int mInputMode;
public static void pickTime(@NonNull Fragment fragment,
@NonNull FromToTimePicker.OnPickListener listener,
@NonNull HoursMinutes fromTime,
@NonNull HoursMinutes toTime,
int id,
public static void pickTime(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
@NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id,
boolean startWithToTime)
{
FromToTimePicker timePicker = new FromToTimePicker(fragment,
listener,
fromTime,
toTime,
id);
FromToTimePicker timePicker = new FromToTimePicker(fragment, listener, fromTime, toTime, id);
if (startWithToTime)
timePicker.showToTimePicker();
@@ -51,11 +41,8 @@ public class FromToTimePicker
timePicker.showFromTimePicker();
}
private FromToTimePicker(@NonNull Fragment fragment,
@NonNull FromToTimePicker.OnPickListener listener,
@NonNull HoursMinutes fromTime,
@NonNull HoursMinutes toTime,
int id)
private FromToTimePicker(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
@NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id)
{
mActivity = fragment.requireActivity();
mFragmentManager = fragment.getChildFragmentManager();
@@ -100,15 +87,12 @@ public class FromToTimePicker
private MaterialTimePicker buildFromTimePicker()
{
MaterialTimePicker timePicker = buildTimePicker(mFromTime,
mResources.getString(R.string.editor_time_from),
mResources.getString(R.string.next_button),
null);
MaterialTimePicker timePicker = buildTimePicker(mFromTime, mResources.getString(R.string.editor_time_from),
mResources.getString(R.string.next_button), null);
timePicker.addOnNegativeButtonClickListener(view -> finishTimePicking(false));
timePicker.addOnPositiveButtonClickListener(view ->
{
timePicker.addOnPositiveButtonClickListener(view -> {
mIsFromTimePicked = true;
saveState(timePicker, true);
mFromTimePicker = null;
@@ -122,13 +106,10 @@ public class FromToTimePicker
private MaterialTimePicker buildToTimePicker()
{
MaterialTimePicker timePicker = buildTimePicker(mToTime,
mResources.getString(R.string.editor_time_to),
null,
MaterialTimePicker timePicker = buildTimePicker(mToTime, mResources.getString(R.string.editor_time_to), null,
mResources.getString(R.string.back));
timePicker.addOnNegativeButtonClickListener(view ->
{
timePicker.addOnNegativeButtonClickListener(view -> {
saveState(timePicker, false);
mToTimePicker = null;
if (mIsFromTimePicked)
@@ -137,8 +118,7 @@ public class FromToTimePicker
finishTimePicking(false);
});
timePicker.addOnPositiveButtonClickListener(view ->
{
timePicker.addOnPositiveButtonClickListener(view -> {
saveState(timePicker, false);
finishTimePicking(true);
});
@@ -149,18 +129,18 @@ public class FromToTimePicker
}
@NonNull
private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time,
@NonNull String title,
private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time, @NonNull String title,
@Nullable String positiveButtonTextOverride,
@Nullable String negativeButtonTextOverride)
{
MaterialTimePicker.Builder builder = new MaterialTimePicker.Builder()
.setTitleText(title)
.setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H)
.setInputMode(mInputMode)
.setTheme(R.style.MwmTheme_MaterialTimePicker)
.setHour((int) time.hours)
.setMinute((int) time.minutes);
MaterialTimePicker.Builder builder =
new MaterialTimePicker.Builder()
.setTitleText(title)
.setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H)
.setInputMode(mInputMode)
.setTheme(R.style.MwmTheme_MaterialTimePicker)
.setHour((int) time.hours)
.setMinute((int) time.minutes);
if (positiveButtonTextOverride != null)
builder.setPositiveButtonText(positiveButtonTextOverride);

View File

@@ -7,7 +7,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import androidx.annotation.IdRes;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
@@ -122,20 +121,14 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
notifyItemChanged(getItemCount() - 1);
}
private void pickTime(int position,
@IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
private void pickTime(int position, @IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
boolean startWithToTime)
{
final Timetable data = mItems.get(position);
mPickingPosition = position;
FromToTimePicker.pickTime(mFragment,
this,
data.workingTimespan.start,
data.workingTimespan.end,
id,
startWithToTime);
FromToTimePicker.pickTime(mFragment, this, data.workingTimespan.start, data.workingTimespan.end, id,
startWithToTime);
}
@Override
@@ -384,26 +377,21 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
final String text = mFragment.getString(R.string.editor_time_add);
mAdd.setEnabled(enable);
final ColorStateList bgButtonColor = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled
},
new int[]{
ContextCompat.getColor(
mAdd.getContext(), R.color.base_accent),
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)
});
new int[][] {
new int[] {android.R.attr.state_enabled}, // enabled
new int[] {-android.R.attr.state_enabled} // disabled
},
new int[] {ContextCompat.getColor(mAdd.getContext(), R.color.base_accent),
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)});
final ColorStateList textButtonColor = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled
},
new int[]{
ContextCompat.getColor(
mAdd.getContext(),
UiUtils.getStyledResourceId(mAdd.getContext(), android.R.attr.textColorPrimaryInverse)),
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)
});
new int[][] {
new int[] {android.R.attr.state_enabled}, // enabled
new int[] {-android.R.attr.state_enabled} // disabled
},
new int[] {
ContextCompat.getColor(mAdd.getContext(), UiUtils.getStyledResourceId(
mAdd.getContext(), android.R.attr.textColorPrimaryInverse)),
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)});
mAdd.setBackgroundTintList(bgButtonColor);
mAdd.setTextColor(textButtonColor);
mAdd.setText(enable ? text + " (" + TimeFormatUtils.formatWeekdays(mComplementItem) + ")" : text);

View File

@@ -9,8 +9,8 @@ import androidx.annotation.Nullable;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmRecyclerFragment;
public class SimpleTimetableFragment extends BaseMwmRecyclerFragment<SimpleTimetableAdapter>
implements TimetableProvider
public class SimpleTimetableFragment
extends BaseMwmRecyclerFragment<SimpleTimetableAdapter> implements TimetableProvider
{
private SimpleTimetableAdapter mAdapter;
@Nullable

View File

@@ -35,25 +35,30 @@ public class LayerBottomSheetItem
@DrawableRes
int drawableResId = 0;
@StringRes
int buttonTextResource = switch (mode) {
case OUTDOORS -> {
drawableResId = R.drawable.ic_layers_outdoors;
yield R.string.button_layer_outdoor;
}
case SUBWAY -> {
drawableResId = R.drawable.ic_layers_subway;
yield R.string.subway;
}
case ISOLINES -> {
drawableResId = R.drawable.ic_layers_isoline;
yield R.string.button_layer_isolines;
}
case TRAFFIC -> {
drawableResId = R.drawable.ic_layers_traffic;
yield R.string.button_layer_traffic;
}
int buttonTextResource = switch (mode)
{
case OUTDOORS ->
{
drawableResId = R.drawable.ic_layers_outdoors;
yield R.string.button_layer_outdoor;
}
case SUBWAY ->
{
drawableResId = R.drawable.ic_layers_subway;
yield R.string.subway;
}
case ISOLINES ->
{
drawableResId = R.drawable.ic_layers_isoline;
yield R.string.button_layer_isolines;
}
case TRAFFIC ->
{
drawableResId = R.drawable.ic_layers_traffic;
yield R.string.button_layer_traffic;
}
};
return new LayerBottomSheetItem(drawableResId, buttonTextResource, mode, layerItemClickListener);
return new LayerBottomSheetItem(drawableResId, buttonTextResource, mode, layerItemClickListener);
}
@NonNull

View File

@@ -5,11 +5,9 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.adapter.OnItemClickListener;
import com.google.android.material.textview.MaterialTextView;
class LayerHolder extends RecyclerView.ViewHolder
{

View File

@@ -395,7 +395,7 @@ public class MapButtonsController extends Fragment
0;
// Allow offset tolerance for zoom buttons
};
showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey());
showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey());
}
}
}

View File

@@ -43,7 +43,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.DotDividerItemDecoration;
import app.organicmaps.widget.recycler.MultilineLayoutManager;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
@@ -123,9 +122,9 @@ final class RoutingBottomMenuController implements View.OnClickListener
@NonNull View timeElevationLine, @NonNull View transitFrame,
@NonNull MaterialTextView error, @NonNull MaterialButton start,
@NonNull ShapeableImageView altitudeChart, @NonNull MaterialTextView time,
@NonNull MaterialTextView altitudeDifference, @NonNull MaterialTextView timeVehicle,
@Nullable MaterialTextView arrival, @NonNull View actionFrame,
@Nullable RoutingBottomMenuListener listener)
@NonNull MaterialTextView altitudeDifference,
@NonNull MaterialTextView timeVehicle, @Nullable MaterialTextView arrival,
@NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener)
{
mContext = context;
mAltitudeChartFrame = altitudeChartFrame;

View File

@@ -12,9 +12,6 @@ import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
@@ -29,6 +26,7 @@ import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
import app.organicmaps.widget.RoutingToolbarButton;
import app.organicmaps.widget.ToolbarController;
import app.organicmaps.widget.WheelProgressView;
import com.google.android.material.textview.MaterialTextView;
public class RoutingPlanController extends ToolbarController
{
@@ -264,7 +262,7 @@ public class RoutingPlanController extends ToolbarController
default -> throw new IllegalArgumentException("unknown router: " + router);
};
RoutingToolbarButton button = mRouterTypes.findViewById(mRouterTypes.getCheckedRadioButtonId());
RoutingToolbarButton button = mRouterTypes.findViewById(mRouterTypes.getCheckedRadioButtonId());
button.progress();
updateProgressLabels();

View File

@@ -14,12 +14,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.sdk.search.DisplayedCategories;
import app.organicmaps.sdk.util.Language;
import com.google.android.material.textview.MaterialTextView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Locale;

View File

@@ -10,14 +10,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.sdk.search.SearchResult;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import com.google.android.material.textview.MaterialTextView;
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
{
@@ -152,7 +150,8 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{
final Resources resources = mSearchFragment.getResources();
if (result.description.openNow != SearchResult.OPEN_NOW_YES && result.description.openNow != SearchResult.OPEN_NOW_NO)
if (result.description.openNow != SearchResult.OPEN_NOW_YES
&& result.description.openNow != SearchResult.OPEN_NOW_NO)
{
// Hide if unknown opening hours state
UiUtils.hide(mOpen);
@@ -169,15 +168,18 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{
final String minsToChangeStr = resources.getQuantityString(
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
final String nextChangeFormatted = resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
final String nextChangeFormatted =
resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
UiUtils.setTextAndShow(mOpen, nextChangeFormatted);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
}
else
{
UiUtils.setTextAndShow(mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed));
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red));
UiUtils.setTextAndShow(
mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed));
mOpen.setTextColor(
ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red));
}
}

View File

@@ -273,7 +273,8 @@ public class SearchFragment extends BaseMwmFragment implements SearchListener, C
RecyclerView mResults = mResultsFrame.findViewById(R.id.recycler);
setRecyclerScrollListener(mResults);
mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder);
mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail);
mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query,
R.drawable.ic_search_fail);
mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
{

View File

@@ -5,15 +5,13 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchRecents;
import app.organicmaps.util.Graphics;
import app.organicmaps.widget.SearchToolbarController;
import com.google.android.material.textview.MaterialTextView;
class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.ViewHolder>
{

View File

@@ -8,14 +8,12 @@ import android.view.ViewGroup;
import android.widget.CompoundButton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.materialswitch.MaterialSwitch;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmToolbarFragment;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.settings.RoadType;
import com.google.android.material.materialswitch.MaterialSwitch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;

View File

@@ -90,8 +90,7 @@ public enum ThemeSwitcher
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_YES);
else
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
if (RoutingController.get().isVehicleNavigation())
style = MapStyle.VehicleDark;
@@ -104,8 +103,7 @@ public enum ThemeSwitcher
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_NO);
else
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
if (RoutingController.get().isVehicleNavigation())
style = MapStyle.VehicleClear;

View File

@@ -8,165 +8,165 @@ import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public abstract class BaseSignView extends View
{
private float mBorderWidthRatio = 0.1f;
protected void setBorderWidthRatio(float ratio) {
mBorderWidthRatio = ratio;
}
private float mBorderWidthRatio = 0.1f;
protected void setBorderWidthRatio(float ratio)
{
mBorderWidthRatio = ratio;
}
private float mBorderInsetRatio = 0f;
protected void setBorderInsetRatio(float ratio) {
mBorderInsetRatio = ratio;
}
private float mBorderInsetRatio = 0f;
protected void setBorderInsetRatio(float ratio)
{
mBorderInsetRatio = ratio;
}
// colors
protected int mBackgroundColor;
protected int mBorderColor;
protected int mAlertColor;
protected int mTextColor;
protected int mTextAlertColor;
// colors
protected int mBackgroundColor;
protected int mBorderColor;
protected int mAlertColor;
protected int mTextColor;
protected int mTextAlertColor;
// paints
protected final Paint mBackgroundPaint;
protected final Paint mBorderPaint;
protected final Paint mTextPaint;
// paints
protected final Paint mBackgroundPaint;
protected final Paint mBorderPaint;
protected final Paint mTextPaint;
// geometry
protected float mWidth;
protected float mHeight;
protected float mRadius;
protected float mBorderWidth;
protected float mBorderRadius;
// geometry
protected float mWidth;
protected float mHeight;
protected float mRadius;
protected float mBorderWidth;
protected float mBorderRadius;
public BaseSignView(Context ctx, @Nullable AttributeSet attrs)
public BaseSignView(Context ctx, @Nullable AttributeSet attrs)
{
super(ctx, attrs);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
}
protected void setColors(int backgroundColor, int borderColor, int alertColor, int textColor, int textAlertColor)
{
mBackgroundColor = backgroundColor;
mBorderColor = borderColor;
mAlertColor = alertColor;
mTextColor = textColor;
mTextAlertColor = textAlertColor;
mBackgroundPaint.setColor(mBackgroundColor);
mBorderPaint.setColor(mBorderColor);
mTextPaint.setColor(mTextColor);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
{
super.onSizeChanged(width, height, oldWidth, oldHeight);
final float paddingX = getPaddingLeft() + getPaddingRight();
final float paddingY = getPaddingTop() + getPaddingBottom();
mWidth = width - paddingX;
mHeight = height - paddingY;
mRadius = Math.min(mWidth, mHeight) / 2f;
mBorderWidth = mRadius * mBorderWidthRatio;
// subtract half the stroke PLUS the extra inset
final float gap = mRadius * mBorderInsetRatio;
mBorderRadius = mRadius - (mBorderWidth / 2f) - gap;
configureTextSize();
}
@Override
protected void onDraw(@NonNull Canvas canvas)
{
super.onDraw(canvas);
final String str = getValueString();
if (str == null)
return;
final float cx = mWidth / 2f;
final float cy = mHeight / 2f;
// background & border
boolean alert = isAlert();
mBackgroundPaint.setColor(alert ? mAlertColor : mBackgroundColor);
canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint);
if (!alert)
{
super(ctx, attrs);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
}
protected void setColors(int backgroundColor,
int borderColor,
int alertColor,
int textColor,
int textAlertColor)
// text
mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
drawValueString(canvas, cx, cy, str);
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent e)
{
final float cx = mWidth / 2f, cy = mHeight / 2f;
final float dx = e.getX() - cx, dy = e.getY() - cy;
if ((dx * dx) + (dy * dy) <= (mRadius * mRadius))
{
mBackgroundColor = backgroundColor;
mBorderColor = borderColor;
mAlertColor = alertColor;
mTextColor = textColor;
mTextAlertColor = textAlertColor;
mBackgroundPaint.setColor(mBackgroundColor);
mBorderPaint.setColor(mBorderColor);
mTextPaint.setColor(mTextColor);
performClick();
return true;
}
return false;
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
final float paddingX = getPaddingLeft() + getPaddingRight();
final float paddingY = getPaddingTop() + getPaddingBottom();
mWidth = width - paddingX;
mHeight = height - paddingY;
mRadius = Math.min(mWidth, mHeight) / 2f;
mBorderWidth = mRadius * mBorderWidthRatio;
// subtract half the stroke PLUS the extra inset
final float gap = mRadius * mBorderInsetRatio;
mBorderRadius = mRadius - (mBorderWidth / 2f) - gap;
configureTextSize();
}
@Override
public boolean performClick()
{
super.performClick();
return false;
}
@Override
protected void onDraw(@NonNull Canvas canvas)
private void drawValueString(Canvas c, float cx, float cy, String str)
{
Rect b = new Rect();
mTextPaint.getTextBounds(str, 0, str.length(), b);
final float y = cy - b.exactCenterY();
c.drawText(str, cx, y, mTextPaint);
}
void configureTextSize()
{
String text = getValueString();
if (text == null)
return;
final float textRadius = mBorderRadius - mBorderWidth;
final float maxTextSize = 2f * textRadius;
final float maxTextSize2 = maxTextSize * maxTextSize;
float lo = 0f, hi = maxTextSize, sz = maxTextSize;
Rect b = new Rect();
while (lo <= hi)
{
super.onDraw(canvas);
final String str = getValueString();
if (str == null) return;
final float cx = mWidth / 2f;
final float cy = mHeight / 2f;
// background & border
boolean alert = isAlert();
mBackgroundPaint.setColor(alert ? mAlertColor : mBackgroundColor);
canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint);
if (!alert)
{
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
}
// text
mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
drawValueString(canvas, cx, cy, str);
sz = (lo + hi) / 2f;
mTextPaint.setTextSize(sz);
mTextPaint.getTextBounds(text, 0, text.length(), b);
float area = b.width() * b.width() + b.height() * b.height();
if (area <= maxTextSize2)
lo = sz + 1f;
else
hi = sz - 1f;
}
mTextPaint.setTextSize(Math.max(1f, sz));
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent e)
{
final float cx = mWidth / 2f, cy = mHeight / 2f;
final float dx = e.getX() - cx, dy = e.getY() - cy;
if ((dx * dx) + (dy * dy) <= (mRadius * mRadius))
{
performClick();
return true;
}
return false;
}
/** child must return the string to draw, or null if nothing */
@Nullable
protected abstract String getValueString();
@Override
public boolean performClick()
{
super.performClick();
return false;
}
private void drawValueString(Canvas c, float cx, float cy, String str)
{
Rect b = new Rect();
mTextPaint.getTextBounds(str, 0, str.length(), b);
final float y = cy - b.exactCenterY();
c.drawText(str, cx, y, mTextPaint);
}
void configureTextSize()
{
String text = getValueString();
if (text == null) return;
final float textRadius = mBorderRadius - mBorderWidth;
final float maxTextSize = 2f * textRadius;
final float maxTextSize2 = maxTextSize * maxTextSize;
float lo = 0f, hi = maxTextSize, sz = maxTextSize;
Rect b = new Rect();
while (lo <= hi)
{
sz = (lo + hi) / 2f;
mTextPaint.setTextSize(sz);
mTextPaint.getTextBounds(text, 0, text.length(), b);
float area = b.width()*b.width() + b.height()*b.height();
if (area <= maxTextSize2)
lo = sz + 1f;
else
hi = sz - 1f;
}
mTextPaint.setTextSize(Math.max(1f, sz));
}
/** child must return the string to draw, or null if nothing */
@Nullable
protected abstract String getValueString();
/** child decides if this is in “alert” state */
protected abstract boolean isAlert();
/** child decides if this is in “alert” state */
protected abstract boolean isAlert();
}

View File

@@ -4,9 +4,7 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Pair;
import androidx.annotation.Nullable;
import app.organicmaps.R;
import app.organicmaps.sdk.util.StringUtils;
@@ -22,18 +20,18 @@ public class CurrentSpeedView extends BaseSignView
setBorderWidthRatio(0.1f);
setBorderInsetRatio(0.05f);
try (TypedArray a = ctx.getTheme()
.obtainStyledAttributes(attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */ , 0, 0))
try (TypedArray a = ctx.getTheme().obtainStyledAttributes(
attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */, 0, 0))
{
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR);
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR);
setColors(bg, bd, 0, tc, 0);
if (isInEditMode())
{
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
mSpeedStr = Integer.toString((int)mSpeedMps);
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
mSpeedStr = Integer.toString((int) mSpeedMps);
}
}
}
@@ -47,7 +45,7 @@ public class CurrentSpeedView extends BaseSignView
}
else
{
Pair<String,String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
Pair<String, String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
mSpeedStr = su.first;
}
requestLayout();
@@ -70,8 +68,8 @@ public class CurrentSpeedView extends BaseSignView
private interface DefaultValues
{
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFF000000;
int TEXT_COLOR = 0xFF000000;
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFF000000;
int TEXT_COLOR = 0xFF000000;
}
}

View File

@@ -12,12 +12,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.util.UiUtils;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
public class PlaceholderView extends LinearLayout
{

View File

@@ -5,16 +5,14 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import app.organicmaps.R;
public class SpeedLimitView extends BaseSignView
{
private int mSpeedLimit = -1;
private boolean mAlert = false;
private String mSpeedStr = "-1";
private int mSpeedLimit = -1;
private boolean mAlert = false;
private String mSpeedStr = "-1";
private final int unlimitedBorderColor;
private final int unlimitedStripeColor;
@@ -27,15 +25,22 @@ public class SpeedLimitView extends BaseSignView
try (TypedArray styleAttrs = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0))
{
final int bgColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
final int borderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR);
final int alertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR);
final int textColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR);
final int txtAlertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR);
final int bgColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
final int borderColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR);
final int alertColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR);
final int textColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR);
final int txtAlertColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR);
setColors(bgColor, borderColor, alertColor, textColor, txtAlertColor);
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor, DefaultValues.UNLIMITED_BORDER_COLOR);
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor, DefaultValues.UNLIMITED_STRIPE_COLOR);
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor,
DefaultValues.UNLIMITED_BORDER_COLOR);
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor,
DefaultValues.UNLIMITED_STRIPE_COLOR);
if (isInEditMode())
{
@@ -51,7 +56,7 @@ public class SpeedLimitView extends BaseSignView
if (mSpeedLimit != limit)
{
mSpeedLimit = limit;
mSpeedStr = Integer.toString(limit);
mSpeedStr = Integer.toString(limit);
requestLayout();
}
mAlert = alert;
@@ -75,7 +80,7 @@ public class SpeedLimitView extends BaseSignView
@Override
protected void onDraw(Canvas canvas)
{
final float cx = mWidth/2f, cy = mHeight/2f;
final float cx = mWidth / 2f, cy = mHeight / 2f;
if (mSpeedLimit == 0) // 0 means unlimited speed (maxspeed=none)
{
@@ -105,7 +110,7 @@ public class SpeedLimitView extends BaseSignView
stripe.setStrokeWidth(mBorderWidth * 0.4f);
final float radius = mRadius * 0.8f; // Shorten to 80% of full radius
final float diag = (float) (1/Math.sqrt(2)); // 45 degrees
final float diag = (float) (1 / Math.sqrt(2)); // 45 degrees
final float dx = -diag, dy = +diag;
final float px = -dy, py = +dx; // Perpendicular
final float step = radius * 0.15f; // Spacing
@@ -122,14 +127,13 @@ public class SpeedLimitView extends BaseSignView
}
}
private interface DefaultValues
{
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFFFF0000;
int ALERT_COLOR = 0xFFFF0000;
int TEXT_COLOR = 0xFF000000;
int TEXT_ALERT_COLOR = 0xFFFFFFFF;
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFFFF0000;
int ALERT_COLOR = 0xFFFF0000;
int TEXT_COLOR = 0xFF000000;
int TEXT_ALERT_COLOR = 0xFFFFFFFF;
int UNLIMITED_BORDER_COLOR = 0xFF000000;
int UNLIMITED_STRIPE_COLOR = 0xFF000000;
}

View File

@@ -72,7 +72,7 @@ public class MyPositionButton
case LocationState.FOLLOW_AND_ROTATE -> R.drawable.ic_follow_and_rotate;
default -> throw new IllegalArgumentException("Invalid button mode: " + mode);
};
image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme());
image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme());
mIcons.put(mode, image);
}

View File

@@ -1,9 +1,9 @@
package app.organicmaps.widget.placepage;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.util.StringUtils;
import com.github.mikephil.charting.charts.BarLineChartBase;
import androidx.annotation.Nullable;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;

View File

@@ -105,7 +105,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
public EditBookmarkFragment() {}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog);
}
@@ -184,10 +185,9 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
{
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
if (dialog != null)
{
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
// Focus name and show keyboard for "Unknown Place" bookmarks

View File

@@ -6,9 +6,6 @@ import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.ChartController;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
@@ -17,6 +14,7 @@ import app.organicmaps.sdk.bookmarks.data.Track;
import app.organicmaps.sdk.bookmarks.data.TrackStatistics;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import com.google.android.material.textview.MaterialTextView;
import java.util.Objects;
public class ElevationProfileViewRenderer implements PlacePageStateListener

View File

@@ -14,7 +14,8 @@ public class OpenStateTextFormatter
return String.format(Locale.ROOT, "%02d:%02d", hour, minute);
int h = hour % 12;
if (h == 0) h = 12;
if (h == 0)
h = 12;
String ampm = (hour < 12) ? "AM" : "PM";
return String.format(Locale.ROOT, "%d:%02d %s", h, minute, ampm);
}
@@ -29,21 +30,13 @@ public class OpenStateTextFormatter
return t.getDayOfWeek().getDisplayName(TextStyle.SHORT, locale);
}
static String buildAtLabel(
boolean opens,
boolean isToday,
String dayShort,
String time,
String opensAtLocalized,
String closesAtLocalized,
String opensDayAtLocalized,
String closesDayAtLocalized
)
static String buildAtLabel(boolean opens, boolean isToday, String dayShort, String time, String opensAtLocalized,
String closesAtLocalized, String opensDayAtLocalized, String closesDayAtLocalized)
{
if (isToday)
return opens ? String.format(Locale.ROOT, opensAtLocalized, time) // Opens at %s
: String.format(Locale.ROOT, closesAtLocalized, time); // Closes at %s
: String.format(Locale.ROOT, closesAtLocalized, time); // Closes at %s
return opens ? String.format(Locale.ROOT, opensDayAtLocalized, dayShort, time) // Opens %s at %s
: String.format(Locale.ROOT, closesDayAtLocalized, dayShort, time); // Closes %s at %s
: String.format(Locale.ROOT, closesDayAtLocalized, dayShort, time); // Closes %s at %s
}
}

View File

@@ -80,6 +80,6 @@ public class PlacePageButtonFactory
yield R.drawable.ic_more;
}
};
return new PlacePageButton(titleId, iconId, buttonType);
return new PlacePageButton(titleId, iconId, buttonType);
}
}

View File

@@ -105,12 +105,4 @@ public class PlacePageUtils
});
popup.show();
}
public static String buildPanoramaxURL(double lat, double lon)
{
final String panoramaxURL = "https://api.panoramax.xyz/?map=";
final String levelZoom = "16";
final String quality_score = "&pic_score=ABC";
return panoramaxURL + levelZoom + "/" + lat + "/" + lon + quality_score;
}
}

View File

@@ -4,7 +4,6 @@ import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static app.organicmaps.sdk.util.Utils.getLocalizedFeatureType;
import static app.organicmaps.sdk.util.Utils.getTagValueLocalized;
import static app.organicmaps.widget.placepage.PlacePageUtils.buildPanoramaxURL;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -32,7 +31,6 @@ import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
@@ -291,9 +289,6 @@ public class PlacePageView extends Fragment
openIn.setOnClickListener(this);
openIn.setOnLongClickListener(this);
openIn.setVisibility(VISIBLE);
LinearLayout openPhotoViewer = mFrame.findViewById(R.id.ll__place_open_phviewer);
openPhotoViewer.setOnClickListener(this);
openPhotoViewer.setVisibility(VISIBLE);
mTvLatlon = mFrame.findViewById(R.id.tv__place_latlon);
mWifi = mFrame.findViewById(R.id.ll__place_wifi);
mTvWiFi = mFrame.findViewById(R.id.tv__place_wifi);
@@ -696,6 +691,7 @@ public class PlacePageView extends Fragment
{
UiUtils.showIf(Editor.nativeShouldShowEditPlace(), mEditPlace);
UiUtils.showIf(Editor.nativeShouldShowAddPlace(), mAddPlace);
UiUtils.hide(mMapTooOld);
MaterialButton mTvEditPlace = mEditPlace.findViewById(R.id.mb__place_editor);
MaterialButton mTvAddPlace = mAddPlace.findViewById(R.id.mb__place_add);
@@ -708,34 +704,37 @@ public class PlacePageView extends Fragment
}
else
{
mTvEditPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvAddPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvEditPlace.setOnClickListener(
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
mTvAddPlace.setOnClickListener(
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
CountryItem map = CountryItem.fill(MapManager.nativeGetSelectedCountry());
String countryId = MapManager.nativeGetSelectedCountry();
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
|| map.status == CountryItem.STATUS_FAILED)
if (countryId != null)
{
mMapTooOld.setVisibility(VISIBLE);
MaterialButton mTvUpdateTooOldMap = mMapTooOld.findViewById(R.id.mb__update_too_old_map);
boolean canUpdateMap = map.status != CountryItem.STATUS_DONE;
CountryItem map = CountryItem.fill(countryId);
if (canUpdateMap)
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
|| map.status == CountryItem.STATUS_FAILED)
{
mTvUpdateTooOldMap.setOnClickListener((v) -> {
MapManagerHelper.warn3gAndDownload(requireActivity(), map.id, null);
mMapTooOld.setVisibility(GONE);
});
}
else
{
mTvUpdateTooOldMap.setVisibility(GONE);
UiUtils.show(mMapTooOld);
boolean canUpdateMap = map.status != CountryItem.STATUS_DONE;
MaterialButton mTvUpdateTooOldMap = mMapTooOld.findViewById(R.id.mb__update_too_old_map);
UiUtils.showIf(canUpdateMap, mTvUpdateTooOldMap);
MaterialTextView mapTooOldDescription = mMapTooOld.findViewById(R.id.tv__map_too_old_description);
mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
if (canUpdateMap)
{
mapTooOldDescription.setText(R.string.place_page_map_too_old_description);
mTvUpdateTooOldMap.setOnClickListener((v) -> {
MapManagerHelper.warn3gAndDownload(requireActivity(), map.id, null);
UiUtils.hide(mMapTooOld);
});
}
else
mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
}
}
}
@@ -751,9 +750,7 @@ public class PlacePageView extends Fragment
mTvAddPlace.setTextColor(editButtonColor);
mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
UiUtils.showIf(
UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace),
mEditTopSpace);
UiUtils.showIf(UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace), mEditTopSpace);
}
updateLinksView();
updateOpeningHoursView();
@@ -854,10 +851,9 @@ public class PlacePageView extends Fragment
}
// Get colours
final ForegroundColorSpan colorGreen =
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
final ForegroundColorSpan colorGreen = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
final ForegroundColorSpan colorYellow =
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow));
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow));
final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red));
// Get next state info
@@ -883,13 +879,12 @@ public class PlacePageView extends Fragment
if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2)
{
// NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone.
nextChangeLocal = ZonedDateTime.ofInstant(
Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault()
);
nextChangeLocal = ZonedDateTime.ofInstant(Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault());
hasFiniteNextChange = true;
}
}
catch (Throwable ignored) {}
catch (Throwable ignored)
{}
}
if (!hasFiniteNextChange) // No valid next change
@@ -904,7 +899,7 @@ public class PlacePageView extends Fragment
}
String localizedTimeString = OpenStateTextFormatter.formatHoursMinutes(
nextChangeLocal.getHour(), nextChangeLocal.getMinute(), DateUtils.is24HourFormat(context));
nextChangeLocal.getHour(), nextChangeLocal.getMinute(), DateUtils.is24HourFormat(context));
final boolean shortHorizonClosing = isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_CLOSE_MIN;
final boolean shortHorizonOpening = !isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_OPEN_MIN;
@@ -912,12 +907,12 @@ public class PlacePageView extends Fragment
if (shortHorizonClosing || shortHorizonOpening) // POI Opens/Closes in 60 mins • at 18:00
{
final String minsToChangeStr = getResources().getQuantityString(
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
final String nextChangeFormatted = getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
openStateString.append(nextChangeFormatted, colorYellow, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
.append("") // Add spacer
.append(getString(R.string.at, localizedTimeString));
.append("") // Add spacer
.append(getString(R.string.at, localizedTimeString));
}
else
{
@@ -927,18 +922,16 @@ public class PlacePageView extends Fragment
final String closesDayAtStr = getString(R.string.closes_day_at); // "Closes %1$s at %2$s"
final boolean isToday =
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
// Full weekday name per design feedback.
final String dayName =
nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
final String dayName = nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
if (isOpen) // > 60 minutes OR negative (safety). Show “Open now • Closes at 18:00”
{
openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
final String atLabel =
OpenStateTextFormatter.buildAtLabel(false, isToday, dayName, localizedTimeString,
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
final String atLabel = OpenStateTextFormatter.buildAtLabel(
false, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel);
@@ -947,9 +940,8 @@ public class PlacePageView extends Fragment
{
openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
final String atLabel =
OpenStateTextFormatter.buildAtLabel(true, isToday, dayName, localizedTimeString,
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
final String atLabel = OpenStateTextFormatter.buildAtLabel(
true, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel);
@@ -991,8 +983,6 @@ public class PlacePageView extends Fragment
mMapObject.getName());
Utils.openUri(requireContext(), Uri.parse(uri), R.string.uri_open_location_failed);
}
else if (id == R.id.ll__place_open_phviewer)
Utils.openUrl(requireContext(), buildPanoramaxURL(mMapObject.getLat(),mMapObject.getLon()));
else if (id == R.id.direction_frame)
showBigDirection();
else if (id == R.id.item_icon)
@@ -1040,10 +1030,6 @@ public class PlacePageView extends Fragment
mMapObject.getName());
PlacePageUtils.copyToClipboard(requireContext(), mFrame, uri);
}
else if (id == R.id.ll__place_open_phviewer)
{
PlacePageUtils.copyToClipboard(requireContext(),mFrame, buildPanoramaxURL(mMapObject.getLat(),mMapObject.getLon()));
}
else if (id == R.id.ll__place_operator)
items.add(mTvOperator.getText().toString());
else if (id == R.id.ll__place_network)

View File

@@ -3,9 +3,7 @@ package app.organicmaps.widget.placepage;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import java.util.List;
public class PlacePageViewModel extends ViewModel

View File

@@ -31,7 +31,8 @@ import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.textview.MaterialTextView;
public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener,
Observer<MapObject>, EditBookmarkFragment.EditBookmarkListener
Observer<MapObject>,
EditBookmarkFragment.EditBookmarkListener
{
private View mFrame;
private MaterialTextView mTvBookmarkNote;

View File

@@ -13,15 +13,13 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import java.text.DecimalFormat;
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
@@ -96,8 +94,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
type.setText(resTypeId);
@@ -108,7 +106,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power())));
}
else if (socket.ignorePower()) {
else if (socket.ignorePower())
{
power.setVisibility(INVISIBLE);
}

View File

@@ -191,8 +191,9 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
case FMD_PANORAMAX -> null; // Don't add raw ID to list, as it's useless for users.
default -> mMapObject.getMetadata(type);
};
// Add user names for social media if available
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) items.add(title);
// Add user names for social media if available
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/"))
items.add(title);
if (items.size() == 1)
PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0));

View File

@@ -26,7 +26,7 @@
app:tint="?colorSecondary"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/head_message"
style="?fontHeadline6"
style="@style/TextAppearance.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
@@ -36,7 +36,7 @@
android:text="@string/download_map_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/download_message"
style="?fontBody2"
style="@style/TextAppearance.Body2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base"

View File

@@ -28,7 +28,7 @@
android:layout_marginBottom="8dp"
android:text="@string/aa_connected_title"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
android:textAppearance="@style/TextAppearance.Headline4"
android:textStyle="bold" />
<com.google.android.material.textview.MaterialTextView
@@ -36,7 +36,7 @@
android:layout_height="wrap_content"
android:text="@string/car_used_on_the_car_screen"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />
android:textAppearance="@style/TextAppearance.Body1" />
</LinearLayout>
<com.google.android.material.button.MaterialButton

View File

@@ -20,7 +20,7 @@
android:layout_marginStart="32dp"
android:text="@string/aa_request_permission_activity_text"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
android:textAppearance="@style/TextAppearance.Headline4"
android:textStyle="bold" />
<com.google.android.material.button.MaterialButton

View File

@@ -22,7 +22,7 @@
android:layout_marginStart="@dimen/margin_base"
android:maxLines="3"
android:ellipsize="end"
android:textAppearance="?fontHeadline6"
android:textAppearance="@style/TextAppearance.Headline6"
tools:text="Title" />
<androidx.recyclerview.widget.RecyclerView

View File

@@ -12,7 +12,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base"
android:text="@string/download_country_ask"
android:textAppearance="?fontBody2"
android:textAppearance="@style/TextAppearance.Body2"
android:visibility="gone"
tools:visibility="visible"/>
<com.google.android.material.progressindicator.LinearProgressIndicator

View File

@@ -14,7 +14,6 @@
android:textAppearance="@style/MwmTextAppearance.Title" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et__input_layout"
style="?fontBody1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintEnabled="false">

View File

@@ -27,7 +27,7 @@
android:layout_marginTop="@dimen/margin_base">
<RadioButton
style="?fontSubtitle1"
style="@style/TextAppearance.Subtitle1"
android:id="@+id/sort_by_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
app:buttonTint="@null"/>
<RadioButton
style="?fontSubtitle1"
style="@style/TextAppearance.Subtitle1"
android:id="@+id/sort_by_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -47,7 +47,7 @@
app:buttonTint="@null"/>
<RadioButton
style="?fontSubtitle1"
style="@style/TextAppearance.Subtitle1"
android:id="@+id/sort_by_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -57,7 +57,7 @@
app:buttonTint="@null"/>
<RadioButton
style="?fontSubtitle1"
style="@style/TextAppearance.Subtitle1"
android:id="@+id/sort_by_distance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -67,7 +67,7 @@
app:buttonTint="@null"/>
<RadioButton
style="?fontSubtitle1"
style="@style/TextAppearance.Subtitle1"
android:id="@+id/sort_by_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -17,7 +17,6 @@
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/edit_bookmark_name_input"
style="?fontBody1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/name"
@@ -88,7 +87,6 @@
tools:src="@drawable/ic_bookmark_none" />
</RelativeLayout>
<com.google.android.material.textfield.TextInputLayout
style="?fontBody1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_half"

View File

@@ -17,7 +17,7 @@
android:layout_marginEnd="@dimen/margin_base"
android:paddingTop="@dimen/margin_half"
android:paddingBottom="@dimen/margin_base"
android:textAppearance="?fontHeadline6"
android:textAppearance="@style/TextAppearance.Headline6"
tools:text="Xindian Shitoushan Trail" />
<include
layout="@layout/item_divider"

View File

@@ -16,7 +16,7 @@
android:layout_marginStart="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:text="@string/layers_title"
android:textAppearance="?fontHeadline6"
android:textAppearance="@style/TextAppearance.Headline6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton

View File

@@ -30,7 +30,7 @@
android:ellipsize="middle"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="?fontBody1"
android:textAppearance="@style/TextAppearance.Body1"
tools:text="Bookmark name looooooooooooooooooongasdasdasd" />
<LinearLayout
android:id="@+id/bottom_line_container"

View File

@@ -25,7 +25,7 @@
android:layout_marginEnd="@dimen/bookmark_collection_item_end_margin"
android:ellipsize="middle"
android:singleLine="true"
android:textAppearance="?fontBody1"
android:textAppearance="@style/TextAppearance.Body1"
tools:text="Bookmark name looooooooooooooooooongasdasdasd" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/size"
@@ -37,7 +37,7 @@
android:ellipsize="end"
android:singleLine="true"
android:textColor="?android:textColorSecondary"
style="?fontBody2"
style="@style/TextAppearance.Body2"
tools:text="42000000" />
</LinearLayout>
</LinearLayout>

View File

@@ -12,7 +12,7 @@
android:paddingBottom="@dimen/margin_half_plus">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_message"
style="?fontHeadline6"
style="@style/TextAppearance.Headline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"

View File

@@ -2,7 +2,7 @@
<com.google.android.material.textview.MaterialTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
style="?fontHeadline6"
style="@style/TextAppearance.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?windowBackgroundForced"

View File

@@ -14,7 +14,7 @@
android:gravity="center"
android:maxWidth="500dp"
android:text="@string/editor_category_unsuitable_title"
android:textAppearance="@style/TextAppearance.MdcTypographyStyles.Headline6"
android:textAppearance="@style/TextAppearance.Headline6"
android:textStyle="bold" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/editor_category_unsuitable_text"

View File

@@ -10,7 +10,6 @@
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_layout"
style="?fontBody1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"

View File

@@ -147,12 +147,12 @@
<LinearLayout
android:id="@+id/allday"
android:layout_width="match_parent"
android:layout_height="@dimen/editor_height_allday"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?clickableBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/margin_half_plus">
android:padding="@dimen/margin_half">
<com.google.android.material.textview.MaterialTextView
android:layout_width="0dp"
@@ -164,7 +164,8 @@
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/sw__allday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_quarter"/>
</LinearLayout>

View File

@@ -29,7 +29,7 @@
android:layout_marginTop="@dimen/margin_base"
android:layout_marginEnd="@dimen/bookmark_collection_item_end_margin"
android:singleLine="true"
android:textAppearance="?fontBody1"
android:textAppearance="@style/TextAppearance.Body1"
tools:text="@string/tracks_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tv__bookmark_distance"
@@ -39,7 +39,7 @@
android:layout_marginBottom="@dimen/margin_half_plus"
android:singleLine="true"
android:textColor="?android:textColorSecondary"
android:textAppearance="?fontBody2"
android:textAppearance="@style/TextAppearance.Body2"
tools:text="@string/by_distance" />
</LinearLayout>
<com.google.android.material.imageview.ShapeableImageView

View File

@@ -71,8 +71,6 @@
<include layout="@layout/place_page_latlon"/>
<include layout="@layout/place_page_open_in"/>
<include layout="@layout/place_page_open_photoviewer" />
</LinearLayout>
<include
@@ -84,7 +82,7 @@
<com.google.android.material.textview.MaterialTextView
android:id="@+id/place_page_last_checked"
style="?fontCaption"
style="@style/TextAppearance.Caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/margin_half"

View File

@@ -1,24 +0,0 @@
<?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:id="@+id/ll__place_open_phviewer"
style="@style/PlacePageItemFrame"
tools:background="#20FF0000"
tools:visibility="visible">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv__place_open_phviewer"
style="@style/PlacePageMetadataIcon"
app:srcCompat="@drawable/ic_panoramax"
app:tint="?colorSecondary"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tv__place_open_phviewer"
android:textAlignment="viewStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/open_place_in_pnx"
android:textAppearance="@style/MwmTextAppearance.PlacePage.Accent"/>
</LinearLayout>

View File

@@ -65,7 +65,7 @@
<com.google.android.material.textview.MaterialTextView
android:id="@+id/oh_check_date"
style="?fontCaption"
style="@style/TextAppearance.Caption"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"

View File

@@ -88,19 +88,19 @@
<item name="android:textAppearanceSmall">@style/TextAppearance.Small</item>
<item name="android:textAppearanceMedium">@style/TextAppearance.Medium</item>
<item name="android:textAppearanceLarge">@style/TextAppearance.Large</item>
<item name="fontHeadline1">@style/TextAppearance.MdcTypographyStyles.Headline1</item>
<item name="fontHeadline2">@style/TextAppearance.MdcTypographyStyles.Headline2</item>
<item name="fontHeadline3">@style/TextAppearance.MdcTypographyStyles.Headline3</item>
<item name="fontHeadline4">@style/TextAppearance.MdcTypographyStyles.Headline4</item>
<item name="fontHeadline1">@style/TextAppearance.Headline1</item>
<item name="fontHeadline2">@style/TextAppearance.Headline2</item>
<item name="fontHeadline3">@style/TextAppearance.Headline3</item>
<item name="fontHeadline4">@style/TextAppearance.Headline4</item>
<item name="fontHeadline5">@style/TextAppearance.MaterialComponents.Headline5</item>
<item name="fontHeadline6">@style/TextAppearance.MdcTypographyStyles.Headline6</item>
<item name="fontSubtitle1">@style/TextAppearance.MdcTypographyStyles.Subtitle1</item>
<item name="fontSubtitle2">@style/TextAppearance.MdcTypographyStyles.Subtitle2</item>
<item name="fontBody1">@style/TextAppearance.MdcTypographyStyles.Body1</item>
<item name="fontBody2">@style/TextAppearance.MdcTypographyStyles.Body2</item>
<item name="fontButton">@style/TextAppearance.MdcTypographyStyles.Button</item>
<item name="fontCaption">@style/TextAppearance.MdcTypographyStyles.Caption</item>
<item name="fontOverline">@style/TextAppearance.MdcTypographyStyles.Overline</item>
<item name="fontHeadline6">@style/TextAppearance.Headline6</item>
<item name="fontSubtitle1">@style/TextAppearance.Subtitle1</item>
<item name="fontSubtitle2">@style/TextAppearance.Subtitle2</item>
<item name="fontBody1">@style/TextAppearance.Body1</item>
<item name="fontBody2">@style/TextAppearance.Body2</item>
<item name="fontButton">@style/TextAppearance.Button</item>
<item name="fontCaption">@style/TextAppearance.Caption</item>
<item name="fontOverline">@style/TextAppearance.Overline</item>
<item name="drivingOptionsViewBg">@color/bg_primary_dark</item>
<item name="elevationProfilePropertyBg">@drawable/bg_rounded_rect</item>
<item name="elevationProfilePropIconTint">@color/white_secondary</item>

View File

@@ -130,7 +130,6 @@
<!-- Editor -->
<dimen name="editor_height_days">72dp</dimen>
<dimen name="editor_height_closed">72dp</dimen>
<dimen name="editor_height_allday">56dp</dimen>
<dimen name="editor_height_field">64dp</dimen>
<dimen name="editor_margin_left">56dp</dimen>
<dimen name="editor_auth_btn_height">@dimen/primary_button_min_height</dimen>

View File

@@ -966,5 +966,4 @@
<string name="offline_explanation_title">Offline Maps</string>
<string name="offline_explanation_text">A map needs to be downloaded to view and navigate the area.\nDownload maps for areas you want to travel.</string>
<string name="list_description_empty">Edit the list to add a description</string>
<string name="open_place_in_pnx">Open in Panoramax</string>
</resources>

View File

@@ -6,11 +6,6 @@
<item name="android:textStyle">normal</item>
</style>
<style name="MwmTextAppearance.Display1">
<item name="android:textSize">@dimen/text_size_display_1</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
<style name="MwmTextAppearance.Title">
<item name="android:textSize">@dimen/text_size_title</item>
<item name="android:textColor">?android:textColorPrimary</item>
@@ -190,91 +185,91 @@
<item name="android:textColor">@color/white_secondary</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline1"
parent="TextAppearance.MaterialComponents.Headline1">
<style name="TextAppearance.Headline1"
parent="TextAppearance.Material3.DisplayLarge">
<item name="fontFamily">@string/robotoLight</item>
<item name="android:fontFamily">@string/robotoLight</item>
<item name="android:textSize">96sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline2"
parent="TextAppearance.MaterialComponents.Headline2">
<style name="TextAppearance.Headline2"
parent="TextAppearance.Material3.DisplayLarge">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">60sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline3"
parent="TextAppearance.MaterialComponents.Headline3">
<style name="TextAppearance.Headline3"
parent="TextAppearance.Material3.DisplayMedium">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">48sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline4"
parent="TextAppearance.MaterialComponents.Headline4">
<style name="TextAppearance.Headline4"
parent="TextAppearance.Material3.HeadlineLarge">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">34sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline5"
parent="TextAppearance.MaterialComponents.Headline5">
<style name="TextAppearance.Headline5"
parent="TextAppearance.Material3.HeadlineMedium">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">24sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Headline6"
parent="TextAppearance.MaterialComponents.Headline6">
<style name="TextAppearance.Headline6"
parent="TextAppearance.Material3.HeadlineSmall">
<item name="fontFamily">@string/robotoMedium</item>
<item name="android:fontFamily">@string/robotoMedium</item>
<item name="android:textSize">20sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Subtitle1"
parent="TextAppearance.MaterialComponents.Subtitle1">
<style name="TextAppearance.Subtitle1"
parent="TextAppearance.Material3.TitleMedium">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">16sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Subtitle2"
parent="TextAppearance.MaterialComponents.Subtitle2">
<style name="TextAppearance.Subtitle2"
parent="TextAppearance.Material3.TitleSmall">
<item name="fontFamily">@string/robotoMedium</item>
<item name="android:fontFamily">@string/robotoMedium</item>
<item name="android:textSize">14sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Body1"
parent="TextAppearance.MaterialComponents.Body1">
<style name="TextAppearance.Body1"
parent="TextAppearance.Material3.BodyLarge">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">16sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Body2"
parent="TextAppearance.MaterialComponents.Body2">
<style name="TextAppearance.Body2"
parent="TextAppearance.Material3.BodyMedium">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">14sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Button"
<style name="TextAppearance.Button"
parent="TextAppearance.MaterialComponents.Button">
<item name="fontFamily">@string/robotoMedium</item>
<item name="android:fontFamily">@string/robotoMedium</item>
<item name="android:textSize">14sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Caption"
parent="TextAppearance.MaterialComponents.Caption">
<style name="TextAppearance.Caption"
parent="TextAppearance.Material3.LabelMedium">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>
<item name="android:textSize">12sp</item>
</style>
<style name="TextAppearance.MdcTypographyStyles.Overline"
<style name="TextAppearance.Overline"
parent="TextAppearance.MaterialComponents.Overline">
<item name="fontFamily">@string/robotoRegular</item>
<item name="android:fontFamily">@string/robotoRegular</item>

View File

@@ -139,12 +139,13 @@
<item name="cornerSize">50%</item>
</style>
<style name="MwmWidget.ToolbarStyle" parent="ThemeOverlay.Material3.Dark.ActionBar">
<style name="MwmWidget.ToolbarStyle" parent="Widget.Material3.Toolbar">
<item name="android:background">?colorPrimary</item>
<item name="android:displayOptions">homeAsUp|showTitle</item>
<item name="contentInsetStart">0dp</item>
<item name="android:titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title</item>
<item name="titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title</item>
<item name="buttonGravity">center_vertical</item>
</style>
<style name="MwmWidget.ToolbarStyle.Light">

View File

@@ -93,19 +93,19 @@
<item name="android:textAppearanceSmallInverse">@style/TextAppearance.Small.Inverse</item>
<item name="android:textAppearanceMediumInverse">@style/TextAppearance.Medium.Inverse</item>
<item name="android:textAppearanceLargeInverse">@style/TextAppearance.Large.Inverse</item>
<item name="fontHeadline1">@style/TextAppearance.MdcTypographyStyles.Headline1</item>
<item name="fontHeadline2">@style/TextAppearance.MdcTypographyStyles.Headline2</item>
<item name="fontHeadline3">@style/TextAppearance.MdcTypographyStyles.Headline3</item>
<item name="fontHeadline4">@style/TextAppearance.MdcTypographyStyles.Headline4</item>
<item name="fontHeadline1">@style/TextAppearance.Headline1</item>
<item name="fontHeadline2">@style/TextAppearance.Headline2</item>
<item name="fontHeadline3">@style/TextAppearance.Headline3</item>
<item name="fontHeadline4">@style/TextAppearance.Headline4</item>
<item name="fontHeadline5">@style/TextAppearance.MaterialComponents.Headline5</item>
<item name="fontHeadline6">@style/TextAppearance.MdcTypographyStyles.Headline6</item>
<item name="fontSubtitle1">@style/TextAppearance.MdcTypographyStyles.Subtitle1</item>
<item name="fontSubtitle2">@style/TextAppearance.MdcTypographyStyles.Subtitle2</item>
<item name="fontBody1">@style/TextAppearance.MdcTypographyStyles.Body1</item>
<item name="fontBody2">@style/TextAppearance.MdcTypographyStyles.Body2</item>
<item name="fontButton">@style/TextAppearance.MdcTypographyStyles.Button</item>
<item name="fontCaption">@style/TextAppearance.MdcTypographyStyles.Caption</item>
<item name="fontOverline">@style/TextAppearance.MdcTypographyStyles.Overline</item>
<item name="fontHeadline6">@style/TextAppearance.Headline6</item>
<item name="fontSubtitle1">@style/TextAppearance.Subtitle1</item>
<item name="fontSubtitle2">@style/TextAppearance.Subtitle2</item>
<item name="fontBody1">@style/TextAppearance.Body1</item>
<item name="fontBody2">@style/TextAppearance.Body2</item>
<item name="fontButton">@style/TextAppearance.Button</item>
<item name="fontCaption">@style/TextAppearance.Caption</item>
<item name="fontOverline">@style/TextAppearance.Overline</item>
<item name="drivingOptionsViewBg">@color/bg_primary_dark</item>
<item name="elevationProfilePropertyBg">@drawable/bg_rounded_rect</item>
<item name="elevationProfilePropIconTint">@color/black_secondary</item>

View File

@@ -4,11 +4,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Locale;
import org.junit.Test;
public class OpenStateTextFormatterTest
{
@@ -36,10 +35,10 @@ public class OpenStateTextFormatterTest
@Test
public void buildAtLabel_today_open_close()
{
String open = OpenStateTextFormatter.buildAtLabel(true, true, "Sat", "09:00",
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, true, "Sat", "18:00",
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT);
String open = OpenStateTextFormatter.buildAtLabel(true, true, "Sat", "09:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, true, "Sat", "18:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
CLOSES_DAY_AT);
assertEquals("Opens at 09:00", open);
assertEquals("Closes at 18:00", close);
}
@@ -47,10 +46,10 @@ public class OpenStateTextFormatterTest
@Test
public void buildAtLabel_other_day()
{
String open = OpenStateTextFormatter.buildAtLabel(true, false, "Sat", "09:00",
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, false, "Tue", "18:00",
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT);
String open = OpenStateTextFormatter.buildAtLabel(true, false, "Sat", "09:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, false, "Tue", "18:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
CLOSES_DAY_AT);
assertEquals("Opens Sat at 09:00", open);
assertEquals("Closes Tue at 18:00", close);
}

View File

@@ -18,7 +18,6 @@
#include <functional>
#include <memory>
#include <unordered_map>
#include <vector>
namespace
@@ -53,7 +52,7 @@ struct TBatchedData
jobject g_countryChangedListener = nullptr;
DECLARE_THREAD_CHECKER(g_batchingThreadChecker);
std::unordered_map<jobject, std::vector<TBatchedData>> g_batchedCallbackData;
ankerl::unordered_dense::map<jobject, std::vector<TBatchedData>> g_batchedCallbackData;
bool g_isBatched;
storage::Storage & GetStorage()

View File

@@ -320,7 +320,7 @@ JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeCur
jclass ohStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState");
jclass ruleStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState$State");
static std::unordered_map<RuleState, char const *> const ruleState = {
static ankerl::unordered_dense::map<RuleState, char const *> const ruleState = {
{RuleState::Open, "Open"}, {RuleState::Closed, "Closed"}, {RuleState::Unknown, "Unknown"}};
jfieldID stateField =

View File

@@ -35,7 +35,8 @@ SOFTWARE.
#include <iterator>
#include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
DECLARE_EXCEPTION(JniException, RootException);
@@ -151,7 +152,7 @@ public:
}
private:
std::unordered_map<std::string, jfieldID> m_fieldIds;
ankerl::unordered_dense::map<std::string, jfieldID> m_fieldIds;
};
} // namespace

View File

@@ -4,28 +4,30 @@ package app.organicmaps.sdk.bookmarks.data;
* represents the details of the socket available on a particular charging station
*
*/
public record ChargeSocketDescriptor(String type, int count, double power) {
/**
* Some charge sockets have the same visuals as other sockets, even though they are different and are tagged
* differently in OSM. This method returns the 'visual' type that should be used for the socket.
*
* @return the 'equivalent' visual style that should be used for this socket
*/
public String visualType() {
if (type.equals("typee")) {
return "schuko";
}
return type;
}
/**
* For some sockets (eg, domestic sockets), the power is usually not provided, as it is 'implicit'
*
* @return true if this socket type does not require displaying the power
*/
public Boolean ignorePower() {
return type.equals("typee") || type.equals("schuko");
public record ChargeSocketDescriptor(String type, int count, double power)
{
/**
* Some charge sockets have the same visuals as other sockets, even though they are different and are tagged
* differently in OSM. This method returns the 'visual' type that should be used for the socket.
*
* @return the 'equivalent' visual style that should be used for this socket
*/
public String visualType()
{
if (type.equals("typee"))
{
return "schuko";
}
return type;
}
/**
* For some sockets (eg, domestic sockets), the power is usually not provided, as it is 'implicit'
*
* @return true if this socket type does not require displaying the power
*/
public Boolean ignorePower()
{
return type.equals("typee") || type.equals("schuko");
}
}

View File

@@ -3,7 +3,6 @@ package app.organicmaps.sdk.editor;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.editor.data.Timespan;
import app.organicmaps.sdk.editor.data.Timetable;

View File

@@ -2,16 +2,14 @@ package app.organicmaps.sdk.util;
import android.content.Context;
import android.content.res.Resources;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.R;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import app.organicmaps.sdk.R;
public final class DateUtils
{
private DateUtils() {}
@@ -44,7 +42,7 @@ public final class DateUtils
if (days == 1)
return resources.getString(R.string.yesterday).toLowerCase();
if (days < 7)
return resources.getString(R.string.days_ago, Integer.toString(days));
return resources.getString(R.string.days_ago, Integer.toString(days));
if (days < 30)
return resources.getString(days < 14 ? R.string.week_ago : R.string.weeks_ago, Integer.toString(days / 7));
if (days < 365)

View File

@@ -148,11 +148,11 @@
<ul class="license-list">
<li><a href="https://agg.sourceforge.net/antigrain.com/index.html">Anti-Grain Geometry</a><br>&copy; 2002&ndash;2005 Maxim Shemanarev; <a href="#agg-license" class="license">License</a></li>
<li><a href="https://www.boost.org/">Boost</a>; <a href="#boost-license" class="license">Boost License</a></li>
<li><a href="https://www.boost.org">Boost</a>; <a href="#boost-license" class="license">Boost License</a></li>
<li><a href="https://www.daemonology.net/bsdiff/">bsdiff</a>; <a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://www.daemonology.net/bsdiff">bsdiff</a>; <a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://chromium.googlesource.com/chromium/src/courgette/">Chromium's Courgette</a>;
<li><a href="https://chromium.googlesource.com/chromium/src/courgette">Chromium's Courgette</a>;
<a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://github.com/dpogue/CMake-MetalShaderSupport">CMake Metal support files</a><br>
@@ -170,22 +170,22 @@
<li><a href="https://www.freetype.org">FreeType</a><br>
&copy; 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li>
<li><a href="https://stephenberry.github.io/glaze/">glaze</a><br>
<li><a href="https://stephenberry.github.io/glaze">glaze</a><br>
&copy; 2019 - present, Stephen Berry; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://www.glfw.org/">GLFW</a><br>
<li><a href="https://www.glfw.org">GLFW</a><br>
&copy; 2002-2006 Marcus Geelnard;2006-2019 Camilla Löwy; <a href="#zlib-license" class="license">Zlib License</a></li>
<li><a href="https://www.g-truc.net/project-0016.html">GLM</a><br>
&copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://site.icu-project.org/">ICU</a><br>
<li><a href="https://site.icu-project.org">ICU</a><br>
&copy; 1995&ndash;2016 IBM Corporation and others; <a href="#icu-license" class="license">ICU License</a></li>
<li><a href="https://www.digip.org/jansson/">Jansson</a><br>
<li><a href="https://www.digip.org/jansson">Jansson</a><br>
&copy; 2009-2013 Petri Lehtinen; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://libkdtree.alioth.debian.org/">libkdtree++</a><br>
<li><a href="https://libkdtree.alioth.debian.org">libkdtree++</a><br>
&copy; 2004-2007 Martin F. Krafft, parts are &copy; 2004-2008 Paul Harris and &copy; 2007-2008 Sylvain Bougerel; <a href="#artistic-license" class="license">Artistic License</a></li>
<li><a href="https://github.com/mapsme/omim">MAPS.ME</a><br>
@@ -215,7 +215,7 @@
<li><a href="https://github.com/googlesamples/android-vulkan-tutorials">Vulkan Wrapper</a><br>
&copy; 2016 Google Inc.; <a href="#apache2-license" class="license">Apache License</a></li>
<li class="android"><a href="https://cocosw.com/BottomSheet/">BottomSheet</a><br>
<li class="android"><a href="https://cocosw.com/BottomSheet">BottomSheet</a><br>
&copy; 2011, 2015 Kai Liao; <a href="#apache2-license" class="license">Apache License</a></li>
<li><a href="https://github.com/google/open-location-code">Open Location Code</a><br>
@@ -226,6 +226,9 @@
<li><a href="https://github.com/skarupke/flat_hash_map">Skarupke Hash Tables</a><br>
&copy; Malte Skarupke 2017; <a href="#boost-license" class="license">Boost License</a></li>
<li><a href="https://github.com/martinus/unordered_dense"></a><br>
&copy; 2022 Martin Leitner-Ankerl; <a href="#mit-license" class="license">MIT License</a></li>
</ul>
<p lang="en">Beyond OpenStreetMap, we also use a few other open data sources to improve our map data:</p>

View File

@@ -18,6 +18,8 @@ Below are our specific (but not all!) exceptions to the Google's coding standard
- We ARE using C++ exceptions.
- We are using all features of C++17 and C++23 except `std::filesystem`, `std::to_chars`, `std::from_chars` and `std::format` which are not fully supported on all platforms.
- We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts).
- Do not use `std::unordered_map` for hashmaps. Use `ankerl::unordered_dense::map` (from `3party/ankerl/unordered_dense.h`). When dealing with integers and not iterating, use `ska::flat_hash_map`.
- Use `ankerl::unordered_dense::set` instead of `std::unordered_set`.
Naming and formatting

View File

@@ -1,7 +1,7 @@
#pragma once
#include "generator/collector_interface.hpp"
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator
{
@@ -18,7 +18,7 @@ public:
};
private:
std::unordered_map<uint64_t, AddressInfo> m_addresses;
ankerl::unordered_dense::map<uint64_t, AddressInfo> m_addresses;
public:
void Add(feature::FeatureBuilder const & fb);
@@ -44,7 +44,7 @@ class AddressesCollector : public CollectorInterface
uint64_t m_beg, m_end;
};
// OSM Way ID is a key here.
std::unordered_map<uint64_t, WayInfo> m_interpolWays;
ankerl::unordered_dense::map<uint64_t, WayInfo> m_interpolWays;
public:
explicit AddressesCollector(std::string const & filename);

View File

@@ -133,7 +133,7 @@ template <typename T>
std::vector<std::string> GetHonestAffiliations(T && t, IndexSharedPtr const & index)
{
std::vector<std::string> affiliations;
std::unordered_set<borders::CountryPolygons const *> countires;
ankerl::unordered_dense::set<borders::CountryPolygons const *> countires;
ForEachPoint(t, [&](auto const & point)
{
std::vector<CountriesFilesIndexAffiliation::Value> values;
@@ -196,7 +196,7 @@ CountriesFilesIndexAffiliation::CountriesFilesIndexAffiliation(std::string const
: CountriesFilesAffiliation(borderPath, haveBordersForWholeWorld)
{
static std::mutex cacheMutex;
static std::unordered_map<std::string, std::shared_ptr<Tree>> cache;
static ankerl::unordered_dense::map<std::string, std::shared_ptr<Tree>> cache;
auto const key = borderPath + std::to_string(haveBordersForWholeWorld);
std::lock_guard<std::mutex> lock(cacheMutex);
@@ -228,7 +228,7 @@ std::vector<std::string> CountriesFilesIndexAffiliation::GetAffiliations(m2::Poi
std::shared_ptr<CountriesFilesIndexAffiliation::Tree> CountriesFilesIndexAffiliation::BuildIndex(
std::vector<m2::RectD> const & net)
{
std::unordered_map<borders::CountryPolygons const *, std::vector<m2::RectD>> countriesRects;
ankerl::unordered_dense::map<borders::CountryPolygons const *, std::vector<m2::RectD>> countriesRects;
std::mutex countriesRectsMutex;
std::vector<Value> treeCells;
std::mutex treeCellsMutex;

View File

@@ -262,7 +262,7 @@ CountryPolygonsCollection const & GetOrCreateCountryPolygonsTree(std::string con
{
/// @todo Are there many different paths with polygons, that we have to store map?
static std::mutex mutex;
static std::unordered_map<std::string, CountryPolygonsCollection> countriesMap;
static ankerl::unordered_dense::map<std::string, CountryPolygonsCollection> countriesMap;
std::lock_guard<std::mutex> lock(mutex);
auto const it = countriesMap.find(baseDir);

View File

@@ -10,10 +10,10 @@
#include "geometry/tree4d.hpp"
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "3party/ankerl/unordered_dense.h"
#define BORDERS_DIR "borders/"
#define BORDERS_EXTENSION ".poly"
@@ -112,7 +112,7 @@ public:
template <typename ToDo>
void ForEachCountryInRect(m2::RectD const & rect, ToDo && toDo) const
{
std::unordered_set<CountryPolygons const *> uniq;
ankerl::unordered_dense::set<CountryPolygons const *> uniq;
m_regionsTree.ForEachInRect(rect, [&](CountryPolygons const & cp)
{
if (uniq.insert(&cp).second)
@@ -131,7 +131,7 @@ public:
private:
m4::Tree<std::reference_wrapper<CountryPolygons const>> m_regionsTree;
std::unordered_map<std::string, CountryPolygons> m_countryPolygonsMap;
ankerl::unordered_dense::map<std::string, CountryPolygons> m_countryPolygonsMap;
};
using PolygonsList = std::vector<Polygon>;

View File

@@ -15,10 +15,12 @@
#include <utility>
#include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator
{
using base::GeoObjectId;
using std::pair, std::string, std::unordered_map, std::vector;
using std::pair, std::string, ankerl::unordered_dense::map, std::vector;
DECLARE_EXCEPTION(ParsingError, RootException);
@@ -42,7 +44,7 @@ static void ParseFeatureToBrand(json_t * root, string const & field, GeoObjectId
}
}
void ParseTranslations(json_t * root, std::set<string> const & keys, unordered_map<uint32_t, string> & idToKey)
void ParseTranslations(json_t * root, std::set<string> const & keys, map<uint32_t, string> & idToKey)
{
string const empty;
auto getKey = [&](string & translation) -> string const &
@@ -81,8 +83,7 @@ void ParseTranslations(json_t * root, std::set<string> const & keys, unordered_m
}
}
bool LoadBrands(string const & brandsFilename, string const & translationsFilename,
unordered_map<GeoObjectId, string> & brands)
bool LoadBrands(string const & brandsFilename, string const & translationsFilename, map<GeoObjectId, string> & brands)
{
string jsonBuffer;
try
@@ -126,7 +127,7 @@ bool LoadBrands(string const & brandsFilename, string const & translationsFilena
return false;
}
unordered_map<uint32_t, string> idToKey;
map<uint32_t, string> idToKey;
try
{
base::Json root(jsonBuffer.c_str());

View File

@@ -3,7 +3,8 @@
#include "base/geo_object_id.hpp"
#include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator
{
@@ -52,5 +53,5 @@ namespace generator
// name is "Сабвей", then "Сабвэй".
bool LoadBrands(std::string const & brandsFilename, std::string const & translationsFilename,
std::unordered_map<base::GeoObjectId, std::string> & brands);
ankerl::unordered_dense::map<base::GeoObjectId, std::string> & brands);
} // namespace generator

View File

@@ -5,11 +5,12 @@
#include <cstddef>
#include <cstdint>
#include <map>
#include <optional>
#include <utility>
#include <vector>
#include "3party/skarupke/flat_hash_map.hpp"
namespace generator
{
namespace cells_merger
@@ -67,7 +68,7 @@ private:
m2::RectD Union(m2::PointI const & startXy);
void Remove(m2::PointI const & minXy, m2::PointI const & maxXy);
std::map<m2::PointI, CellWrapper> m_matrix;
ska::flat_hash_map<m2::PointI, CellWrapper> m_matrix;
int32_t m_maxX = 0;
int32_t m_maxY = 0;
};

View File

@@ -16,9 +16,10 @@
#include "base/logging.hpp"
#include <memory>
#include <unordered_map>
#include <vector>
#include "3party/ankerl/unordered_dense.h"
#include "defines.hpp"
namespace generator
@@ -60,7 +61,7 @@ bool BuildCitiesBoundaries(string const & dataPath, BoundariesTable & table, Map
bool BuildCitiesBoundaries(string const & dataPath, OsmIdToBoundariesTable & table)
{
std::unordered_map<uint32_t, base::GeoObjectId> mapping;
ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mapping;
if (!ParseFeatureIdToOsmIdMapping(dataPath + OSM2FEATURE_FILE_EXTENSION, mapping))
{
LOG(LERROR, ("Can't parse feature id to osm id mapping."));
@@ -71,7 +72,7 @@ bool BuildCitiesBoundaries(string const & dataPath, OsmIdToBoundariesTable & tab
bool BuildCitiesBoundariesForTesting(string const & dataPath, TestIdToBoundariesTable & table)
{
std::unordered_map<uint32_t, uint64_t> mapping;
ankerl::unordered_dense::map<uint32_t, uint64_t> mapping;
if (!ParseFeatureIdToTestIdMapping(dataPath, mapping))
{
LOG(LERROR, ("Can't parse feature id to test id mapping."));

View File

@@ -6,21 +6,18 @@
#include "indexer/data_header.hpp"
#include "indexer/feature_to_osm.hpp"
#include "search/categories_cache.hpp"
#include "search/cbv.hpp"
#include "search/localities_source.hpp"
#include "search/mwm_context.hpp"
#include "coding/file_writer.hpp"
#include "coding/files_container.hpp"
#include "base/cancellable.hpp"
#include "base/checked_cast.hpp"
#include "base/geo_object_id.hpp"
#include "base/logging.hpp"
#include <cstdint>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
#include "defines.hpp"
@@ -40,7 +37,7 @@ bool IsWorldMwm(std::string const & path)
}
void WriteCitiesIdsSectionToFile(std::string const & dataPath,
std::unordered_map<uint32_t, base::GeoObjectId> const & mapping)
ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> const & mapping)
{
indexer::FeatureIdToGeoObjectIdBimapMem map;
auto const localities = generator::GetLocalities(dataPath);
@@ -89,7 +86,7 @@ bool BuildCitiesIds(std::string const & dataPath, std::string const & osmToFeatu
classificator::Load();
std::unordered_map<uint32_t, base::GeoObjectId> mapping;
ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mapping;
if (!ParseFeatureIdToOsmIdMapping(osmToFeaturePath, mapping))
{
LOG(LERROR, ("Can't parse feature id to osm id mapping."));
@@ -104,11 +101,11 @@ bool BuildCitiesIdsForTesting(std::string const & dataPath)
{
CHECK(IsWorldMwm(dataPath), ());
std::unordered_map<uint32_t, uint64_t> mapping;
ankerl::unordered_dense::map<uint32_t, uint64_t> mapping;
if (!ParseFeatureIdToTestIdMapping(dataPath, mapping))
return false;
std::unordered_map<uint32_t, base::GeoObjectId> mappingToGeoObjects;
ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mappingToGeoObjects;
for (auto const & entry : mapping)
{
// todo(@m) Make test ids a new source in base::GeoObjectId?

View File

@@ -19,9 +19,10 @@
#include "base/stl_helpers.hpp"
#include <algorithm>
#include <unordered_map>
#include <utility>
#include "3party/ankerl/unordered_dense.h"
namespace
{
using IdRelationVec = std::vector<std::pair<uint64_t, RelationElement>>;

View File

@@ -6,9 +6,10 @@
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "3party/ankerl/unordered_dense.h"
template <typename T>
class ReaderSource;
@@ -82,6 +83,6 @@ private:
IDRInterfacePtr m_cache;
std::vector<uint64_t> m_roadOsmIDs;
std::unordered_map<uint64_t, CameraInfo> m_speedCameras;
ankerl::unordered_dense::map<uint64_t, CameraInfo> m_speedCameras;
};
} // namespace routing_builder

View File

@@ -4,8 +4,7 @@
#include "generator/mini_roundabout_info.hpp"
#include "generator/way_nodes_mapper.hpp"
#include <unordered_map>
#include <unordered_set>
#include "3party/ankerl/unordered_dense.h"
namespace generator
{
@@ -39,7 +38,7 @@ private:
IDRInterfacePtr m_cache;
WaysIDHolder m_roads;
std::unordered_map<uint64_t, MiniRoundaboutInfo> m_miniRoundabouts;
std::unordered_set<uint64_t> m_miniRoundaboutsExceptions;
ankerl::unordered_dense::map<uint64_t, MiniRoundaboutInfo> m_miniRoundabouts;
ankerl::unordered_dense::set<uint64_t> m_miniRoundaboutsExceptions;
};
} // namespace generator

View File

@@ -92,7 +92,7 @@ public:
private:
// Value is an index in m_data vector.
std::unordered_map<IDType, uint64_t> m_id2index;
ankerl::unordered_dense::map<IDType, uint64_t> m_id2index;
std::vector<Locality> m_data;
};
@@ -107,10 +107,10 @@ public:
void Save(std::string const & fileName);
private:
std::unordered_map<IDType, Locality> m_id2loc;
using IDsSetT = std::unordered_set<IDType>;
std::unordered_map<IDType, IDsSetT> m_node2rel;
std::unordered_map<std::string, IDsSetT> m_name2rel;
ankerl::unordered_dense::map<IDType, Locality> m_id2loc;
using IDsSetT = ankerl::unordered_dense::set<IDType>;
ankerl::unordered_dense::map<IDType, IDsSetT> m_node2rel;
ankerl::unordered_dense::map<std::string, IDsSetT> m_name2rel;
};
class RoutingCityBoundariesCollector : public CollectorInterface

View File

@@ -45,9 +45,9 @@ tree_node::Forest<HierarchyEntry> const & ComplexLoader::GetForest(storage::Coun
return it == std::cend(m_forests) ? kEmpty : it->second;
}
std::unordered_set<CompositeId> ComplexLoader::GetIdsSet() const
ankerl::unordered_dense::set<CompositeId> ComplexLoader::GetIdsSet() const
{
std::unordered_set<CompositeId> set;
ankerl::unordered_dense::set<CompositeId> set;
ForEach([&](auto const &, auto const & forest)
{
forest.ForEachTree([&](auto const & tree)
@@ -59,7 +59,7 @@ std::unordered_set<CompositeId> ComplexLoader::GetIdsSet() const
ComplexLoader const & GetOrCreateComplexLoader(std::string const & filename)
{
static std::mutex m;
static std::unordered_map<std::string, ComplexLoader> complexLoaders;
static ankerl::unordered_dense::map<std::string, ComplexLoader> complexLoaders;
std::lock_guard<std::mutex> lock(m);
auto const it = complexLoaders.find(filename);

View File

@@ -8,10 +8,10 @@
#include <functional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator
{
namespace complex
@@ -36,10 +36,10 @@ public:
fn(pair.first, pair.second);
}
std::unordered_set<CompositeId> GetIdsSet() const;
ankerl::unordered_dense::set<CompositeId> GetIdsSet() const;
private:
std::unordered_map<storage::CountryId, tree_node::Forest<HierarchyEntry>> m_forests;
ankerl::unordered_dense::map<storage::CountryId, tree_node::Forest<HierarchyEntry>> m_forests;
};
// Returns true if hierarchy tree is complex; otherwise returns false.

View File

@@ -8,7 +8,8 @@
#include <array>
#include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
class FeatureType;
@@ -22,8 +23,8 @@ public:
std::optional<std::string> GetWikidataId(uint32_t featureId) const;
private:
std::unordered_map<uint32_t, base::GeoObjectId> m_featureIdToOsmId;
std::unordered_map<base::GeoObjectId, std::string> m_osmIdToWikidataId;
ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> m_featureIdToOsmId;
ankerl::unordered_dense::map<base::GeoObjectId, std::string> m_osmIdToWikidataId;
};
class DescriptionsCollectionBuilderStat
@@ -88,7 +89,7 @@ public:
descriptions::DescriptionsCollection m_collection;
private:
std::unordered_map<std::string, descriptions::StringIndex> m_path2Index;
ankerl::unordered_dense::map<std::string, descriptions::StringIndex> m_path2Index;
WikidataHelper m_wikidataHelper;
std::string m_wikipediaDir;

View File

@@ -220,9 +220,7 @@ bool FeatureBuilder::PreSerialize()
{
StringUtf8Multilang nameWithRef;
m_params.name.ForEach([&nameWithRef, this](int8_t code, std::string_view name)
{
nameWithRef.AddString(code, std::string(name) + " (" + m_params.ref + ")");
});
{ nameWithRef.AddString(code, std::string(name) + " (" + m_params.ref + ")"); });
m_params.name = std::move(nameWithRef);
}
else if (ftypes::IsEmergencyAccessPointChecker::Instance()(types))

Some files were not shown because too many files have changed in this diff Show More