[ios, macos] Minimal darwin wrappers of 'format' expression
Add support for `MGL_FUNCTION('format', <text>, <options dictionary>)`
This commit is contained in:
@@ -38,7 +38,8 @@ std::unique_ptr<Expression> boolean(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> toColor(std::unique_ptr<Expression>);
|
||||
std::unique_ptr<Expression> toString(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> toFormatted(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> get(const char* value);
|
||||
std::unique_ptr<Expression> get(std::unique_ptr<Expression>);
|
||||
|
||||
@@ -78,6 +79,9 @@ std::unique_ptr<Expression> interpolate(Interpolator interpolator,
|
||||
double input3, std::unique_ptr<Expression> output3);
|
||||
|
||||
std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inputs);
|
||||
|
||||
std::unique_ptr<Expression> format(const char* value);
|
||||
std::unique_ptr<Expression> format(std::unique_ptr<Expression>);
|
||||
|
||||
} // namespace dsl
|
||||
} // namespace expression
|
||||
|
||||
@@ -103,6 +103,11 @@ global.objCTestValue = function (property, layerType, arraysAsStructs, indent) {
|
||||
case 'number':
|
||||
return '@"1"';
|
||||
case 'formatted':
|
||||
// Special 'string' case to handle constant expression text-field that automatically
|
||||
// converts Formatted back to string.
|
||||
return layerType === 'string' ?
|
||||
`@"'${_.startCase(propertyName)}'"` :
|
||||
`@"MGL_FUNCTION('format', '${_.startCase(propertyName)}', %@)", @{}`;
|
||||
case 'string':
|
||||
return `@"'${_.startCase(propertyName)}'"`;
|
||||
case 'enum':
|
||||
@@ -559,6 +564,7 @@ global.valueTransformerArguments = function (property) {
|
||||
case 'number':
|
||||
return ['float', objCType];
|
||||
case 'formatted':
|
||||
return ['mbgl::style::expression::Formatted', objCType];
|
||||
case 'string':
|
||||
return ['std::string', objCType];
|
||||
case 'enum':
|
||||
@@ -593,6 +599,7 @@ global.mbglType = function(property) {
|
||||
case 'number':
|
||||
return 'float';
|
||||
case 'formatted':
|
||||
return 'mbgl::style::expression::Formatted';
|
||||
case 'string':
|
||||
return 'std::string';
|
||||
case 'enum': {
|
||||
|
||||
@@ -125,8 +125,13 @@ namespace mbgl {
|
||||
if (<%- objCName(property) %> && <%- objCName(property) %>.expressionType == NSConstantValueExpressionType) {
|
||||
std::string string = ((NSString *)<%- objCName(property) %>.constantValue).UTF8String;
|
||||
if (mbgl::style::conversion::hasTokens(string)) {
|
||||
<% if (property.type === 'formatted') { -%>
|
||||
self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<mbgl::style::expression::Formatted>(
|
||||
mbgl::style::conversion::convertTokenStringToFormatExpression(string)));
|
||||
<% } else { -%>
|
||||
self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<std::string>(
|
||||
mbgl::style::conversion::convertTokenStringToExpression(string)));
|
||||
<% } -%>
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,11 @@ private: // Private utilities for converting from mgl to mbgl values
|
||||
mbglValue = rawValue.UTF8String;
|
||||
}
|
||||
|
||||
// Formatted
|
||||
void getMBGLValue(NSString *rawValue, mbgl::style::expression::Formatted &mbglValue) {
|
||||
mbglValue = mbgl::style::expression::Formatted(rawValue.UTF8String);
|
||||
}
|
||||
|
||||
// Offsets
|
||||
void getMBGLValue(id rawValue, std::array<float, 2> &mbglValue) {
|
||||
if ([rawValue isKindOfClass:[NSValue class]]) {
|
||||
@@ -250,6 +255,11 @@ private: // Private utilities for converting from mbgl to mgl values
|
||||
return @(mbglStopValue.c_str());
|
||||
}
|
||||
|
||||
// Formatted
|
||||
static NSString *toMGLRawStyleValue(const mbgl::style::expression::Formatted &mbglStopValue) {
|
||||
return @(mbglStopValue.toString().c_str());
|
||||
}
|
||||
|
||||
// Offsets
|
||||
static NSValue *toMGLRawStyleValue(const std::array<float, 2> &mbglStopValue) {
|
||||
return [NSValue mgl_valueWithOffsetArray:mbglStopValue];
|
||||
|
||||
@@ -601,12 +601,12 @@ namespace mbgl {
|
||||
if (text && text.expressionType == NSConstantValueExpressionType) {
|
||||
std::string string = ((NSString *)text.constantValue).UTF8String;
|
||||
if (mbgl::style::conversion::hasTokens(string)) {
|
||||
self.rawLayer->setTextField(mbgl::style::PropertyValue<std::string>(
|
||||
mbgl::style::conversion::convertTokenStringToExpression(string)));
|
||||
self.rawLayer->setTextField(mbgl::style::PropertyValue<mbgl::style::expression::Formatted>(
|
||||
mbgl::style::conversion::convertTokenStringToFormatExpression(string)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(text, true);
|
||||
auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Formatted, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Formatted>>(text, true);
|
||||
self.rawLayer->setTextField(mbglValue);
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ namespace mbgl {
|
||||
if (propertyValue.isUndefined()) {
|
||||
propertyValue = self.rawLayer->getDefaultTextField();
|
||||
}
|
||||
return MGLStyleValueTransformer<std::string, NSString *>().toExpression(propertyValue);
|
||||
return MGLStyleValueTransformer<mbgl::style::expression::Formatted, NSString *>().toExpression(propertyValue);
|
||||
}
|
||||
|
||||
- (void)setTextField:(NSExpression *)textField {
|
||||
|
||||
@@ -1111,6 +1111,11 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
|
||||
// Avoid wrapping collator options object in literal expression.
|
||||
return @[@"collator", self.arguments[1].constantValue];
|
||||
}
|
||||
if (op.expressionType == NSConstantValueExpressionType
|
||||
&& [op.constantValue isEqualToString:@"format"]) {
|
||||
// Avoid wrapping format options object in literal expression.
|
||||
return @[@"format", self.arguments[1].mgl_jsonExpressionObject, self.arguments[2].constantValue];
|
||||
}
|
||||
return self.arguments.mgl_jsonExpressionObject;
|
||||
} else if (op == [MGLColor class] && [function isEqualToString:@"colorWithRed:green:blue:alpha:"]) {
|
||||
NSArray *arguments = self.arguments.mgl_jsonExpressionObject;
|
||||
|
||||
@@ -68,7 +68,11 @@
|
||||
@"<%- originalPropertyName(property) %> should be unset initially.");
|
||||
NSExpression *defaultExpression = layer.<%- objCName(property) %>;
|
||||
|
||||
<% if (property.type === 'formatted') { -%>
|
||||
NSExpression *constantExpression = [NSExpression expressionWithFormat:<%- objCTestValue(property, 'string', true, 3) %>];
|
||||
<% } else { -%>
|
||||
NSExpression *constantExpression = [NSExpression expressionWithFormat:<%- objCTestValue(property, type, true, 3) %>];
|
||||
<% } -%>
|
||||
layer.<%- objCName(property) %> = constantExpression;
|
||||
mbgl::style::PropertyValue<<%- mbglType(property) %>> propertyValue = { <%- mbglTestValue(property, type) %> };
|
||||
XCTAssertEqual(rawLayer->get<%- camelize(originalPropertyName(property)) %>(), propertyValue,
|
||||
@@ -83,7 +87,11 @@
|
||||
{
|
||||
using namespace mbgl::style::expression::dsl;
|
||||
propertyValue = mbgl::style::PropertyExpression<<%- mbglType(property) %>>(
|
||||
<% if (property.type === 'formatted') { -%>
|
||||
step(zoom(), format(<%- mbglExpressionTestValue(property, type) %>), 18.0, format(<%- mbglExpressionTestValue(property, type) %>))
|
||||
<% } else { -%>
|
||||
step(zoom(), literal(<%- mbglExpressionTestValue(property, type) %>), 18.0, literal(<%- mbglExpressionTestValue(property, type) %>))
|
||||
<% } -%>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -160,13 +168,23 @@
|
||||
{
|
||||
using namespace mbgl::style::expression::dsl;
|
||||
propertyValue = mbgl::style::PropertyExpression<<%- mbglType(property) %>>(
|
||||
<% if (property.type === 'formatted') { -%>
|
||||
format(toString(get(literal("token"))))
|
||||
<% } else { -%>
|
||||
toString(get(literal("token")))
|
||||
<% } -%>
|
||||
);
|
||||
}
|
||||
|
||||
XCTAssertEqual(rawLayer->get<%- camelize(originalPropertyName(property)) %>(), propertyValue,
|
||||
@"Setting <%- objCName(property) %> to a constant string with tokens should convert to an expression.");
|
||||
XCTAssertEqualObjects(layer.<%- objCName(property) %>, [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"],
|
||||
|
||||
<% if (property.type === 'formatted') { -%>
|
||||
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', CAST(token, 'NSString'), %@)", @{}];
|
||||
<% } else { -%>
|
||||
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"];
|
||||
<% } -%>
|
||||
XCTAssertEqualObjects(layer.<%- objCName(property) %>, tokenExpression,
|
||||
@"Setting <%- objCName(property) %> to a constant string with tokens should convert to an expression.");
|
||||
<% } -%>
|
||||
}
|
||||
|
||||
@@ -224,7 +224,9 @@
|
||||
|
||||
XCTAssertEqual(rawLayer->getIconImage(), propertyValue,
|
||||
@"Setting iconImageName to a constant string with tokens should convert to an expression.");
|
||||
XCTAssertEqualObjects(layer.iconImageName, [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"],
|
||||
|
||||
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"];
|
||||
XCTAssertEqualObjects(layer.iconImageName, tokenExpression,
|
||||
@"Setting iconImageName to a constant string with tokens should convert to an expression.");
|
||||
}
|
||||
|
||||
@@ -1096,20 +1098,20 @@
|
||||
|
||||
NSExpression *constantExpression = [NSExpression expressionWithFormat:@"'Text Field'"];
|
||||
layer.text = constantExpression;
|
||||
mbgl::style::PropertyValue<std::string> propertyValue = { "Text Field" };
|
||||
mbgl::style::PropertyValue<mbgl::style::expression::Formatted> propertyValue = { "Text Field" };
|
||||
XCTAssertEqual(rawLayer->getTextField(), propertyValue,
|
||||
@"Setting text to a constant value expression should update text-field.");
|
||||
XCTAssertEqualObjects(layer.text, constantExpression,
|
||||
@"text should round-trip constant value expressions.");
|
||||
|
||||
constantExpression = [NSExpression expressionWithFormat:@"'Text Field'"];
|
||||
constantExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', 'Text Field', %@)", @{}];
|
||||
NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}];
|
||||
layer.text = functionExpression;
|
||||
|
||||
{
|
||||
using namespace mbgl::style::expression::dsl;
|
||||
propertyValue = mbgl::style::PropertyExpression<std::string>(
|
||||
step(zoom(), literal("Text Field"), 18.0, literal("Text Field"))
|
||||
propertyValue = mbgl::style::PropertyExpression<mbgl::style::expression::Formatted>(
|
||||
step(zoom(), format("Text Field"), 18.0, format("Text Field"))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1130,14 +1132,16 @@
|
||||
|
||||
{
|
||||
using namespace mbgl::style::expression::dsl;
|
||||
propertyValue = mbgl::style::PropertyExpression<std::string>(
|
||||
toString(get(literal("token")))
|
||||
propertyValue = mbgl::style::PropertyExpression<mbgl::style::expression::Formatted>(
|
||||
format(toString(get(literal("token"))))
|
||||
);
|
||||
}
|
||||
|
||||
XCTAssertEqual(rawLayer->getTextField(), propertyValue,
|
||||
@"Setting text to a constant string with tokens should convert to an expression.");
|
||||
XCTAssertEqualObjects(layer.text, [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"],
|
||||
|
||||
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', CAST(token, 'NSString'), %@)", @{}];
|
||||
XCTAssertEqualObjects(layer.text, tokenExpression,
|
||||
@"Setting text to a constant string with tokens should convert to an expression.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user