Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Formatted "text-field" property setter #13358

Merged
merged 1 commit into from
Dec 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

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;

/**
Expand Down Expand Up @@ -137,9 +138,12 @@ public long getNativePtr() {

@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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;

/**
Expand Down Expand Up @@ -2134,6 +2135,16 @@ public static PropertyValue<String> textField(String 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.
*
* @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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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) %>
*
Expand All @@ -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) %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,12 @@
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;
}

Expand All @@ -41,6 +32,14 @@ public FormattedSection[] getFormattedSections() {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import android.support.annotation.Nullable;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
* A component of the {@link Formatted}.
Expand Down Expand Up @@ -117,4 +119,11 @@ public int hashCode() {
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};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,9 @@ public void testConstFormatExpressionMultipleInputs() {

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());
});
}
Expand Down Expand Up @@ -493,6 +492,29 @@ public void testFormatExpressionPlainTextCoercion() {
});
}

@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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,14 @@ public void testTextFieldAsConstant() {
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")))));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}"));
Expand Down
2 changes: 1 addition & 1 deletion platform/android/scripts/generate-style-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down
60 changes: 57 additions & 3 deletions src/mbgl/style/expression/formatted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down