|
|
|
Strata Live 3D CX / Meson User Manual
Overview
"Meson" is the name of a suite of connected technologies which allow interactive applications with both 2D and 3D elements to be
developed quickly, and with a very small execution footprint. Like "Java" the name denotes a language, an object model of predefined
classes, and a runtime execution environment.
The ordinary deployment method of a Meson application is in an applet on a web page. The following example shows a typical use case:
<html><body>
<applet code='com.kaon.meson.MesonApplet' archive='mesonApplet.jar,rasterGluon.jar,sceneGluon.jar' width=400 height=300>
<param name='meson' value='
Applet.Primary.fill="336699";
Applet.Primary.image="/images/productDemo/splash.jpg";
Meson.gluon("com.kaon.meson.raster.RasterGluon");
Data.Primary.url="/apps/productDemo/program.jar";
'>
</applet>
</body></html>
|
In this example, a short program is given right in the HTML file, using the meson applet parameter. This program uses the
trick of giving an attribute value over multiple lines, in order to improve readability. Note, however, that the HTML processor strips out
the line feeds before passing the parameter to the applet, so the applet receives this program as one very long line. Therefore, each
line ends with a ; to break the statements up for the parser. This program sets the background color of the applet (used
until an image appears), then sets the initial image in the applet using a URL relative to this page. Next it loads the Java code used
for 2D (raster) operations, and then creates a data source to fetch the application program. This program would display its own progress
meter, and load other Java code to extend the functionality into the 3D space.
Note that there is no way to express the ' (apostrophe) character in a HTML parameter value. Therefore, this character is not
required in the Meson language. If you need to include ' in a program on a web page, the unicode version \u0027 can be used.
Developing a Meson program using only a browser to debug can be difficult. For this reason, Meson includes a console application
called "blackboard" which executes program files, and has a command-line interface into which expressions can be typed. In this way, it
is similar to a LISP development environment, where debugging and programming are performed with the same tool. In the context of the
blackboard application, the above program would be this:
Meson.newApplet(["Primary",400,300])
Applet.Primary.fill="336699"
Applet.Primary.image="/images/productDemo/splash.jpg"
Meson.gluon("com.kaon.meson.raster.RasterGluon")
Data.Primary.url="/apps/productDemo/program.jar"
|
To run the blackboard application with a command line interface, open a command window, and cd to the folder where Live 3D is installed. Then type the following: jre/bin/java -mx96M -jar blackboard.jar optionally followed by the names of text
files containing Meson program statements. To run the blackboard program non-interactively, just drag a program text file onto the
Blackboard.exe launcher icon.
The blackboard application adds a few items to the Meson environment:
-
Meson.newApplet takes an array with up to 5 elements as its argument. First is the name of the applet, which can be prepended with a
* to request an applet window with no title bar or close button. Then width and height, followed optionally by left and top screen coordinates.
-
Meson.exit takes a single number argument, causing the blackboard application to terminate with that exit code.
- The attribute javaWindow is added to the Applet object, which can then be manipulated using Java reflection.
- The attribute windowClosed is added to the Applet object, with the default value {Meson.exit(0)}. This can be changed by the application, as needed.
Conceptual Framework
The heart of a Meson environment is the blackboard. This is a common place where all data is stored. Each piece of data on the
blackboard (each "attribute") has a name and a value. For example, Meson.clock ::= 5.3 is a way of expressing that the datum
called "Meson.clock" has the value "5.3". The power in the Meson language comes from the ability to put expressions into the blackboard,
which get their values by performing operations on other attributes in the blackboard. For example, Image.Blue.x ::= Image.Yellow.mouseX+50
says that the value of the attribute Image.Blue.x should always be 50 larger than the current value of the attribute
Image.Yellow.mouseX. These two examples are expressed in the Meson language as follows:
Meson.clock=5.3
Image.Blue.x={Image.Yellow.mouseX+50}
|
The Meson.clock example is called an immediate expression, whereas the Image.Blue.x example is
a deferred expression. When an expression references an attribute on the blackboard which is defined by a deferred
expression, that expression is evaluated. In the semantics of Java, a deferred expression is like a method, whereas an immediate
expression is like an instance variable. For almost all cases, deferred expression can fully describe the dynamic state of the sytem.
However, for the few cases where this is not true, the Meson runtime provides the concept of a Trigger. A trigger combines
some sort of test, with an expression to evaluate under conditions described by the test. There are several variations of Trigger, to
detect "transition to true" conditions, "value changed" conditions, and "value might have changed" conditions. Triggers are only
evaluated when the attributes in their test are assigned new values. In the case of deferred expression, the Trigger wll be tested when
any attribute used in that expression is assigned a new value. In general, there are two ways to express most relationships between
attributes:
ChangeTrigger.ToolCenter.test={Display.Primary.width}
ChangeTrigger.ToolCenter.exec={Image.Toolbar.x=Display.Primary/2}
|
Image.Toolbar.x={Display.Primary.width/2}
|
When a choice like this exists, do not use the Trigger. The latter expression is more concise, easier to debug, and more
efficient than the former expression. The temptation will probably be to use the former method, because that is how it would be done in a procedural language
like Java or Basic. But Meson is a declarative language, not a procedural one. A Trigger should be used only when there is no way to express the
relationship in a declarative manner, as shown in the following example:
Area.Button1.state={Area.Button1.press?"press":"off"}
Trigger.Button1.test={Area.Button1.press}
Trigger.Button1.exec={counter=counter+1}
|
The blackboard uses a smart cache to minimize the runtime cost of using deferred expressions. For example, if Image.Toolbar.x is defined as follows:
Image.Toolbar.x={Display.Primary.width/2}
|
the first time anything reads Image.Toolbar.x from the blackboard, the calculation will be performed. This value is cached,
and every other blackboard value which contributed to its calculation (just Display.Primary.width in this case), is tagged
with the cache dependency. If Display.Primary.width changes, then the cached value of Image.Toolbar.x will be
dropped. But until then, subsequent reads of this attribute will be essentially free. In a typical Meson application, about 90% of
attribute fetches from the blackboard hit the cache.
The presence of the cache is generally transparent to the Meson programmer. However, there is one case which requires special care:
programming by side effect. When an attribute on the blackboard is really being used as a procedure, callers must use care
to reference it using procedure call semantics. For example:
increment={counter=counter+1}
Trigger.Button1.test={Area.Button1.press}
Trigger.Button1.exec={increment()}
|
Note the use of parenthesis in the read of increment. This tells the cache system to evaluate the expression, regardless
of whether a value might be cached.
The blackboard is augmented with a scratch data storage area, called the notebook. The notebook has pages, which can
store attributes, much like the blackboard. The idea of the notebook is that it is a semi-private area where an expression can take notes without polluting the
blackboard. For example:
distSquared={#dx=Applet.Primary.mouseX-cx;#dy=Applet.Primary.mouseY-cy;
#dx*#dx+#dy*#dy}
|
In this example, two notebook attributes (#dx and #dy) are used to store temporary values. Reading and writing
attributes in the notebook is more efficient than working on attributes on the blackboard, because notebook attributes have two
restrictions: notebook attributes cannot be tested in a Trigger, and notebook attributes cannot be objects (for example, #Image.Foo.x does
not create an object of class Image, whereas Image.Foo.x would implicitly create such an object). Also, notebook
attributes are not cached.
An application uses attributes on the current page of the notebook with the # operator. It is also possible to
use attributes on the next page of the notebook, using the ^ operator. This facility is provided as an argument passing
mechanism -- when an attribute is
referenced using function notation (for example, Meson.sin(3.14)), the notebook page is advanced. This way each function
can safely write any attribute without concern for trashing someone else's notes.
squareSum={#dx*#dx + #dy*#dy}
distSquared={squareSum(^dx=Applet.Primary.mouseX-cx;
^dy=Applet.Primary.mouseY-cy)}
|
The remainder of this document fully describes the Meson language and object model.
Syntax
Meson programs are written in a line-oriented declarative language. A typical line of a Meson program looks like this:
Attributes can be simple names, or they can be fully qualified object members. For example:
Each delcaration occurs on a single logical line. If the text is long, lines can be split by ending them with \ (similar to some
BASIC interpreters). Unbalanced curly braces implicitly cause line continuation:
Image.Label.text="This is a very long string "+ \
"which has been split across lines."
Scene.3d.width={Display.Primary.Width-
Image.RightToolbar.Width}
|
Literal symbols include quoted strings (as with Javascript, the forms "string" and 'string' are both
allowed, to ease embedding quote and apostrophe characters within strings), the special strings true
and false, and any string of non-operator characters starting with any of the
following: ._-0123456789 (period, underscore, minus sign, and digits). In essence, the quotes are optional when symbols
start with these characters. Whether a symbol denotes a number depends on how it is used, not on what its starting character is.
The symbols true and false are recognized by the parser and need not be quoted.
Using quotes around a string allows the use of any special character, and also enables the use of escaping (\n for newline,
\t for tab, \" for a quote, \' for an apostrophe, and \uXXXX for a unicode
character). Note that the parser reads the text as UTF-8 encoded unicode, so using unicode escapes is only necessary if the text is
being edited with a ASCII editor, like Notepad.
Style.Default.color=336699
Style.Default.color="336699"
Style.Default.color="FFFFFF"
black="ff000000"
text='He said, "Hello".'
text="It's my party..."
Style.Default.color=black
Style.Default.color=@("black")
Image.Logo.text="Powered By\nwww.strata.com"
Image.Temp.text={"Current Temp: " ~ temp ~ "\u00B0 C"}
|
There are two kinds of expressions which can be used on the right side of an assignment: immediate and
deferred. An immediate expression is evaluated right away, whereas a deferred expression is like
a little program which will run on demand:
|
Examples of immediate expressions.
Scene.3d.width=300
Image.Toolbar.anchor=_C
Image.Toolbar.x=Scene.3d.width/2
Examples of deferred expressions.
Scene.3d.width={Display.Primary.width}
Image.Toolbar.x={Display.Primary.width/2}
|
Expressions can combine terms using a variety of operators:
-
* / % Multiply, Divide, Remainder
-
+ - Add, Subtract
-
! & | Not, And, Or (boolean operators)
-
∪ \ Union, Set Minus (array operators; ++ -- also accepted)
-
~ Concatenate (string operator)
-
≈ < > Equal to, Less Than, Greater Than (== is accepted in place of ≈)
-
≠ ≤ ≥ Not Equal to, Less or Equal, Greater or Equal (!= <= >= also accepted)
-
? : Test (a?b:c means if (a==true) then b else c), the : clause is optional
-
@ # ^ Attribute Reference, Local Reference, Parameter Reference
-
¬ Dereference (-> also accepted)
-
= Assignment
-
; , Statement Separators
-
{ } Deferred Expression
-
( ) Grouping/Function Operator
-
[ ] Array Operator
-
« » Prefix Section (<< and >> also accepted)
The following examples demonstrate some syntactic paradigms:
Area.Measure.state={Scene.3d.mode=="rotate"?"on":"off"}
attr={#dx=(Image.Pop.x-Image.base.x); #dx * #dx}
square={square.arg * square.arg}
attr=(square.arg=(Image.Pop.x-Image.base.x); square())
square={#arg * #arg}
attr=square(Image.Pop.x-Image.base.x)
squareSum={#x*#x + #y*#y}
attr=squareSum(^x=Image.Pop.x-Image.base.x;^y=Image.Pop.y-Image.base.y)
power={#exp==1?#base:(#base*power(^base=#base;^exp=#exp-1))}
Image.Expr.text="5^6=" ~ power(^base=5;^exp=6)
power={#exp==1?#base:(#exp=#exp-1;#base*power)}
theImage="Image.Main"
theX={@(theImage~.x)}
theY={theImage->y}
hello={Meson.log("Hello")}
helloWorld=hello+{Meson.log("World")}
Foo.Class<<
.bar=1 /* equivalent to Foo.Class.bar=1 */
.baz=2 /* equivalent to Foo.Class.baz=2 */
>>
|
Built-in Functions
The Meson interpreter defines a handful of built-in functions:
foreach(string elem, array in, deferred do) iterates over the elements in an array:
numbers=[one,two,three]
count={^c=0;foreach(^elem="i";^in=numbers;^do={#c=#c+1;@Meson.log(#c~" = "~#i)})}
|
try(deferred exec, deferred catch) returns the value of the exec clause unless an exception is thrown, in which case the value of the catch clause is returned. When the catch clause is evaluated three additional local attributes are placed in the notebook: exception fully qualified Java class of the exception; message message member of the Java exception; javaException actual Java Exception object.
width="90%"
widthNum={try(^exec={width+0};^catch={
Meson.log("E: {"~#exception~"}");
Meson.log("M: {"~#message~"}");
Meson.log("J: {"~#javaException~"}");
-1})}
|
Meson.length(array arg) returns the number of elements in the array.
Meson.assert(boolean arg) throws an exception if the passed arg is not equal to "true":
a=5
b={Meson.assert(a==5); a}
c={b*b}
d={a=3}
e=d+c
|
Meson.throw(string arg) throws an exception
Meson.log(string arg) prints a string to the console
Meson.dump(string arg) dumps the blackboard contents to the console. Only blackboard items starting with the passed argument are dumped.
Use Meson.dump("") for a full dump.
Meson.getMethod(string class, string method, array args) and Meson.callMethod(java.lang.reflect.Method method, array args) are used together to access Java methods:
randMethod=Meson.getMethod(^class="java.lang.Math";^method="random";^args=[])
rand={Meson.callMethod(^method=randMethod;^args=[])}
Image.Foo.x={rand * Display.Primary.width}
Meson.atan2Method=Meson.getMethod(^class="java.lang.Math"; \
^method="atan2";^args=["double","double"])
Meson.atan2={Meson.callMethod(^method=Meson.atan2Method;^args=#arg)}
someAttr=Meson.atan2([1, 0.5])
|
Note that for non-static methods, the Java object to operate on should be passed as the first array element to
Meson.callMethod but should not be declared in the array passed to Meson.getMethod.
Use the built-in attribute null to pass a null pointer as an argument.
Meson.newInstance(string className) creates an instance of a Java class using the no-arguments constructor.
Meson.gluon(string arg) loads a Gluon to add more built-in functions:
Applet.Primary.image="splash.jpg"
Meson.gluon("com.kaon.meson.raster.RasterGluon")
Display.Primary.file="splash2.jpg"
|
Each bit of functionality in the Meson system is provided by a Gluon. A Gluon is a set of Java classes which extend the
native capabilities of the Meson language. This document describes functions provided by the Raster and Scene Gluons.
Meson.showDocument(string applet, string url, string target) is used to request than an applet show an HTML
page (url parameter) in a frame or window (target parameter).
Meson.showStatus(string applet, string status) is used to request than an applet show a message in the the
status bar of the browser window.
Meson.jsEval(string javascript) is used to invoke an arbitrary javascript expression in the context of the web page that
includes the applet. Note that the MAYSCRIPT attribute must be added to the applet tag on the HTML page if this method
is used.
Meson.addContextMenu(string applet, string label) adds a label to the applet context menu. Calling this
with the ^label="-" inserts a separator. When the user accesses an item on the context menu, this label value is placed
in the applet's menuItem attribute.
Meson.addContextMenu(^applet="Applet.Primary", ^label="CNN")
Trigger.CNN.test={Applet.Primary.menuItem=="CNN"}
Trigger.CNN.exec={Meson.showDocument(^applet="Applet.Primary", ^url="http://cnn.com", target="_blank")}
|
Meson.unique generates a unique identifier, useful for creating helper objects.
setInterval={#t="Timer."~Meson.unique();#t->delay=#delay;#t->repeat=true;#t->exec=#exec;
@(#t->start);#t}
|
Meson.checkpoint captures the entire state of the blackboard into an attribute
Meson.restore(arg) restores the state of the blackboard to the passed checkpoint
Meson.addContextMenu(^applet="Applet.Primary", ^label="Checkpoint")
Meson.addContextMenu(^applet="Applet.Primary", ^label="Restore")
ckpt=Meson.checkpoint()
Trigger.Checkpoint.test={Applet.Primary.menuItem=="Checkpoint"}
Trigger.Checkpoint.exec={ckpt=Meson.checkpoint()}
Trigger.Restore.test={Applet.Primary.menuItem=="Restore"}
Trigger.Restore.exec={ckpt=Meson.restore()}
|
Note that the checkpoint itself is not in the checkpointed blackboard, so restore returns the checkpoint, so that it can
be stored into the restored blackboard. If the Restore trigger simply said Trigger.Restore.exec={Meson.restore()} then
the attribute ckpt would disappear after restore, since it is restoring a blackboard which had no ckpt
attribute on it.
Meson.setInterval(number delay, deferred exec) creates a repeating timer, similar to the JavaScript setInterval function
Meson.setCurrentDataSource(string arg) sets the default data source for images created between now and the next time
this is called. This is used by the Data class of the Raster gluon to control defaulting when reading a meson program, and the data used by that program,
from the same file. The argument should either be the name of a Data object (Meson.setCurrentDataSource(Data.myProg)) or
a URL relative to the current document base (Meson.setCurrentDataSource("http:/data/")). Since this is set automatically
by the Data object, it is unlikely an application will ever need to call this function.
Meson.clock holds the time since Meson initialization, in seconds.
Meson.frameStep holds the amount of time since the last tick, in seconds.
Meson.documentBase holds the URL of the applets using this blackboard.
Meson.displayDepth holds the bit depth (16 or 32) of the display on which the applet appears.
Meson.notebookPages holds the number of pages in the notebook (32, by default). An application can increase this limit
if it needs to use recursive evaluations which are very deep.
clear black green silver lime gray olive white yellow maroon navy red blue purple teal fuchsia aqua are all predefined
with their CSS-equivalent color values (clear has alpha channel of 0x00, all other have alpha of 0xff)
Meson.isMac is true on Mac OS (9 or X) platforms
Meson.language holds the two-letter code of the default user language as reported by the O/S (en, es, zh, etc...)
Object Models
Several classes are included in the the baseline Meson system: Trigger, ChangeTrigger,
HairTrigger, Timer, Ticker, Applet, and GenericPeer.
Applications create instances of these classes with the notation
Class Name.Instance Name.attributes...=value.
In other words, an instance of a class is created when one of the attributes of that instance is referenced.
Each class defines a set of attributes which have special meaning in instances of that class. The application may use custom
attributes within the scope of an instance as well. The predefined attributes have types which the system expects to find when it parses
them. These are:
-
string a string of unicode characters
-
integer a positive, negative, or 0 whole number
-
number an integer or floating point number (when this represents an integral values, such as pixels, floating point
values will be rounded to the nearest integer)
-
color an ARGB color value specified as 4 or 8 hex digits, or an RGB color value specified as 3 or 6 hex digits
(note that the character # used in HTML colors must be omitted, because # has special meaning)
-
enum a value from the specified list of choices
-
boolean true or false
-
array a set of values (generally, if a value of a different type is used where an array is expected, a one-element
array will be created automatically)
-
attribute the name of an attribute or class instance
-
native a native Java object
-
deferred a deferred expression
Assignments which do not start with a class name create attributes in a global variable space. Assignments which start with a #
create attributes on the current notebook page. Assignments which start with a ^ create attributes on the next notebook
page, which will be the current notebook page of the next function invoked.
The defaults for a class can be overridden using the special object Class which acts as a template during
instantiation. For example, to change the default for Images to use 16-bit color depth instead of 32-bit color depth, use
Image.Class.depth=16. Note that this will not retroactively change existing instances. To implement retroactive changes
to defaults, use deferred assignments: defaultImageDepth=32 and
Image.Class.depth={defaultImageDepth}. In this example, images get {defaultImageDepth} as their depth
attribute, so that a subsequent assignment defaultImageDepth=16 would flow through to the images.
Applications can create custom classes using the special member extends. For example,
HotImage.extends="Image" creates a new class HotImage which extends Image. The application can
then assign attributes to HotImage.Class which will become the defaults for HotImage objects. Note that if an
attribute matches the name of an attribute in the superclass, then the subclass initializer sets the superclass attribute instead. For
example, if HotImage.Class.layer=5, then when the object HotImage.Foo is created, the assignment
Image.Foo.layer=5 will occur. In this example, HotImage.Foo.layer
becomes a proxy to the underying attribute Image.Foo.layer, so reads and writes of either attribute actually change the one
in the base class.
A class can extend multiple base classes. For example, Display.extends=["Applet","Image"]. The order in which base classes
are listed is used to resolve conflicts. For example, both Applet and Image define the width
attribute. Since Display extends Applet first, the default value of width comes from
Applet, and the Display and Image versions of the object both proxy width from Applet:
A.extends=""
A.Class.a=1
A.Class.x=2
B.extends=""
B.Class.b=3
B.Class.x=4
C.extends=["A","B"]
C.Class.c=5
C.Class.a=6
Meson.assert(C.foo.b==3)
Meson.assert(C.foo.x==2)
Meson.assert(C.foo.a==6)
Meson.assert(C.foo.x=9;(A.foo.x==9 & B.foo.x==9 & C.foo.x==9))
|
The $ character is substituted dynamically in class initialization with the name of the object being created. For example,
HotImage.Class.x={HotSpot.$.x} implies that the object HotImage.Reset automatically get the attribute assignment
HotImage.Reset.x={HotSpot.Reset.x}, allowing automatic linking between objects in the user-defined class HotImage and similarly
named hotspots. Similarly, $$ substitutes the fully qualified name including the class and instance parts.
i18n.OK="Way!"
i18n.Cancel="No Way!"
I18NImage.extends="Image"
I18NImage.Class.text={i18n.$}
buttonPadding=5
I18NImage.OK.anchor=SE
I18NImage.OK.x={Image.Dialog.width/2 - buttonPadding}
I18NImage.OK.y={Image.Dialog.height - buttonPadding}
I18NImage.Cancel.anchor=SW
I18NImage.Cancel.x={Image.Dialog.width/2 + buttonPadding}
I18NImage.Cancel.y={Image.Dialog.height - buttonPadding}
|
A class can be given a special member new which is an expression evaluated when an instance is created, just after all
the predefined Class attributes are set. This facility can be used to automatically create partner attributes or objects
which go along with instances of a class.
TipImage.extends="I18NImage"
TipImage.Class.time=2
TipImage.new={ Timer.Hide$.delay=$$.time;
Timer.Hide$.exec={$$.layer=-1};
Trigger.Hide$.test={$$.layer>-1};
Trigger.Hide$.exec={Timer.Hide$.start()} }
TipImage.Class.anchor=_S
TipImage.Reset.x=Area.Reset.x+Area.Reset.width/2
TipImage.Reset.y=Area.Reset.y
SlowTipImage.extends="TipImage"
SlowTipImage.Class.time=5
SlowTipImage.Foo.time=1
|
The prior example demonstrates the order in which initialization of objects takes place when subclassing is being used:
- superclass (recursively) members
- subclass members
- superclass (recursively) new
- subclass new
- instance members
In the example, the final assignment results in the following assignments (in this order) at run time:
Image.Foo.text={i18n.Foo}
TipImage.Foo.time=2
Image.Foo.anchor=_S
TipImage.Foo.time=5
Timer.HideFoo.delay=TipImage.Foo.time
Timer.HideFoo.tick={Image.Foo.layer=-1}
Trigger.HideFoo.test={Image.Foo.layer>-1}
Trigger.HideFoo.exec={Timer.HideFoo.start()}
TipImage.Foo.time=1
|
The final assignment has no effect, because the assignment to Timer.Hide$.delay was an immediate expression. In order for
this example to have the intended results, a deferred expression should have been used:
TipImage.new={ Timer.Hide$.delay={TipImage.$.time};
|
Then the initialization would have been:
Timer.HideFoo.delay={TipImage.Foo.time}
|
which would respond to subsequent changes to the time member of TipImage objects.
The .new attribute is unique, in that each one in a class hierarchy has an opportunity to run during initialization.
Contrast this with other attributes, in which the proxy substitution rules described above cause subclass members to merely replace
superclass members at instantiation. Sometime it is desirable for the subclass to override an attribute (particularly one which holds
a deferred expression), but keep access to the superclass definition as well. This can be accomplished by accessing the
special Class instance member, and using the + operator to join deferred expressions together:
Foo.extends=""
Foo.Class.someMethod={Meson.log("$$ " ~ #arg)}
Bar.extends="Foo"
Bar.Class.access=0
Bar.Class.someMethod=Foo.Class.someMethod+{$$.access=$$.access+1}
|
Another case where + is used to join expressions is adding functionality to an already-defind method:
Foo.Class.new=Foo.Class.new+{Meson.log("Detected creation of object: $$")}
|
By convention, class and object names start with capital letters, while attributes start with lowercase letters. This language is case sensitive.
Basic Object Model
Class: Trigger
A trigger runs a deferred expression when the value of a test expression changes to true.
|
This example sets an attribute in response to a mouse press on the Area called Button
Trigger.Show.test={Area.Button.press}
Trigger.Show.exec={Image.PressedImage.layer=9}
|
|
This example sets an attribute in response to a mouse release on the Area called Button
Trigger.Hide.test={!Area.Button.press}
Trigger.Hide.exec={Image.PressedImage.layer=-1}
|
| An expression which should evaluate to true or false |
| Type | deferred |
| This expression is evaluated when the test transitions from false to true |
| Type | deferred |
Class: ChangeTrigger (Extends Trigger)
A change trigger runs a deferred expression when the value of a test expression changes.
|
This example increments a counter whenever an area changes state in any way
ChangeTrigger.StateCount.test={Area.Button.state}
ChangeTrigger.StateCount.exec={Area.Button.stateCounter=Area.Button.stateCounter+1}
|
| An expression which is evaluated |
| Type | deferred |
| This expression is evaluated when the test value changes |
| Type | deferred |
Class: HairTrigger (Extends Trigger)
A hair trigger runs a deferred expression when anything referenced in the test might have changed, regardless of whether the value of the test expression actually changed. Note that writing a value to the blackboard which is identical to the value already there will not fire a HairTrigger.
|
This example prints a message whenever the layer or alpha is modified
HairTrigger.DebugVis.test={Image.Foo.layer;Image.Foo.state}
HairTrigger.DebugVis.exec={Meson.dump(Image.Foo)}
|
| An expression |
| Type | deferred |
| This expression is evaluated whenever anything in the test might have changed |
| Type | deferred |
Class: Timer
Timers are used to perform actions after a delay, or periodically.
|
This example displays a popup image for a hotspot when the mouse enters, and uses a timer to hide the hotspot 2.5 seconds after
the mouse exits.
Timer.HidePort.exec={Image.portPopup.layer=-1}
Timer.HidePort.delay=2.5
Trigger.SP1.test={HotSpot.Port.hover}
Trigger.SP1.exec={Image.portPopup.layer=9}
Trigger.SP2.test={!HotSpot.Port.hover}
Trigger.SP2.exec={Timer.hidePort.start()}
|
| The delay between events generated by this timer (seconds). |
| Type | number |
| Default | 0 |
| Controls whether the timer fires once, or periodically. |
| Type | boolean |
| Default | false |
| This expression is evaluated when when the timer ticks. |
| Type | deferred |
| Reading this attribute starts the timer. |
| Restrictions | Use function() semantics |
| Reading this attribute stops the timer without firing it. |
| Restrictions | Use function() semantics |
Class: Ticker
Tickers are used to evaluate an expression every frame. An order member is present which can be used to control the order
of execution of Tickers in the system.
| Tickers execute in increasing order, starting at 0. The order of execution
for Tickers with the same order attribute is the order in which they were created. Setting the order to a value
less than 0, such as -1, will prevent the ticker from ticking. |
| Type | number |
| Default | 0 |
| This expression is evaluated when when the Ticker ticks. |
| Type | deferred |
Class: Applet
Applet objects represent applets on web pages. Applet is the only graphical class included in the base object model, in order to
keep the initial footprint of Meson very small. Applications will typically use the Applet class only to display a splash logo. After
loading the Raster gluon, the application will then use the Display class which extends the Applet class with image manipulation
capabilities.
The name of an applet comes from it's mesonName property on the HTML page. If no name is given, the default Applet
name is Primary. If the application uses multiple applets on the same Blackboard, names must be assigned
explicitly.
| This holds the java.applet.Applet object for the
applet. |
| Type | native |
| Default | "" |
| Restrictions | Read Only |
| This holds the java.awt.Image object used as the
background of the applet. Initially, this is based on the image attribute, but when the Raster gluon is loaded, the
Display class replaces it with a new image to reflect the dynamic state of the executing program. |
| Type | native |
| Default | "" |
| Restrictions | Read Only |
| The fill is used at Applet startup to control the background color. |
| Type | color |
| Default | fff |
| The image attribute is a URL (relative to the document on which the applet is
placed) of an image to show in the Applet while the remainder of the program is loading. Progressive JPG or Interlaced GIF images
can be used to get immediate content onto the screen. |
| Type | string |
| Default | "" |
| When set to true, the applet will ask Java to initiate a
repaint. |
| Type | boolean |
| Default | false |
| Width of the applet. This may change if the applet is in
a resizable window, and uses percentage for its width attribute. |
| Type | integer |
| Default | 0 |
| Restrictions | Read Only |
| Height of the applet. This may change if the applet is in
a resizable window, and uses percentage for its height attribute. |
| Type | integer |
| Default | 0 |
| Restrictions | Read Only |
Keyboard and mouse input is delivered into Applet attributes. In order to ensure Trigger objects fire correctly, the
events are queued as they happen, so that if multiple events happen during a frame, the next frame will get all those events in
order. For example, if the left mouse button is clicked, the press element will be set to true
(causing Triggers watching for press to execute), and then to false (causing release Triggers to execute).
| The X position of the mouse, measured from the left side
of the applet. Note that browsers typically only deliver mouse coordinates when the applet has focus. |
| Type | integer |
| Default | -1 |
| Restrictions | Read Only |
| The Y position of the mouse, measured from the top
of the applet. Note that browsers typically only deliver mouse coordinates when the applet has focus. |
| Type | integer |
| Default | -1 |
| Restrictions | Read Only |
| True when the left mouse button is being pressed
in the applet. |
| Type | boolean |
| Default | false |
| Restrictions | Read Only |
| True when the Shift key is pressed and the applet has
focus. |
| Type | boolean |
| Default | false |
| Restrictions | Read Only |
| True when the Control key is pressed and the applet has
focus. |
| Type | boolean |
| Default | false |
| Restrictions | Read Only |
| Holds the most recently typed key. Triggers which respond to keystrokes can set
this back to "" after firing, to respond to mulitple presses in a row. For special keys, this holds the key
name (Enter, Left, Right, Up, Down, Tab,
Delete, Back). For all other keys, it holds the unicode letter. |
| Type | string |
| Default | "" |
Class:
GenericPeer
Generic Peer is extended by other objects which bear a very close relationship to objects implemented by Gluons in Java code.
Their primary purpose is to provide a simple, consistent way for Meson programs to invoke methods on these native objects. Their use
is entirely optional, as they merely wrap calls to built-in functions like Meson.getMethod and
Meson.callMethod.
| Specifies the fully-qualified Java class name of the native peer class. |
| Type | string |
| Holds the native object which is created in reponse to this object being referenced in the
Meson program. Note that a no-arguments constructor is used by default, so a native class using this facility should use separate
initializers (similar to the design pattern used in Applets and Servlets). |
| Type | native |
| Invokes a method on the native object. Arguments are as follows:
-
method: native method name as a string
-
types: array of argument types. For primitive types, use strings like float or long. For object
types use the fully-qualified class name, such as java.lang.String. For array types, use the Java method signature conventions (for
example, "[[F" for a two-dimensional array of float, or "[Ljava.lang.String;" for a
one-dimensional array of strings.
-
args: array of arguments, which must correspond to the values passed in the types parameter. As
explained above, use null for null parameters.
|
| Type | deferred |
| Looks up a method of the native object. When a method is going to be called very
frequently, it is a good idea to look it up once in advance and cache it, rather than looking it up over and over
with callMethod. Arguments are as follows:
-
method: native method name as a string
-
types: array of argument types. For primitive types, use strings like float or long. For object
types use the fully-qualified class name, such as java.lang.String. For array types, use the Java method signature conventions (for
example, "[[F" for a two-dimensional array of float, or "[Ljava.lang.String;" for a
one-dimensional array of strings.
|
| Type | deferred |
Raster Gluon
The Raster gluon adds several classes to Meson: Anim, Data, Image,
Display, Area, and Style. It also adds several built-in functions.
Raster Built-in Functions
Meson.sin(number arg),
Meson.cos(number arg),
Meson.tan(number arg),
Meson.atan(number arg),
Meson.atan2(array arg),
Meson.round(number arg),
Meson.ceil(number arg),
Meson.floor(number arg),
Meson.ln(number arg) (natural log),
Meson.exp(number arg) (natural exponent)
provide access to
the equivalent methods in java.lang.Math. For convenience, the attributes Meson.degToRad and Meson.radToDeg
are also defined.
Ticker.Dot.exec={currentAngle=currentAngle+Meson.frameStep*rateDegPerSec}
rateDegPerSec=360/60
Image.Dot.x={dotRadius * Meson.cos(currentAngle*Meson.degToRad)}
Image.Dot.y={dotRadius * Meson.sin(currentAngle*Meson.degToRad)}
dotRadius={(Image.Dot.parent~.width)/2-Image.Dot.width}
|
Meson.formatFloat(number value, string format) returns the number formatted according to the user's regional numeric
formatting conventions, as specified by the OS. The format specifier is of the
form integerDigits[.decimalDigits]. That is, the if no decimal part is given, the value will be shown as an
integer.
Raster Object Model
Class:
Anim
Animation objects are used to set attributes to values over time. The animation uses a combination of linear interpolation and
exponential smoothing, to allow values to change in a variety of ways.
|
This example shows how to use an Anim object to make a toolbar slide in when the mouse enters the area (like a desktop taskbar with
auto-hide).
Area.ShowToolbar.image="Image.Toolbar"
Anim.ToolY.attr=["Image.Toolbar.y"]
Anim.ToolY.rate=10
Anim.ToolY.highPriority=true
Anim.ToolY.goal=[{Display.Primary.height-(Area.ShowToolbar.hover?Image.Toolbar.height:5)}]
|
| The attributes which are controlled by this animation. |
| Type | array of attribute |
| The value to be assigned to each attr over time. |
| Type | array of number |
| The maximum rate (per second) at which to change the value. If this value is <0,
the rate is not limited. |
| Type | number |
| Default | -1 |
| The exponential smoothing constant to apply when changing the value. A value of 0
changes instantly, whereas a value of 1 will never change. This parameter controls the amount of goal value to blend with the current
value each time step, based on the equation weight=smoothtimeStepSeconds. Typical values are around 0.05. |
| Type | number |
| Default | 0 |
| When an attribute value is this close to the goal
(|goal-attribute|≤threshold) the attribute will be set to exactly the goal. |
| Type | number |
| Default | 0.001 |
| The animation only operates when this attribute
is true. |
| Type | boolean |
| Default | true |
| If this is set to true, the animation will set its
own enabled attribute to false when the attribute value reaches the goal. This is used for "one shot"
animations. |
| Type | boolean |
| Default | false |
| If modulus is non-zero, then the attribute will skip up or down an appropriate amount
to never be more than half the modulus away from the goal. For example, when the attribute is an angular measure, a modulus
of 360 will lead to the attribute following the shortest path around the circle to the goal. |
| Type | number |
| Default | 0 |
| A high-priority animation sets an internal flag in the applet context
when it is running (i.e., when the attribute value is not the goal, and the animation is enabled). This flag is consulted by various
low-priority tasks, such as 3D Scene anti-aliasing, to control sharing of CPU cycles. In a nutshell, a high-priority animation will
be visually smoother than a normal priority one on a heavily loaded system. For animations with moving rasters, such as the toolbar animation in the
above example, this will give a better appearance. For animations of alpha parameters, it is generally not necessary, as the user
cannot see the subtle frame rate differences involved. |
| Type | boolean |
| Default | false |
Class:
Data
Data objects represent a bundle of resources used by a Meson application. The data file referenced by this object is in the ZIP (JAR)
format, and may contain an arbitrary mix of .txt files containing Meson programs, .jpg and .gif files used by those programs, 3D scene
data including wavelet .kwl files and compressed binary data, and other ZIPs or JARs. The best compression is achieved by building a compressed JAR containing a single uncompressed JAR with
the files. The resulting compression is much better than a simple compressed JAR.
| URL (relative to the page the applet is on) of the JAR file containing the data |
| Type | string |
| State of the data file. Data starts
in the _NEW state, immediate transitions to the _OPEN state where data is read, and transitions to the
_CLOSED state when reading is complete. It may transition to the _FAILED state if any error
occurs. |
| Type | enum
_NEW, _OPEN, _CLOSED, _FAILED |
| Restrictions | Read Only |
| When the state is _FAILED, this holds
the error message |
| Type | string |
| Restrictions | Read Only |
| Contains the content length, as reported by the server. Note
that this may be -1 if the server does not know the content length. |
| Type | number |
| Restrictions | Read Only |
| Contains a count of bytes read so far. |
| Type | number |
| Restrictions | Read Only |
| Set this to true to temporarily stall reading the
data. |
| Type | boolean |
| Default | false |
| Contains the list of files read from this data source so far. |
| Type | array |
| If the data source contains wavelet-encoded images, this holds the
percentage of image data which has been decoded so far. |
| Type | number |
| Default | 100 |
| When set to true, the file read will stop, and the state will transition back
to _NEW. This will cause the file to immediately start loading again, unless you first set the url attribute to "". |
| Type | boolean |
| Indicates that the URL points to Meson code or a ZIP/JAR archive which should be parsed. |
| Type | boolean |
| Default | true |
| When the parse attribute is false, the data pointed at by the URL will be read into a string and placed into this attribute. |
| Type | string |
Class:
Image
An image is a rectangular raster of pixels. There are three ways to create an image: from a file, by rendering text, or simply
allocating a blank area.
| Create the image from the specified file. The file may be a GIF or JPG format
image (PNG format is not supported in all browser environments, so it should be avoided). GIF files may use animation, although this
should be avoided where possible for performance reasons (using a multi-state image and flipping thru the states will yield faster
update rates). In cases where a continuous alpha channel
is required (in contrast to the On/Off alpha of GIF transparency), two images may be given, separated by an @ symbol.
The first file gives the color information, and the second gives alpha information. For example:
Image.Toolbar.file="toolbar.jpg@toolbarMask.gif".
The blue channel of the pixels in the GIF images are used as the alpha channel (in practice, a gray-scale GIF can be used,
since the red and green channels are ignored). The color pixels may come from either a JPG or GIF format file, however, if GIF is
used, it must not include transparency (specify transparency in the alpha channel file instead). Animation is not permitted in an
alpha channel GIF. |
| Type | string |
| Example | "top.jpg" |
| Create the image by rendering the specified text. The background of the
text comes from the buffer attribute. If no buffer color is given, the text will be on a transparent background. |
| Type | string |
| Example | "Open Lid" |
| Specifies the default spacing, in pixels, for tab stops (used when rendering
text containing the \t character). |
| Type | number |
| Default | 50 |
| Specifies explicit tab stop locations, in pixels. Note that, as with word
processing programs, the default tab spacing is used to the right of the last explicit tab stop. |
| Type | array |
| Default | [] |
| Text can be auto-wrapped while being rendered, to ensure the resulting image
does not exceed a certain width. This attribute controls that process. Note that spaces, tabs, language-specific rules (such as Japanese, where breaks between glyphs are allowed except in a few cases), and style-changes can result
in breaks (the non-breaking-space unicode character \u00A0 can be used to insert a non-breaking space between words). If a single
piece of unbreakable text is longer than will fit in the wrapWidth, then text wrapping will not be performed on that text. In this
case, the width member could end up larger than wrapWidth, if set implicitly. If you assign a particular
value to width then text which extends beyond this will be clipped. |
| Type | number |
| Default | 0 |
| When using the wrapWidth attribute, this selects the language rules to use when determining how to break long lines at word boundaries. |
| Type | string |
| Default | {Meson.language} |
| When using the wrapWidth attribute, this selects the country-specific language rules to use when determining how to break long lines at word boundaries. |
| Type | string |
| Default | "" |
| Create a buffer with the specified fill color |
| Type | color |
| Example | "FF336699" |
| Used together with a buffer, this softens the alpha channel all the
way around the rectangular image by the specified number of pixels on each side. |
| Type | number |
| Default | 0 |
Images can represented internally using 32-bit ARGB, or 16-bit YCrCb representation. In the 32-bit setting, alpha and the 3 color channels are represented by 8 bits each. In the 16-bit setting, each adjacent pair of pixels share a chominance value, and each has its own luminance. Both modes support a full 256 gray levels, but only the 32 bit mode supports alpha channels and the complete range of colors. For textures compressed with JPEG compression, there is nothing to be gained using 32-bit representation, because JPEG forces each pair of adjacent pixels to have the same chrominance.
| Set the color depth to be used to represent this image |
| Type | enum 16, 32 |
| Default | 32 |
Text images will always use font smoothing when the underlying Java implementation supports it. When it does not, font smoothing
can be emulated to varying degrees of precision. The higher the degree, the longer it takes to render the text initially. Once the
text is set, however, the speed of rendering is not impacted by smoothing.
| Font anti-aliasing control. A value of 0 does no
anti-aliasing, 1 does a little anti-aliasing, while value of 2 does maximum anti-aliasing. Note that text which changes frequently, such as the measuring distance,
should use a value of 0 for best performance. This only controls the default anti-aliasing for an image. Individual text Styles
can specify a different level of text anti-aliasing, which will take precedence over this setting. |
| Type | enum 0, 1, 2 |
| Default | 2 |
An image can have multiple states, which are stacked vertically, with the first state on top, the next one below it, and so on. The version of
an image which appears on the screen is the first state overlaid with other states as specified by Area objects within the
image.
| Names the states represented within the image. |
| Type | array |
| Default | ["default"] |
The image is placed at an X,Y coordinate relative to its parent image (such as the display). The coordinates specify the location
that the anchor pixel should be located on that image. The 0,0 point on the parent is the northwest corner of the parent.
| The image on which this image is rendered. |
| Type | attribute |
| Default | "Display.Primary" |
| The X position of the image anchor, relative to its parent. |
| Type | number |
| Default | 0 |
| The Y position of the image anchor, relative to its parent. |
| Type | number |
| Default | 0 |
| The stacking order value of this image. 0 is on the bottom. Images with a layer
value < 0 are not displayed. |
| Type | integer |
| Default | 0 |
| The alpha blending value of this image. 0.0 is transparent; 1.0 is
opaque. |
| Type | number |
| Default | 1.0 |
| The position of the anchor expressed as a compass
direction, or _C for center. For example, if the image is 150x24, anchor=_S would place the anchor at 75,24. |
| Type | enum
_N, _NW, _W, _SW, _S, _SE, _E, _NE, _C |
| Default | _NW |
| The width of the image. |
| Type | number |
| The displayed height of the image. Note that if the number of states is greater than 0, then the height reported in
this attribute will be a fraction of the actual overall height of the image. |
| Type | number |
| For Images which use file attribute, and also specify an explicit
width and/or height, the file contents will be placed int the upper left corner by default. If the tile is set to true,
however, the file will instead be tiled across the image area (like the background image of an HTML page). |
| Type | boolean |
| Default | false |
| Provides a hook to a method that will draw the contents of the image whenever it is required.
This will be invoked immediately after the data buffer is cleared. A pointer to the underlying Java MesonRaster class object is
passed as the argument. |
| Type | deferred |
Images can be scaled independently in X and Y, and rotated through an arbitrary angle. All transforms apply about the anchor of the image. Note that this transform is done at rendering-time, and is currently not cached in any way, so it is best not to use large scaled or rotated images over 3D windows or other screen areas that refresh quite frequently. Children of the image inherit scale and rotation, and are given locations relative to the un-transformed parent.
| Width scaling factor. Use a number less than 1 to shrink the image, or a number
larger than 1 to stretch it. |
| Type | number |
| Default | 1 |
| Height scaling factor. Use a number less than 1 to shrink the image, or a number
larger than 1 to stretch it. |
| Type | number |
| Default | 1 |
| Rotation angle, in degrees. Note that since Y increases as you move down the
screen, this rotates the opposite direction from the geometry you learned in high school: angle=90 means turn the image
1/4 turn clockwise, for example. |
| Type | number |
| Default | 0 |
| When rendering with scaleX ≠ 1, scaleY ≠ 1,
or angle ≠ 0, this controls oversampling. Oversampling is an anti-aliasing technique in which an area of the
original image is averaged together to determine what color to render in each pixel of the destination image. As a general rule,
oversampling will improve the apperance of images that are scaled down by a factor of 2 or more in either dimension.
For large images, where render time is dominated by the time it takes to read data from memory, oversampling will slow rendering of
images by a factor of about 3. |
| Type | boolean |
| Default | false |
| When rendering with scaleX ≠ 1, scaleY ≠ 1,
or angle ≠ 0, this controls bi-linear filtering. Bi-linear filtering is an anti-aliasing technique in which colors
in the original image are interpolated to determine what color to render in each pixel of the destination image. As a general rule,
bi-linear filtering will improve the apperance of images that are scaled by a factor larger than 0.5 in either dimension (that is,
scaled down by a factor less than 2, or scaled up by any factor), or when the image is rotated.
For large images, where render time is dominated by the time it takes to read data from memory, bi-linear filtering will slow rendering of
images by a factor of about 4. |
| Type | boolean |
| Default | false |
Note that oversample and bilinear can be used together, for example, if the image is both scaled down and rotated,
but the delays compound, so using both together may be up to 12 times slower than rendering with neither filter enabled. On the
other hand, if the image is scale down considerably, it will not take that long to render anyway, so the extra processing may not be noticeable.
By default, images monitor mouse motion over their surface, and respond to these actions. This can be switched on and off at the
image level, or for individual areas within the image. Disabling mouse input for an image implicitly disables it for all children
images as well, however, it does not change the enabled attribute of those images.
| Controls whether the image responds to mouse actions such as motion and
clicking. |
| Type | boolean |
| Default | true |
| Cursor to display
when the mouse is over this
image (when this image is enabled). If "" is specified, the parent determines the cursor. This setting may be
overridden by individual areas on the image. If a digit or letter is given, that is used to access any built-in cursor provided by
the Java environment. |
| Type | enum
"", _ARROW, _HAND, _CROSSHAIR, _MOVE, 0,1,2,...9,A,B,... |
| Default | |
Each image automatically creates a Trigger object to repaint when one of several attributes changes. In rare circumstances, an application may need to request a repaint of this to reflect a change in an attribute other than the default ones.
| Read this attribute to trigger a repaint of the applet |
| Type | deferred |
| Restrictions | Use function() semantics |
Most attributes of the image are monitored to determine when the image needs to be rebuilt (text re-rendered, or image file re-decoded). However, there are some cases where the application will need to tell the image that regeneration is needed: making changes to text Style objects used by text rendered into the image is the most common case. The rebuild flag can be used in these cases.
| Set this to true to force a re-build of the image. |
| Type | boolean |
| Default | false |
Each image has several additional attributes which derive their values from other attributes. If scale or rotation transforms are being used, these transforms are inverted in the calculation of these derived attributes. For example, mouseX is the location of the mouse X coordinate on the original image, not the location of the mouse on the scaled or rotated image.
| The X location of the northwest corner of the image relative to the topmost parent's northwest
corner. |
| Type | number |
| Restrictions | Read Only |
| The Y location of the northwest corner of the image relative to the topmost parent's northwest
corner. |
| Type | number |
| Restrictions | Read Only |
| The net alpha value of this image, taking into account the alpha
values of all its ancestors. |
| Type | number |
| Restrictions | Read Only |
| The net enabled state of this image, taking into account the
enabled state of all its ancestors. |
| Type | boolean |
| Restrictions | Read Only |
| The net visibility state of this image, taking into account the
layer and alpha values of all its ancestors. |
| Type | boolean |
| Restrictions | Read Only |
| The X location of the mouse, relative to the northwest corner of this image |
| Type | number |
| Restrictions | Read Only |
| The Y location of the mouse, relative to the northwest corner of this image |
| Type | number |
| Restrictions | Read Only |
| The display on which this image ultimately appears |
| Type | attribute |
| Restrictions | Read Only |
| The X location of the image anchor, relative to the northwest corner of this
image (this is derived from anchor by default, but can be set to an explicit value, if needed). |
| Type | number |
| The Y location of the image anchor, relative to the northwest corner of this
image (this is derived from anchor by default, but can be set to an explicit value, if needed). |
| Type | number |
| List of all Images with this image as their parent |
| Type | array |
| Restrictions | Read Only |
| List of all Areas with this image as their image |
| Type | array |
| Restrictions | Read Only |
| The native representation of this raster inside the Raster gluon
Java code |
| Type | native |
| Restrictions | Read Only |
| This member is true when the image has the same coordinate basis as the
display. That is, it is true when scaleX==1, scaleY==1, and angle==0. This is used to
shortcut the math used in mouse coordinate calculation, and to determine which algorithm to use to transfer pixels from the image to
the display. |
| Type | boolean |
The transform members scaleX, scaleY, and angle are used to compute transformation matrices
for the image. These matrices are stored in image attributes via complex expressions which can be overridden to achieve 2D
transform effects such as shearing. Each 3x2 affine transform matrix is stored in 6 members:
| m00 m01 m02 | | w00 w01 w02 | | i00 i01 i02 |
| m10 m11 m12 | | w10 w11 w12 | | i10 i11 i12 |
The m??, w??, and i?? attributes store the local-to-parent transform, local-to-world transform, and world-to-local transform of this image, respectively. The m members are derived from scaleX, scaleY, angle, x, y, anchorX, and anchorY members. The w members are derived from the m members of this image, and the w members of this image's parent image. The i members are derived exclusively from the w members. So, for example, if you install a shear matrix into the m members, the w and i members will automatically reflect this change. However, be careful that whatever matrix you install in m is invertable (that is, it has a non-zero determinant) since failure to do so will lead to extremely strange results. One last caution: even if you set the m matrix explicitly, you should still set the scaleX and scaleY members, as they are used in the computation of the barycentric mapping functions of source-to-destination pixels in the case of oversampling and bilinear filtering. (If that last sentence was meaningless to you, you probably should not be changing the matrix members directly!)
Class:
Display (Extends ["Applet", "Image"])
Display combines the base class Applet with the raster class Image. When the Raster gluon initializes it promotes all Applet
objects into Display objects.
| Controls the background color of the display. Note that alpha values other than
FF are not permitted, due to browser limitations. |
| Type | color |
| Default | {Applet.$.fill} |
| Controls the background beneath all other images. Note that using a transparent GIF or an alpha channel image will yield inconsistent and unpredictable results. |
| Type | string |
| Default | {Applet.$.image} |
| When the operating system reports that the user is operating in "high-color"
(16 bit color) mode (Meson.displayDepth=="16"), the true color image is dithered by Meson, using an error diffusion
algorithm. This removes color bands, resulting in a much better looking image. |
| Type | boolean |
| Default | true |
| Enqueue an expression to be evaluated just before the next paint pass. This can be used to guarantee execution of a native built-in method in the AWT event thread. |
| Type | deferred |
Class: Area
An image can have a variety of area objects within it, which define rectangular regions which can respond to mouse actions and show multiple states.
Area.RotateMode.image="Image.Toolbar"
Area.RotateMode.x=12
Area.RotateMode.y=34
Area.RotateMode.width=5
Area.RotateMode.height=6
Image.RotateTip.layer={Area.RotateMode.hover==true?9:-1}
Area.RotateMode.state={Scene.3d.mode=="rotate"?
"on":(Area.RotateMode.hover==true?"hover":"off")}
Trigger.RotateMode.test={Area.RotateMode.press}
Trigger.RotateMode.exec={Scene.3d.mode="rotate"}
This example creates an area on the Image Toolbar called RotateMode covering the specified rectangular area. It then sets up rules to show a tool tip and light up the "hover" state of the image in this area when the mouse hovers over the area, and hide the tool tip and revert the state when the mouse leaves the area. It shows the "on" state when the scene is in Rotate mode, regardless of the hover. The last assignments create a Trigger which sets the attribute mode in the primary 3D scene, to set the desired major mode of the interface to rotate when the area is pressed with the mouse.
|
| The image on which this area resides. |
| Type | attribute |
| Default | Display.Primary |
| The pixel location of the left side of the area. |
| Type | number |
| Default | 0 |
| The pixel location of the top side of the area. |
| Type | number |
| Default | 0 |
| The width of the area, in pixels. |
| Type | number |
| Default | image->width |
| The height of the area, in pixels. |
| Type | number |
| Default | image->height |
| Controls whether the area responds to mouse actions such as motion and
clicking. |
| Type | boolean |
| Default | true |
| In a multi-state image, this controls which state is displayed in this area. |
| Type | string |
| Default | "default" |
| Cursor to display when the mouse is hovering over this area |
| Type | enum
_ARROW, _HAND, _CROSSHAIR, _MOVE, 0,1,...9,A,B,... |
| Indicates that the mouse is hovering over the area. In general,
applications should not reference this attribute, but should use hover instead. |
| Type | boolean |
| Restrictions | Read Only |
| Indicates that the mouse is hovering over the area. Note that this is actually an expression, which, by default, exactly matches the value of mouseHover. However, this expression can be overridden, for example to cause two areas to work as one (this is done automatically, for example, when rendering text with embedded areas that wrap across lines). Note that the pixel under the mouse must be drawn by this area's image in order to transition to hover=true (see boxPick below). If the mouse button is pressed on the area, no other area will be considered to have hover until the mouse is released. That is, "grab" is implicit. |
| Type | boolean |
| Indicates that the left mouse button is pressed in the area. |
| Type | boolean |
| Restrictions | Read Only |
| Ordinarily, an area will only be considered for mouse hover if it's image
drew the pixel under the mouse cursor. To have the area be considered regardless of whether the individual pixel was drawn,
set boxPick to true. Note that the image itself still must be drawn, so this is only relevant with images
that have an alpha channel (such as text). |
| Type | boolean |
| Default | false |
| Default pick behavior is similar to boxPick, except that the
pick will happen if either the pick was on a pixel drawn by the image, or if it was on the display behind the image inside the area boundary.
That is, other images can block reception of the hover. |
| Type | boolean |
| Default | false |
When areas are generated automatically during text rendering, the following attributes will also be set:
| The un-styled text content which was rendered into this area. Note that if multiple area
sections have the same ID, this is the concatenation of all those bits of content. |
| Type | string |
| This attribute is read, using function semantics, when the text in this area is first rendered
into the image, in cases where the id is followed by (). See the hypertext example in the section on
the area attribute of the Style class. |
| Type | deferred |
Class:
Style
Styles are used to control the appearance of images created from text. Where possible, attribute names mirror those used in
CSS. There is a predefined style called Default which is used in the absence of style controls in the text. When
rendering text, styles are called out by %style{text to style}. A span of text can be
identified by adding :id after the style name, and when the style defines an area, initialization
arguments can follow the id, as follows: %style:id(args){text to style}
Styles can be nested, where
the inner style overrides one or more parameters of the outer style. ID's are concatenated in this case. When placed on an image with multiple states, the character #
can be used to indicate which state is being rendered. For example, if an image has states ["plain","hover"] then the text
"%Hot_#{Click Here}" would be rendered with style Hot_plain in the plain version of the image, and style
Hot_hover in the hover version. The # character can also be used in the ID - the same substitution rule applies.
|
This example shows how the default style can be set, along with one custom style.
Style.Default.fontFamily=["Arial", "Helvetica", "SansSerif"]
Style.Default.fontSize=12
Style.Default.textAlign=_CENTER
Style.Bold.fontWeight=_BOLD
Image.message.text="Powered By\n%Bold{www.strata.com}"
|
| The font family to use for text. As with CSS, a list
of fallback fonts can be specified. The last fallback should be one of SansSerif, Serif, or
Monospaced. (Note that on some operating systems, case matters.) The special value [] means this attribute is not set. |
| Type | array |
| Default | [] |
| The font size, in points. (Unlike CSS, font sizes cannot
be specified in other units, such as em or px). The value -1 means this attribute is not
set. |
| Type | number |
| Default | -1 |
| The font weight. The value . means this attribute is not
set. |
| Type | enum
_PLAIN, _BOLD, . |
| Default | . |
| The font style. The value . means this attribute is not
set. |
| Type | enum
_PLAIN, _ITALIC, . |
| Default | . |
| Font smoothing. The value -1 means this attribute is not
set. Typically, font smoothing is specified by the Image into which the text is rendered. However, this attribute
allows overriding of the font smoothing for a given style. For example, when rendering a large amount of text,
Image.MyText.fontSmooth=0 might be used to speed up rendering, but Style.Bold.fontSmooth=2 could be
used to enable font smoothing for bold spans. |
| Type | enum
-1, 0, 1, 2 |
| Default | -1 |
| The text decoration. The value . means this attribute is not
set. |
| Type | enum
_NONE, _UNDERLINE, . |
| Default | . |
| The text color. The value "" means this attribute is not
set. |
| Type | color |
| Default | "" |
| The color of the text drop shadow. Use a color with 0
alpha (such as 0000) to skip drawing the drop shadow. The value "" means this attribute is not
set. |
| Type | color |
| Default | "" |
| The distance to the drop shadow, if any. The value -1 means this attribute is not
set. |
| Type | number |
| Default | -1 |
| The sub-pixel X offset used to render the text. Use this together with the
fontSmooth attribute of the image to achieve subtle text effects. The value -1 means this attribute is not
set. |
| Type | number |
| Default | -1 |
| Example | -0.5 |
| The sub-pixel Y offset used to render the text. Use this together with the
fontSmooth attribute of the image to achieve subtle text effects. The value -1 means this attribute is not
set. |
| Type | number |
| Default | -1 |
| Example | 0.5 |
The following attributes may impact more than just the text area being rendered. For example, a style midway through a line with
a larger lineSpacing will increase the spacing for the entire line. When the styles used in a text image differ in
global settings, such as margin, the value used will be derived from a certain character in the text, which is indicated below.
| The text alignment for
multi-line text, and for text created with explicit image width or wrapWidth. The value . means this attribute is not
set. The alignment of all text on a line should be consistent, to avoid strange text-overlap effects. |
| Type | enum
_LEFT, _CENTER, _RIGHT, . |
| Default | . |
| Extra spacing (in pixels) to use between lines of text. Use positive numbers to
increase space between lines, or negative numbers to bring lines closer together. The value -999 means this attribute is not
set. The line spacing for any given line is the maximum of all styles used on that line. |
| Type | number |
| Default | . |
| The number of pixels of space with which to inset the text
inside the image. The value -1 means this attribute is not
set. |
| Type | number |
| Default | -1 |
| The number of pixels of space with which to inset the text
inside the image on the left side. This takes precedence over the margin attribute. The value -1 means this attribute is not
set. The style of the first character on a line controls the left margin for that line. |
| Type | number |
| Default | -1 |
| The number of pixels of space with which to inset the text
inside the image on the right side. This takes precedence over the margin attribute. The value -1 means this attribute is not
set. The style of the last character on a line controls the right margin for that line. |
| Type | number |
| Default | -1 |
| The number of pixels of space with which to inset the text
inside the image on the bottom side. This takes precedence over the margin attribute. The value -1 means this attribute is not
set. The style of the last character on all lines controls the bottom margin for the image (the largest bottom-margin on those
characters wins). |
| Type | number |
| Default | -1 |
| The number of pixels of space with which to inset the text
inside the image on the top side. This takes precedence over the margin attribute. The value -1 means this attribute is not
set. The style of the last character of the first line controls the top margin. |
| Type | number |
| Default | -1 |
| The thickness of the border, in pixels. The value -1 means
this attribute is not set. The border properties (thickness, colors) of the first character rendered control the border. |
| Type | number |
| Default | -1 |
| The border color. The value "" means this attribute is not
set. |
| Type | color |
| Default | "" |
| The border color on the left side. This takes precedence over
the borderColor attribute. The value "" means this attribute is not set. |
| Type | color |
| Default | "" |
| The border color on the right side. This takes precedence over
the borderColor attribute. The value "" means this attribute is not set. |
| Type | color |
| Default | "" |
| The border color on the bottom side. This takes precedence over
the borderColor attribute. The value "" means this attribute is not set. |
| Type | color |
| Default | "" |
| The border color on the top side. This takes precedence over
the borderColor attribute. The value "" means this attribute is not set. |
| Type | color |
| Default | "" |
The following style attributes allow styles to generate more sophisticated text-processing results, such as inserting bullets for
a list, or making hot links in the midst of the text. Examples are included to more clearly demonstrate how these features are
intended to be used.
| Additional content which should be prepended when a span starts using this
style. Note that this may itself contain style directives. |
| Type | string |
| Default | "" |
| Additional content which should be appended when a span stops using this
style. Note that this may itself contain style directives. |
| Type | string |
| Default | "" |
|
This example shows how to use contentPre, contentPost, margins and tabs, to produce bullet points with a hanging indent.
Style.BulletMark<<
.marginLeft=0
.color=red
.lineSpacing=10
>>
Style.Bullet<<
.marginLeft=15
.color=blue
.contentPre="%BulletMark{\u2022}\t"
.contentPost="\n"
>>
Image.BulletList<<
.tabStops=[15]
.wrapWidth=100
.text="%Bullet{The first bullet point is the most important}\
%Bullet{The second bullet point is also fairly important}\
%Bullet{The third bullet point is not at all important}"
>>
|
| When a style includes the area attribute, an instance of the indicated
class (which should be Area or a class derived from Area) will be created for
any identified span which appears within that style. A span is identified only if it, or an encapsulating span, uses
the :id syntax when the style is specified. If the span includes arguments, in the
form (args) then those will be passed to the area init method. If multiple spans occur within
the style (as could happen if the style used other style within it, or if word wrapping is enabled), then Area class
objects are created for all the subsequent spans, and the members of these area are rigged to work together with the main area class
object. |
| Type | string |
| Default | "" |
|
This example shows how to use styles to create hyperlinks within a text area.
Link.extends="Area"
Link.Class<<
.url=""
.target="_blank"
.init={$$.url=#arg}
.state={$$.hover?"h":"p"}
.boxPick=true
.new={
Trigger.$_h.test={$$.hover};
Trigger.$_h.exec={Meson.showStatus(^applet="Applet.Primary",^status=$$.url)};
Trigger.$_p.test={$$.press};
Trigger.$_p.exec={Meson.showDocument(^applet="Applet.Primary"
^url=$$.url,^target=$$.target)};
}
>>
Style.Link<<
_p.area="Link"
_p.textDecoration=_UNDERLINE
_p.color=blue
_h.textDecoration=_UNDERLINE
_h.color=red
>>
Image.Text<<
.states=["p","h"]
.wrapWidth=100
.text="This is some text containing \
%Link_#:Google(http://www.google.com'){a link that will wrap} \
to a site called %Link_#:Google{google} that you can use \
to search. Another %Link_#:Yahoo('http://www.yahoo.com'){site \
%Bold{that you}} can use is %Link_#:Yahoo{Yahoo}."
>>
The Link class extends area, and includes an init method, which receives the argument. When a Link is created, it creates two
triggers: one to show the URL on the status line when the mouse hovers, and the other to open the link when the mouse clicks.
Next, two styles are created: Link_p for plain links, and Link_h for hovering links. Only the first has an
area associated with it, using the Link class which was just defined. When the Link_p style is used, a corresponding Link object
will be created. Finally, an image is created which uses these styles. Note that only the first link encountered with a given
ID needs to include initializer arguments. Subsequent spans with the same ID (either implicitly created because of word wrap,
or explicitly created as in this example) have simple Area objects created which are rigged to mirror/control the Link object.
|
The following table shows the default style values.
Style.Default.fontFamily=[SansSerif]
Style.Default.fontSize=12
Style.Default.fontWeight=_PLAIN
Style.Default.fontStyle=_PLAIN
Style.Default.fontSmooth=-1
Style.Default.textAlign=_LEFT
Style.Default.textDecoration=_NONE
Style.Default.lineSpacing=0
Style.Default.margin=2
Style.Default.color=black
Style.Default.dropShadow=""
Style.Default.shadowOffset=1
Style.Default.borderThickness=0
Style.Default.borderColor=black
Style.Default.offsetX=0
Style.Default.offsetY=0
Style.Default.contentPre=""
Style.Default.contentPost=""
Style.Default.area=""
|
Scene Gluon
Scene Built-in Functions
Scene.setObjectWriteZAlpha(string scene, string object, boolean write) controls whether the indicated object writes into the Z-buffer when drawing with alpha. Ordinarily, this is true, but it might not be desired, for example, to allow picking through semi-transparent windows.
Scene.measure(string scene, number x0, number y0, number x1, number y1) returns the distance in native units between the two pixel locations.
Scene.pick(string scene, number x, number y) performs a pick operation under the indicated pixel location. If no pixel was drawn at that location, the return value is false. If a pixel was drawn, multiple return values can be fetched from the notebook: ^object
object ID, ^material material ID, ^x ^y ^z world coordinates location, ^lx ^ly ^lz local coordinates location.
Trigger.Pick.test={Area.3d.press}
Trigger.Pick.exec={Scene.pick(^scene="Scene.3d",^x=Scene.3d.mouseX,^y=Scene.3d.mouseY)?Meson.log("Picked obj:"~^object~" mat:"~^material);}
|
Scene Object Model
Class:
Scene (Extends Image)
A Scene is a rendered 3D environment. By default, the view of a scene can be manipulated using certain mouse gestures. However, the manner by which mouse gestures translate into view changes is entirely
programmed in the Meson language, and can therefore be overriden to use other interface approaches. The most direct way to override
the default behavior is to set the mode attribute of the scene to "" which will disable the
Anim object which updates the view. Then add new controller objects to manipulate the Scene's view as needed.
Scene adds the following attributes to the base Image class:
| Indicates the internal runtime representation of a 3D world which is rendered in this scene.
The runtime is created using a set of classes documented at the end of this section, and is typically generated automatically by
software. |
| Type | native |
| Indicates whether all the images used by textures have been loaded sufficiently to be
displayed. For streaming textures, more resolution will continue to load as data is received. |
| Type | boolean |
| Indicates that if the runtime associated with the scene is changed, the
textures used by the previous runtime should be cleared from memory. Restoring the previous runtime will therefore require
re-decoding of all texture information, so this mode sacrifices performance for memory conservation. Disabling
unloadRuntimes should only be done after a careful examination of memory requirements of the application. |
| Type | boolean |
| Default | true |
| The current major mode of the user interface (the thing that happens
when the mouse is dragged on the 3D area). |
| Type | enum
rotate, move, measure |
| Default | rotate |
| The scale to multiply native 3D distance values by in order to get Inches. |
| Type | number |
| Restrictions | Read Only |
| The scale to multiply native 3D distance values by in order to get centimeters. |
| Type | number |
| Restrictions | Read Only |
| The most recent measured distance. |
| Type | number |
| Restrictions | Read Only |
| The view definition to use when projecting 3D data into the image. |
| Type | string |
| Default | View.(scene name) |
| The minimum desirable frame rate. When the actual frame rate drops below this
value, various visual-quality-degrading optimizations are employed to improve the frame rate (not doing linear filtering, mipmapping, etc.). |
| Type | number |
| Default | 10 |
| Whether to perform incremental anti-aliasing passes when the scene is not
changing. |
| Type | boolean |
| Default | true |
| Whether to temporarily pause computation of
antialias image to improve responsiveness. |
| Type | boolean |
| Default | (true when mouse is pressed) |
| Whether to compute reduced-resolution versions of all file-derived textures in
the scene, in order to avoid aliasing artifacts when anti-aliasing is not being performed (such as when the object is moving). This
increases memory consumption by about 33%, so it should be turned off when exceptionally large scenes are being used. Since most Java
VMs will not allow applets to use more than 64MB, the memory limit for texture (assuming 16-bit depth) is less than 32 Mega-pixels
without mipmapping, and less than 24 Mega-pixels with mipmapping. Exactly how much less than these number will be available depends
on the 2D environment in which the 3D scene is placed (screen size, anti-aliasing used, other 2D images in the scene, etc.). |
| Type | boolean |
| Default | true |
| The amount by which to change theta as the mouse moves during
interactive rotation. |
| Type | number |
| Default | 360 / scene width |
| The amount by which to change phi as the mouse moves during
interactive rotation. |
| Type | number |
| Default | 180 / scene height |
| Turns on illustration rendering mode. |
| Type | boolean |
| Default | true |
| In illustration mode, controls the line thickness. |
| Type | number |
| Default | 1 |
| In illustration mode, controls the crease angle threshold used to detect where to draw lines. In degrees, in the range 0 to 90. |
| Type | number |
| Default | 15 |
| In illustration mode, controls the color of drawn lines. This may include an alpha component. |
| Type | color |
| Default | black |
| In illustration mode, controls the color of area fills. This may not include an alpha component. Set this to "" or clear to indicate that areas should be rendered in ordinary photorealistic style. |
| Type | color |
| Default | white |
Scene overrides these attributes:
| 3D Scenes are always rendered using alpha channels.
Change the background behind the scene by changing the parent image, or sibling images with lower layer values. |
| Type | color |
| Default | 0000 |
| Restrictions | Read Only |
| By default, the cursor used by a scene is dynamically set based on
the value of the mode attribute of the scene. |
| Type | string |
| Default | depends on mode |
Class:
HotSpot
A HotSpot is a 3D sphere in the scene which is projected into screen space each frame to allow connections between the 2D interface
elements (such as popup graphics) and points in 3D space. HotSpot objects are not created directly by Meson programs. Instead, the
program includes a HotSpotRT object which is associated with a 3D scene runtime. The Scene then creates a peer
HotSpot object for each HotSpotRT it finds, and fills it with projected information. This peer is named
HotSpot.(scene name)_(HotSpot RT name). For example, if a scene named Scene.3d finds a HotSpot
named HotSpotRT.hs1, it will create the object HotSpot.3d_hs1.
| The projected X image coordinate of the current location of the
hotspot. |
| Type | number |
| Restrictions | Read Only |
| The projected Y image coordinate of the current location of the
hotspot. |
| Type | number |
| Restrictions | Read Only |
| The distance between the viewer and the current location of the
hotspot. |
| Type | number |
| Restrictions | Read Only |
| The projected radius of the hotspot, in pixels. |
| Type | number |
| Restrictions | Read Only |
| Set to true if the closest part of the hotspot sphere is in front of
the 3D objects in the scene. |
| Type | boolean |
| Restrictions | Read Only |
| Indicates that the mouse is hovering over the hotspot. Note that
applications generally should not use this attribute directly, but rather should use the hover attribute. |
| Type | boolean |
| Indicates that the mouse is hovering over the hotspot. Note that the pixel under the mouse must
be drawn by this hotspot's Scene image in order to transition to hover=true. This defaults to an expression which
simply mirrors the mouseHover attribute, but can be modified to achieve more complex behaviors. |
| Type | boolean |
| Indicates that the left mouse button is pressed on the HotSpot. |
| Type | boolean |
| Restrictions | Read Only |
|
|