From 16289d3d2010a413b6c66571eec2ce8423cb3a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Mar 2019 18:37:54 +0100 Subject: wip --- .../mapboxsdk/style/expressions/Expression.java | 32 +++++++-- .../mapboxsdk/style/types/FormattedSection.java | 82 ++++++++++++++++++++-- .../mapboxsdk/testapp/style/ExpressionTest.java | 53 +++++++++++--- platform/android/src/style/formatted.cpp | 40 ++++++----- 4 files changed, 173 insertions(+), 34 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java index 25ff819470..c3451845dd 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java @@ -2843,7 +2843,8 @@ public class Expression { * CircleLayer circleLayer = new CircleLayer("layer-id", "source-id"); * circleLayer.setProperties( * circleColor(switchCase( - * eq(literal("it"), resolvedLocale(collator(true, true, Locale.ITALY))), literal(ColorUtils.colorToRgbaString(Color.GREEN)), + * eq(literal("it"), resolvedLocale(collator(true, true, Locale.ITALY))), literal(ColorUtils.colorToRgbaString + * (Color.GREEN)), * literal(ColorUtils.colorToRgbaString(Color.RED)))) * ); * } @@ -3626,7 +3627,8 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression step(@NonNull Expression input, @NonNull Expression defaultOutput, @NonNull Expression... stops) { + public static Expression step(@NonNull Expression input, @NonNull Expression defaultOutput, + @NonNull Expression... stops) { return new Expression("step", join(new Expression[] {input, defaultOutput}, stops)); } @@ -4411,7 +4413,7 @@ public class Expression { /** * If set, the text-font argument overrides the font specified by the root layout properties. *

- * "text-font" is required to a literal array. + * "text-font" is required to be a literal array. *

* The requested font stack has to be a part of the used style. * For more information see the documentation. @@ -4427,7 +4429,7 @@ public class Expression { /** * If set, the text-font argument overrides the font specified by the root layout properties. *

- * "text-font" is required to a literal array. + * "text-font" is required to be a literal array. *

* The requested font stack has to be a part of the used style. * For more information see the documentation. @@ -4439,6 +4441,28 @@ public class Expression { public static FormatOption formatTextFont(@NonNull String[] fontStack) { return new FormatOption("text-font", literal(fontStack)); } + + /** + * If set, the text-color argument overrides the color specified by the root paint properties. + * + * @param expression expression + * @return format option + */ + @NonNull + public static FormatOption formatTextColor(@NonNull Expression expression) { + return new FormatOption("text-color", expression); + } + + /** + * If set, the text-color argument overrides the color specified by the root paint properties. + * + * @param color value + * @return format option + */ + @NonNull + public static FormatOption formatTextColor(@ColorInt int color) { + return new FormatOption("text-color", color(color)); + } } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java index c96a104afd..df70a511c1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java @@ -13,9 +13,10 @@ import java.util.Map; */ @Keep public class FormattedSection { - private final String text; - private final Number fontScale; - private final String[] fontStack; + private String text; + private Number fontScale; + private String[] fontStack; + private String textColor; /** * Creates a formatted section. @@ -24,7 +25,9 @@ public class FormattedSection { * @param fontScale scale of the font, setting to null will fall back to style's default settings * @param fontStack main and fallback fonts that are a part of the style, * setting null will fall back to style's default settings + * @deprecated use setters instead */ + @Deprecated public FormattedSection(@NonNull String text, @Nullable Number fontScale, @Nullable String[] fontStack) { this.text = text; this.fontScale = fontScale; @@ -36,7 +39,27 @@ public class FormattedSection { * * @param text displayed string * @param fontScale scale of the font, setting to null will fall back to style's default settings + * @param fontStack main and fallback fonts that are a part of the style, + * setting null will fall back to style's default settings + * @deprecated use setters instead + */ + @Deprecated + public FormattedSection(@NonNull String text, @Nullable Number fontScale, @Nullable String[] fontStack, + @Nullable String textColor) { + this.text = text; + this.fontScale = fontScale; + this.fontStack = fontStack; + this.textColor = textColor; + } + + /** + * Creates a formatted section. + * + * @param text displayed string + * @param fontScale scale of the font, setting to null will fall back to style's default settings + * @deprecated use setters instead */ + @Deprecated public FormattedSection(@NonNull String text, @Nullable Number fontScale) { this(text, fontScale, null); } @@ -45,6 +68,7 @@ public class FormattedSection { * Creates a formatted section. * * @param text displayed string + * @deprecated use setters instead */ public FormattedSection(@NonNull String text) { this(text, null, null); @@ -56,7 +80,9 @@ public class FormattedSection { * @param text displayed string * @param fontStack main and fallback fonts that are a part of the style, * setting null will fall back to style's default settings + * @deprecated use setters instead */ + @Deprecated public FormattedSection(@NonNull String text, @Nullable String[] fontStack) { this(text, null, fontStack); } @@ -91,6 +117,49 @@ public class FormattedSection { return fontStack; } + /** + * Returns the text color. + * + * @return text color + */ + public String getTextColor() { + return textColor; + } + + /** + * Set font scale. + * + * @param fontScale fontScale + */ + public void setFontScale(@Nullable Number fontScale) { + // called from JNI + this.fontScale = fontScale; + } + + /** + * Set font stack. + * + * @param fontStack fontStack + */ + public void setFontStack(@Nullable String[] fontStack) { + // called from JNI + this.fontStack = fontStack; + } + + /** + * Set text color. + * + * @param textColor text color + */ + public void setTextColor(@Nullable String textColor) { + this.textColor = textColor; + } + + void setTextColor(@Nullable Object textColor) { + // called from JNI + setTextColor((String) textColor); + } + @Override public boolean equals(Object o) { if (this == o) { @@ -109,7 +178,10 @@ public class FormattedSection { return false; } // Probably incorrect - comparing Object[] arrays with Arrays.equals - return Arrays.equals(fontStack, that.fontStack); + if (!Arrays.equals(fontStack, that.fontStack)) { + return false; + } + return textColor != null ? textColor.equals(that.textColor) : that.textColor == null; } @Override @@ -117,6 +189,7 @@ public class FormattedSection { int result = text != null ? text.hashCode() : 0; result = 31 * result + (fontScale != null ? fontScale.hashCode() : 0); result = 31 * result + Arrays.hashCode(fontStack); + result = 31 * result + (textColor != null ? textColor.hashCode() : 0); return result; } @@ -124,6 +197,7 @@ public class FormattedSection { Map params = new HashMap<>(); params.put("font-scale", fontScale); params.put("text-font", fontStack); + params.put("text-color", textColor); return new Object[] {text, params}; } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java index cf7bedeaea..3144807ca6 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java @@ -17,8 +17,8 @@ import com.mapbox.mapboxsdk.style.types.Formatted; import com.mapbox.mapboxsdk.style.types.FormattedSection; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; -import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils; import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils; +import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils; import com.mapbox.mapboxsdk.utils.ColorUtils; import org.junit.Test; @@ -29,6 +29,7 @@ import java.io.IOException; import timber.log.Timber; import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatFontScale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextColor; import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextFont; import static com.mapbox.mapboxsdk.style.expressions.Expression.collator; import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; @@ -352,6 +353,35 @@ public class ExpressionTest extends EspressoTest { }); } + @Test + public void testConstFormatExpressionTextColorParam() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + literal("test"), + formatTextColor(literal("yellow")) + ) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView()); + + assertFalse( + mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test", null, null, "rgba(1, 1, 0, 1)") + ), layer.getTextField().getValue()); + }); + } + @Test public void testConstFormatExpressionAllParams() { validateTestSetup(); @@ -366,7 +396,8 @@ public class ExpressionTest extends EspressoTest { formatEntry( "test", formatFontScale(0.5), - formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) + formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}), + formatTextColor(Color.RED) ) ); layer.setProperties(textField(expression)); @@ -379,7 +410,8 @@ public class ExpressionTest extends EspressoTest { assertEquals(new Formatted( new FormattedSection("test", 0.5, - new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) + new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}, + "rgba(1, 0, 0, 1)") ), layer.getTextField().getValue()); }); } @@ -400,7 +432,7 @@ public class ExpressionTest extends EspressoTest { formatFontScale(1.5), formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) ), - formatEntry("\ntest2", formatFontScale(2)) + formatEntry("\ntest2", formatFontScale(2), formatTextColor(Color.BLUE)) ); layer.setProperties(textField(expression)); TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView()); @@ -412,7 +444,7 @@ public class ExpressionTest extends EspressoTest { assertEquals(new Formatted( new FormattedSection("test", 1.5, new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}), - new FormattedSection("\ntest2", 2.0) + new FormattedSection("\ntest2", 2.0, null, "rgba(0, 0, 1, 1)") ), layer.getTextField().getValue()); }); } @@ -425,6 +457,7 @@ public class ExpressionTest extends EspressoTest { Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); feature.addStringProperty("test_property", "test"); feature.addNumberProperty("test_property_number", 1.5); + feature.addStringProperty("test_property_color", "rgba(0, 1, 0, 1)"); mapboxMap.getStyle().addSource(new GeoJsonSource("source", feature)); SymbolLayer layer = new SymbolLayer("layer", "source"); mapboxMap.getStyle().addLayer(layer); @@ -433,7 +466,8 @@ public class ExpressionTest extends EspressoTest { formatEntry( get("test_property"), Expression.FormatOption.formatFontScale(number(get("test_property_number"))), - formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}) + formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + formatTextColor(get("test_property_color")) ) ); layer.setProperties(textField(expression)); @@ -454,6 +488,7 @@ public class ExpressionTest extends EspressoTest { Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); feature.addStringProperty("test_property", "test"); feature.addNumberProperty("test_property_number", 1.5); + feature.addStringProperty("test_property_color", "rgba(0, 1, 0, 1)"); mapboxMap.getStyle().addSource(new GeoJsonSource("source", feature)); SymbolLayer layer = new SymbolLayer("layer", "source"); mapboxMap.getStyle().addLayer(layer); @@ -462,7 +497,8 @@ public class ExpressionTest extends EspressoTest { formatEntry( get("test_property"), formatFontScale(1.25), - formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}) + formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + formatTextColor(get("test_property_color")) ), formatEntry("\ntest2", formatFontScale(2)) ); @@ -509,7 +545,8 @@ public class ExpressionTest extends EspressoTest { Formatted formatted = new Formatted( new FormattedSection("test", 1.5), - new FormattedSection("\ntest", 0.5, new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}) + new FormattedSection("\ntest", 0.5, new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + new FormattedSection("test", null, null, "rgba(1, 0, 0, 1)") ); layer.setProperties(textField(formatted)); TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView()); diff --git a/platform/android/src/style/formatted.cpp b/platform/android/src/style/formatted.cpp index 8659e6961e..8876d39c55 100644 --- a/platform/android/src/style/formatted.cpp +++ b/platform/android/src/style/formatted.cpp @@ -1,5 +1,7 @@ #include "formatted.hpp" #include "formatted_section.hpp" +#include "../conversion/conversion.hpp" +#include "../conversion/constant.hpp" namespace mbgl { namespace android { @@ -11,36 +13,38 @@ void Formatted::registerNative(jni::JNIEnv& env) { jni::Local> Formatted::New(jni::JNIEnv& env, const style::expression::Formatted& value) { static auto& formatted = jni::Class::Singleton(env); static auto formattedConstructor = formatted.GetConstructor>>(env); - static auto& formattedSection = jni::Class::Singleton(env); + static auto& formattedSectionClass = jni::Class::Singleton(env); auto sections = jni::Array>::New(env, value.sections.size()); for (std::size_t i = 0; i < value.sections.size(); i++) { auto section = value.sections.at(i); auto text = jni::Make(env, section.text); + static auto formattedSectionConstructor = formattedSectionClass.GetConstructor(env); + auto formattedSection = formattedSectionClass.New(env, formattedSectionConstructor, text); - if (section.fontStack && section.fontScale) { + if (section.fontScale) { double fontScale = section.fontScale.value(); + static auto method = formattedSectionClass.GetMethod(env, "setFontScale"); + formattedSection.Call(env, method, fontScale); + } + + if (section.fontStack) { auto fontStack = jni::Array::New(env, section.fontStack.value().size()); for (std::size_t j = 0; j < section.fontStack.value().size(); j++) { fontStack.Set(env, j, jni::Make(env, section.fontStack.value().at(j))); } - static auto formattedSectionConstructor = formattedSection.GetConstructor>(env); - sections.Set(env, i, formattedSection.New(env, formattedSectionConstructor, text, jni::Box(env, fontScale), fontStack)); - } else if (section.fontScale) { - double fontScale = section.fontScale.value(); - static auto formattedSectionConstructor = formattedSection.GetConstructor(env); - sections.Set(env, i, formattedSection.New(env, formattedSectionConstructor, text, jni::Box(env, fontScale))); - } else if (section.fontStack) { - auto fontStack = jni::Array::New(env, section.fontStack.value().size()); - for (std::size_t j = 0; j < section.fontStack.value().size(); j++) { - fontStack.Set(env, j, jni::Make(env, section.fontStack.value().at(j))); - } - static auto formattedSectionConstructor = formattedSection.GetConstructor>(env); - sections.Set(env, i, formattedSection.New(env, formattedSectionConstructor, text, fontStack)); - } else { - static auto formattedSectionConstructor = formattedSection.GetConstructor(env); - sections.Set(env, i, formattedSection.New(env, formattedSectionConstructor, text)); + static auto method = formattedSectionClass.GetMethod)>(env, "setFontStack"); + formattedSection.Call(env, method, fontStack); } + + if (section.textColor) { + using namespace mbgl::android::conversion; + auto textColor = std::move(*convert>>(env, *section.textColor)); + static auto method = formattedSectionClass.GetMethod)>(env, "setTextColor"); + formattedSection.Call(env, method, textColor); + } + + sections.Set(env, i, formattedSection); } return formatted.New(env, formattedConstructor, sections); -- cgit v1.2.1