| Developing with the SDK > Using CSS Syntax in the Style Sheet > Applying CSS To Java Objects > Expressions |
Expressions |
INDEX
PREVIOUS
NEXT
|
The value in a CSS declaration is usually a literal. However, it is possible to write an expression in place of a literal.
If the value begins with @|, then the remainder of the value is processed as an expression.
The syntax of the expressions, after the @| prefix, is close to the Java syntax. The expression type can be arithmetic (type int, long, float, or double), Boolean, or String. Examples:
@|3+2*5 -> 13 @|true&&(true||!true) -> true @|start+end -> "startend"
An expression can refer to model attributes. The syntax is the usual one:
@|@speed/100+@drift -> 1/100 of the value of speed plus the value of drift , where speed and drift are attributes of the current object.
'@|"name is: " + @name'-> "name is: Bob", if the value of current object attribute name is "Bob." Note the use of quotes to keep the space characters. You could use the backslash (\) character instead, directly preceding the space characters to retain them. The backslah works to quote any character that directly follows it. Use of the backslash character makes sure that the character thus quoted is not interpreted by the expression parser.
The standard functions abs(), acos(), asin(), atan(), ceil(), cos(), exp(), floor(), log(), pi, rint(), round(), sin(), sqrt(), and tan() are accepted, as in, for example:
@|3+sin(pi/2) -> 4
There are some default functions in the ilog.views.sdm.renderer package: concat, int, long, float, double. The first one concatenates its parameters as String; the others evaluate basic numerical expressions (only the four operators +, -, *, / are allowed).
If the CSS engine encounters an error while it is resolving an expression, it silently ignores the declaration.
Users of CSS for Java can register their own functions, which can be part of an expression. A custom function must implement ilog.views.sdm.renderer.IlvSDMCSSFunction. This is an abstract class, but technically you should consider it just like an interface.
The signature of the main method is as follows:
public Object call(Object[] args, Class type, IlvSDMEngine engine,
Object node, Object target, Object closure);
args array.
type is the expected type of the function, when known. A null value is possible. Implementation should take care to return an object of this type; otherwise the conversion will only be performed if it can be (that is, if it is a simple conversion between primitive types or to String).
engine, node, and target are determined at invocation time as follows: engine is the current SDM engine, node is the current model object being customized, and target is the graphic object being customized. Not all functions need these parameters (see, for example, Code Sample 3.8).
closure allows the caller to retrieve the context on exit from the method.
If an error occurs during the call, the exception will be reported and the current property setting will be canceled.
Code Sample 3.7 gives an example of a function that computes the average value of its parameters.
Code Sample 3.8 shows an example of how to call a custom function, where the custom function is the Average class, which has the return value avrg. Note that this function does not require information from the engine.
node { width : @|avrg(@param1,@param2); } |
Code Sample 3.9 gives an example of a CSS function for SDM, which returns the graphic object (IlvGraphic) associated with the object whose ID is specified as argument.
Code Sample 3.10 shows an example of calling the getGraphicFromId function to return the graphic object associated with the current object. Note that this function does require information from the engine to retrieve the current object and its associated graphic object.
graphic : @|getGraphicFromId(@__ID) ; |
You must register custom functions before using them in a style sheet.
To register a function, you can simply call registerFunction in ilog.views.sdm.renderer.IlvStyleSheetRenderer (given an IlvSDMEngine, use IlvRendererUtil.getRenderer to find the active instance of IlvStyleSheetRenderer).
It is also possible to register a function in the style sheet, provided that the function is a JavaBean. You can set the property functionList to the list of custom functions, as class names separated by commas. This property is available in the IlvStyleSheetRenderer class. Code Sample 3.11 shows an example.
StyleSheet { functionList : "myPackage.RevertFunction,tests.RandomFunction"; } |
In very special situations, expressions must be inverted. For example, if there is a rule:
node {
x : @|log(@X) ;
}
and the representation of the node is moved horizontally, then the attribute named X in the model should be updated according to the expression and the new x value (here: X = 10^x).
If you can modify a representation object in the interface, the model attributes described in the style sheet may change. When the style sheet maps a property to an attribute directly, as in:
label : @name ;
the update is automatic. But if the mapping is realized through a function, as in:
label : @|concat(name is: ,@name) ;
then the function must be able to invert its operation (here, if the string evaluates to: "name is: Bob", then the inverse function should set the name attribute to "Bob").
| Note |
In this release, expressions cannot be inverted. However custom functions can be inverted, using the invert method.
|
Custom functions can be inverted using the invert method, which is defined as follows:
public Feedback[] invert(Object[] args, Object value, IlvSDMEngine engine, Object target)
The parameters args, engine, target have the same meaning as in call. The parameter value is the final value, and the method returns an array of couples (name, value). The name is the attribute name, and value is the value to set for this attribute. The result is an array when there are several attributes to update.
If a function cannot be inverted, then a null value should be returned.
Code Sample 3.12 shows how the Average function implements the invert method.
As you see in this example, there are two assumptions in the implementation of invert for Average:
Average function must be attributes only.
Most functions are difficult (sometimes even impossible) to invert. They usually need a compromise to support a minimum operation. But remember that invert needs to be implemented only when the interface allows you to modify the rendered object in such a way that the style sheet change needs to be reflected in the data model. Usually it is better to modify the model directly.
The default functions try at best to deliver a sensible result for invert. They accept model indirection (that is, @name) but no recursive calls to other functions.
| Copyright © 1987-2007 ILOG S.A. All rights reserved. Documentation homepage. Legal terms. | PREVIOUS NEXT |