[android] expose Formatted text-field setter
This commit is contained in:
committed by
Łukasz Paczos
parent
1e7c7e0489
commit
794b851f02
@@ -2,10 +2,11 @@ package com.mapbox.mapboxsdk.style.layers;
|
||||
|
||||
import android.support.annotation.Keep;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.types.Formatted;
|
||||
import com.mapbox.mapboxsdk.utils.ThreadUtils;
|
||||
|
||||
/**
|
||||
@@ -137,9 +138,12 @@ public abstract class Layer {
|
||||
|
||||
@Nullable
|
||||
private Object convertValue(@Nullable Object value) {
|
||||
if (value != null && value instanceof Expression) {
|
||||
if (value instanceof Expression) {
|
||||
return ((Expression) value).toArray();
|
||||
} else if (value instanceof Formatted) {
|
||||
return ((Formatted) value).toArray();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package com.mapbox.mapboxsdk.style.layers;
|
||||
import android.support.annotation.ColorInt;
|
||||
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.types.Formatted;
|
||||
import static com.mapbox.mapboxsdk.utils.ColorUtils.colorToRgbaString;
|
||||
|
||||
/**
|
||||
@@ -2134,6 +2135,16 @@ public class PropertyFactory {
|
||||
return new LayoutPropertyValue<>("text-field", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Value to use for a text label. If a plain `string` is provided, it will be treated as a `formatted` with default/inherited formatting options.
|
||||
*
|
||||
* @param value a Formatted value
|
||||
* @return property wrapper around Formatted
|
||||
*/
|
||||
public static PropertyValue<Formatted> textField(Formatted value) {
|
||||
return new LayoutPropertyValue<>("text-field", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Value to use for a text label. If a plain `string` is provided, it will be treated as a `formatted` with default/inherited formatting options.
|
||||
*
|
||||
|
||||
@@ -9,6 +9,7 @@ package com.mapbox.mapboxsdk.style.layers;
|
||||
import android.support.annotation.ColorInt;
|
||||
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.types.Formatted;
|
||||
import static com.mapbox.mapboxsdk.utils.ColorUtils.colorToRgbaString;
|
||||
|
||||
/**
|
||||
@@ -73,7 +74,8 @@ public class PropertyFactory {
|
||||
public static PropertyValue<String> <%- camelizeWithLeadingLowercase(property.name) %>(String value) {
|
||||
return new LayoutPropertyValue<>("<%- property.name %>", value);
|
||||
}
|
||||
<% } else {-%>
|
||||
|
||||
<% } -%>
|
||||
/**
|
||||
* <%- propertyFactoryMethodDoc(property) %>
|
||||
*
|
||||
@@ -83,7 +85,6 @@ public class PropertyFactory {
|
||||
public static PropertyValue<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) {
|
||||
return new LayoutPropertyValue<>("<%- property.name %>", value);
|
||||
}
|
||||
<% } -%>
|
||||
|
||||
/**
|
||||
* <%- propertyFactoryMethodDoc(property) %>
|
||||
|
||||
@@ -14,21 +14,12 @@ import java.util.Arrays;
|
||||
public class Formatted {
|
||||
private final FormattedSection[] formattedSections;
|
||||
|
||||
/**
|
||||
* Create a new formatted text.
|
||||
*
|
||||
* @param formattedSection section with formatting options
|
||||
*/
|
||||
public Formatted(FormattedSection formattedSection) {
|
||||
this(new FormattedSection[] {formattedSection});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new formatted text.
|
||||
*
|
||||
* @param formattedSections sections with formatting options
|
||||
*/
|
||||
public Formatted(FormattedSection[] formattedSections) {
|
||||
public Formatted(FormattedSection... formattedSections) {
|
||||
this.formattedSections = formattedSections;
|
||||
}
|
||||
|
||||
@@ -41,6 +32,14 @@ public class Formatted {
|
||||
return formattedSections;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
Object[] sections = new Object[formattedSections.length];
|
||||
for (int i = 0; i < formattedSections.length; i++) {
|
||||
sections[i] = formattedSections[i].toArray();
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A component of the {@link Formatted}.
|
||||
@@ -117,4 +119,11 @@ public class FormattedSection {
|
||||
result = 31 * result + Arrays.hashCode(fontStack);
|
||||
return result;
|
||||
}
|
||||
|
||||
Object[] toArray() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("font-scale", fontScale);
|
||||
params.put("text-font", fontStack);
|
||||
return new Object[] {text, params};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,10 +406,9 @@ public class ExpressionTest extends BaseActivityTest {
|
||||
|
||||
assertNull(layer.getTextField().getExpression());
|
||||
assertEquals(new Formatted(
|
||||
new FormattedSection[] {
|
||||
new FormattedSection("test", 1.5, new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}),
|
||||
new FormattedSection("\ntest2", 2.0),
|
||||
}
|
||||
new FormattedSection("test", 1.5,
|
||||
new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}),
|
||||
new FormattedSection("\ntest2", 2.0)
|
||||
), layer.getTextField().getValue());
|
||||
});
|
||||
}
|
||||
@@ -493,6 +492,29 @@ public class ExpressionTest extends BaseActivityTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTextFieldFormattedArgument() {
|
||||
validateTestSetup();
|
||||
invoke(mapboxMap, (uiController, mapboxMap) -> {
|
||||
LatLng latLng = new LatLng(51, 17);
|
||||
mapboxMap.addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())));
|
||||
SymbolLayer layer = new SymbolLayer("layer", "source");
|
||||
mapboxMap.addLayer(layer);
|
||||
|
||||
Formatted formatted = new Formatted(
|
||||
new FormattedSection("test", 1.5),
|
||||
new FormattedSection("\ntest", 0.5, new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"})
|
||||
);
|
||||
layer.setProperties(textField(formatted));
|
||||
waitForLayer(uiController, mapboxMap, latLng);
|
||||
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
|
||||
.isEmpty());
|
||||
|
||||
assertNull(layer.getTextField().getExpression());
|
||||
assertEquals(formatted, layer.getTextField().getValue());
|
||||
});
|
||||
}
|
||||
|
||||
private static final long WAIT_TIMEOUT = 5000;
|
||||
private static final long WAIT_DELAY = 150;
|
||||
|
||||
|
||||
@@ -521,11 +521,14 @@ public class SymbolLayerTest extends BaseActivityTest {
|
||||
assertNull(layer.getTextField().getValue());
|
||||
|
||||
// Set and Get
|
||||
Formatted propertyValue = new Formatted(new FormattedSection[]{new FormattedSection("default")});
|
||||
Formatted propertyValue = new Formatted(new FormattedSection("default"));
|
||||
|
||||
layer.setProperties(textField("default"));
|
||||
assertEquals(layer.getTextField().getValue(), propertyValue);
|
||||
|
||||
layer.setProperties(textField(propertyValue));
|
||||
assertEquals(layer.getTextField().getValue(), propertyValue);
|
||||
|
||||
layer.setProperties(textField("{token}"));
|
||||
assertEquals(layer.getTextField().getExpression(), format(Expression.formatEntry(Expression.toString(Expression.get("token")))));
|
||||
});
|
||||
|
||||
@@ -175,10 +175,10 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest {
|
||||
|
||||
layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>("default"));
|
||||
assertEquals(layer.get<%- camelize(property.name) %>().getValue(), propertyValue);
|
||||
<% } else {-%>
|
||||
|
||||
<% } -%>
|
||||
layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(propertyValue));
|
||||
assertEquals(layer.get<%- camelize(property.name) %>().getValue(), propertyValue);
|
||||
<% } -%>
|
||||
<% if (property.tokens) { -%>
|
||||
|
||||
layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>("{token}"));
|
||||
|
||||
@@ -187,7 +187,7 @@ global.defaultValueJava = function(property) {
|
||||
case 'number':
|
||||
return '0.3f';
|
||||
case 'formatted':
|
||||
return 'new Formatted(new FormattedSection[]{new FormattedSection("default")})'
|
||||
return 'new Formatted(new FormattedSection("default"))'
|
||||
case 'string':
|
||||
return '"' + property['default'] + '"';
|
||||
case 'enum':
|
||||
|
||||
@@ -44,13 +44,67 @@ namespace conversion {
|
||||
|
||||
using namespace mbgl::style::expression;
|
||||
|
||||
optional<Formatted> Converter<Formatted>::operator()(const Convertible& value, Error&) const {
|
||||
optional<Formatted> Converter<Formatted>::operator()(const Convertible& value, Error& error) const {
|
||||
using namespace mbgl::style::expression;
|
||||
|
||||
auto result = toString(value);
|
||||
if (result) {
|
||||
if (isArray(value)) {
|
||||
std::vector<FormattedSection> sections;
|
||||
for (std::size_t i = 0; i < arrayLength(value); ++i) {
|
||||
Convertible section = arrayMember(value, i);
|
||||
std::size_t sectionLength = arrayLength(section);
|
||||
if (sectionLength < 1) {
|
||||
error.message = "Section has to contain a text and optional parameters.";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<std::string> sectionText = toString(arrayMember(section, 0));
|
||||
if (!sectionText) {
|
||||
error.message = "Section has to contain a text.";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<double> fontScale;
|
||||
optional<FontStack> textFont;
|
||||
if (sectionLength > 1) {
|
||||
Convertible sectionParams = arrayMember(section, 1);
|
||||
if (!isObject(sectionParams)) {
|
||||
error.message = "Parameters have to be enclosed in an object.";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<Convertible> fontScaleMember = objectMember(sectionParams, "font-scale");
|
||||
if (fontScaleMember) {
|
||||
fontScale = toDouble(*fontScaleMember);
|
||||
}
|
||||
|
||||
optional<Convertible> textFontMember = objectMember(sectionParams, "text-font");
|
||||
if (textFontMember) {
|
||||
if (isArray(*textFontMember)) {
|
||||
std::vector<std::string> fontsVector;
|
||||
for (std::size_t j = 0; j < arrayLength(*textFontMember); ++j) {
|
||||
auto font = toString(arrayMember(*textFontMember, j));
|
||||
if (font) {
|
||||
fontsVector.push_back(*font);
|
||||
} else {
|
||||
error.message = "Font has to be a string.";
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
textFont = fontsVector;
|
||||
} else {
|
||||
error.message = "Font stack has to be an array.";
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sections.push_back(FormattedSection(*sectionText, fontScale, textFont));
|
||||
}
|
||||
return Formatted(sections);
|
||||
} else if (optional<std::string> result = toString(value)) {
|
||||
return Formatted(result->c_str());
|
||||
} else {
|
||||
error.message = "Formatted must be plain string or array type.";
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user