diff --git a/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java index 1d80f0980..695552669 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java @@ -4,41 +4,21 @@ import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; -import app.organicmaps.sdk.R; +import androidx.annotation.NonNull; +import app.organicmaps.BuildConfig; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.log.Logger; import com.google.common.base.Objects; +import dalvik.annotation.optimization.FastNative; public class Icon implements Parcelable { + private static final String TAG = Icon.class.getSimpleName(); + static final int BOOKMARK_ICON_TYPE_NONE = 0; - /// @note Important! Should be synced with kml/types.hpp/BookmarkIcon - /// @todo Can make better: take name-by-type from Core and make a concat: "R.drawable.ic_bookmark_" + name. - // First icon should be "none" <-> BOOKMARK_ICON_TYPE_NONE. @DrawableRes - private static final int[] TYPE_ICONS = { - R.drawable.ic_bookmark_none, R.drawable.ic_bookmark_hotel, R.drawable.ic_bookmark_animals, - R.drawable.ic_bookmark_buddhism, R.drawable.ic_bookmark_building, R.drawable.ic_bookmark_christianity, - R.drawable.ic_bookmark_entertainment, R.drawable.ic_bookmark_money, R.drawable.ic_bookmark_food, - R.drawable.ic_bookmark_gas, R.drawable.ic_bookmark_judaism, R.drawable.ic_bookmark_medicine, - R.drawable.ic_bookmark_mountain, R.drawable.ic_bookmark_museum, R.drawable.ic_bookmark_islam, - R.drawable.ic_bookmark_park, R.drawable.ic_bookmark_parking, R.drawable.ic_bookmark_shop, - R.drawable.ic_bookmark_sights, R.drawable.ic_bookmark_swim, R.drawable.ic_bookmark_water, - R.drawable.ic_bookmark_bar, R.drawable.ic_bookmark_transport, R.drawable.ic_bookmark_viewpoint, - R.drawable.ic_bookmark_sport, - R.drawable.ic_bookmark_none, // pub - R.drawable.ic_bookmark_none, // art - R.drawable.ic_bookmark_none, // bank - R.drawable.ic_bookmark_none, // cafe - R.drawable.ic_bookmark_none, // pharmacy - R.drawable.ic_bookmark_none, // stadium - R.drawable.ic_bookmark_none, // theatre - R.drawable.ic_bookmark_none, // information - R.drawable.ic_bookmark_none, // ChargingStation - R.drawable.ic_bookmark_none, // BicycleParking - R.drawable.ic_bookmark_none, // BicycleParkingCovered - R.drawable.ic_bookmark_none, // BicycleRental - R.drawable.ic_bookmark_none // FastFood - }; + private static final int[] TYPE_ICONS = GetTypeIcons(); @PredefinedColors.Color private final int mColor; @@ -119,4 +99,34 @@ public class Icon implements Parcelable return new Icon[size]; } }; + + @NonNull + @DrawableRes + private static int[] GetTypeIcons() + { + final String[] names = nativeGetBookmarkIconNames(); + int[] icons = new int[names.length]; + for (int i = 0; i < names.length; i++) + { + final String name = StringUtils.toSnakeCase(names[i]); + try + { + icons[i] = app.organicmaps.sdk.R.drawable.class.getField("ic_bookmark_" + name).getInt(null); + } + catch (NoSuchFieldException | IllegalAccessException e) + { + Logger.e(TAG, "Error getting icon for " + name); + // Force devs to add an icon for each bookmark type. + if (BuildConfig.DEBUG) + throw new RuntimeException("Error getting icon for " + name, e); + icons[i] = app.organicmaps.sdk.R.drawable.ic_bookmark_none; // Fallback icon + } + } + + return icons; + } + + @FastNative + @NonNull + private static native String[] nativeGetBookmarkIconNames(); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java index 1512c6898..ca0ce167b 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java @@ -11,6 +11,10 @@ import java.util.Locale; public class StringUtils { + public static String toSnakeCase(String input) + { + return input.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase(); + } public static String formatUsingUsLocale(String pattern, Object... args) { return String.format(Locale.US, pattern, args); diff --git a/android/sdk/src/main/cpp/CMakeLists.txt b/android/sdk/src/main/cpp/CMakeLists.txt index 4efbd8135..d579fca8a 100644 --- a/android/sdk/src/main/cpp/CMakeLists.txt +++ b/android/sdk/src/main/cpp/CMakeLists.txt @@ -43,6 +43,8 @@ set(SRC app/organicmaps/sdk/core/jni_java_methods.cpp app/organicmaps/sdk/core/logging.cpp app/organicmaps/sdk/bookmarks/data/BookmarkManager.cpp + app/organicmaps/sdk/bookmarks/data/Icon.cpp + app/organicmaps/sdk/bookmarks/data/Icon.hpp app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp app/organicmaps/sdk/DownloadResourcesLegacyActivity.cpp diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.cpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.cpp new file mode 100644 index 000000000..377f0e42b --- /dev/null +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.cpp @@ -0,0 +1,37 @@ +#include + +#include "app/organicmaps/sdk/core/jni_helper.hpp" + +#include "kml/types.hpp" + +extern "C" +{ +JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_bookmarks_data_Icon_nativeGetBookmarkIconNames(JNIEnv * env, + jclass) +{ + std::vector icons; + for (uint16_t i = 0; i < static_cast(kml::BookmarkIcon::Count); ++i) + icons.emplace_back(kml::DebugPrint(static_cast(i))); + return jni::ToJavaStringArray(env, icons); +} +} + +namespace +{ +JNINativeMethod const iconMethods[] = { + {"nativeGetBookmarkIconNames", "()[Ljava/lang/String;", + reinterpret_cast(&Java_app_organicmaps_sdk_bookmarks_data_Icon_nativeGetBookmarkIconNames)}, +}; +} + +namespace icon +{ +jint registerNativeMethods(JNIEnv * env) +{ + jclass clazz = env->FindClass("app/organicmaps/sdk/bookmarks/data/Icon"); + if (clazz == nullptr) + return JNI_ERR; + + return env->RegisterNatives(clazz, iconMethods, std::size(iconMethods)); +} +} // namespace icon diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.hpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.hpp new file mode 100644 index 000000000..3eefa4214 --- /dev/null +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/Icon.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace icon +{ +jint registerNativeMethods(JNIEnv * env); +} // namespace icon diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp index c038a1330..da8cc3e45 100644 --- a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp @@ -21,7 +21,7 @@ Java_app_organicmaps_sdk_bookmarks_data_PredefinedColors_nativeGetPredefinedColo namespace { -JNINativeMethod const methods[] = { +JNINativeMethod const predefinedColorsMethods[] = { {"nativeGetPredefinedColors", "()[I", reinterpret_cast(&Java_app_organicmaps_sdk_bookmarks_data_PredefinedColors_nativeGetPredefinedColors)}, }; @@ -35,6 +35,6 @@ jint registerNativeMethods(JNIEnv * env) if (clazz == nullptr) return JNI_ERR; - return env->RegisterNatives(clazz, methods, std::size(methods)); + return env->RegisterNatives(clazz, predefinedColorsMethods, std::size(predefinedColorsMethods)); } } // namespace predefined_colors diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp index 0296558b6..e7d798b5d 100644 --- a/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp @@ -5,4 +5,4 @@ namespace predefined_colors { jint registerNativeMethods(JNIEnv * env); -} +} // namespace predefined_colors diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.cpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.cpp index 05a8700bf..c315cc7cc 100644 --- a/android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.cpp +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.cpp @@ -7,6 +7,7 @@ #include "base/string_utils.hpp" #include "app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp" +#include "app/organicmaps/sdk/bookmarks/data/Icon.hpp" #include @@ -70,6 +71,8 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * jvm, void *) { if (predefined_colors::registerNativeMethods(env) != JNI_OK) return JNI_ERR; + if (icon::registerNativeMethods(env) != JNI_OK) + return JNI_ERR; } return JNI_VERSION_1_6; diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_art.xml b/android/sdk/src/main/res/drawable/ic_bookmark_art.xml new file mode 100644 index 000000000..d6eac556c --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_art.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_bank.xml b/android/sdk/src/main/res/drawable/ic_bookmark_bank.xml new file mode 100644 index 000000000..f730dabb8 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_bank.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking.xml b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking.xml new file mode 100644 index 000000000..1b2bc137e --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking_covered.xml b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking_covered.xml new file mode 100644 index 000000000..20a49e010 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_parking_covered.xml @@ -0,0 +1,15 @@ + + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_rental.xml b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_rental.xml new file mode 100644 index 000000000..e9cfcb4c3 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_bicycle_rental.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_cafe.xml b/android/sdk/src/main/res/drawable/ic_bookmark_cafe.xml new file mode 100644 index 000000000..e0e30df2c --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_cafe.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_charging_station.xml b/android/sdk/src/main/res/drawable/ic_bookmark_charging_station.xml new file mode 100644 index 000000000..b12b65325 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_charging_station.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_exchange.xml b/android/sdk/src/main/res/drawable/ic_bookmark_exchange.xml new file mode 100644 index 000000000..e47ba88a0 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_exchange.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_fast_food.xml b/android/sdk/src/main/res/drawable/ic_bookmark_fast_food.xml new file mode 100644 index 000000000..95045c3bc --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_fast_food.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_information.xml b/android/sdk/src/main/res/drawable/ic_bookmark_information.xml new file mode 100644 index 000000000..f64461c04 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_information.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_pharmacy.xml b/android/sdk/src/main/res/drawable/ic_bookmark_pharmacy.xml new file mode 100644 index 000000000..919a6d694 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_pharmacy.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_pub.xml b/android/sdk/src/main/res/drawable/ic_bookmark_pub.xml new file mode 100644 index 000000000..68cac9429 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_pub.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_stadium.xml b/android/sdk/src/main/res/drawable/ic_bookmark_stadium.xml new file mode 100644 index 000000000..c66d8cc94 --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_stadium.xml @@ -0,0 +1,10 @@ + + + diff --git a/android/sdk/src/main/res/drawable/ic_bookmark_theatre.xml b/android/sdk/src/main/res/drawable/ic_bookmark_theatre.xml new file mode 100644 index 000000000..304450ebd --- /dev/null +++ b/android/sdk/src/main/res/drawable/ic_bookmark_theatre.xml @@ -0,0 +1,10 @@ + + + diff --git a/libs/kml/types.hpp b/libs/kml/types.hpp index c4ad8deb1..dcda3fcda 100644 --- a/libs/kml/types.hpp +++ b/libs/kml/types.hpp @@ -145,7 +145,6 @@ inline std::string DebugPrint(CompilationType compilationType) UNREACHABLE(); } -/// @note Important! Should be synced with android/app/src/main/java/app/organicmaps/bookmarks/data/Icon.java enum class BookmarkIcon : uint16_t { None = 0,