@c -*-texinfo-*-
@node AWS2 Native Objects, AWS2 Widget, AWS2 Quick Start, AWS2
@subsection Native @sc{aws2} Objects

Much like the DOM in your browser, @sc{aws2} has certain native language objects that help you get the job done.  These are
the lowest level objects in the system.  Some of them you may use directly, but generally you will not use them unless you
are writing a new Widget, or skinning an existing widget


@menu
@end menu

@node AWS2 Widget, AWS2 Pen, AWS2 Native Objects, AWS2
@subsection Widget object

The Widget object is the base for any widget that will be displayed on the screen,
or used as a container for other displayable widgets.  It has a number of methods
and properties, and is very likely the most complex object in the system.

Widgets that are not children, and that are not docked are top-level widgets.  
This means that they exist in a linked list that indicates their drawing level.  Currently
@sc{aws2} uses a focus-follows-mouse for widget activation/deactivation.

The following table summarizes all of the methods that are available for a widget.

@table @code
@item Move(x,y)
Move the widget @strong{relative} to x,y.

@item MoveTo(x,y)
Move the widget to @strong{absolute} position x,y.

@item Resize(width,height)
Resize the widget @strong{relative} to width,height.

@item ResizeTo(width,height)
Resize the widget to @strong{absolute} size width,height.

@item Invalidate()
Indicates the the state of this widget has changed, and on the next redraw it's @code{onRedraw} function will be called.

@item GetPen()
Gets the Pen object, if any, associated with this widget.

@item SetPen(pen)
Sets the Pen object to be associated with this widget.

@item AddChild(child, ...additional parms...)
Adds a widget as a child to this widget.  If any additional parameters are specified, they will be passed to the
onAddChild event that gets fired before this method completes.

@item RemoveChild(child, ...additional parms...)
Removes a widget as a child to this widget.  If any additional parameters are specified, they will be passed to the
onRemoveChild event that gets fired before this method completes.

@item Dock(sibling, position)
Docks a widget to the given position.  The position may be one of the DOCK_XXXX properties listed below.  Only
@strong{one} widget should be docked to any given position.  The sibling widget's frame will be resized and/or
moved in accordance with the frame that is being docked to.  Docking occurs in peer relationships, not parent/child.

@item Broadcast(signal_name)
This essential calls the function named by signal_name on all of the children of the given widget.  It does
@strong{not} propagate to grandchildren and below.

@item SetFrameAnchor(anchor_flags)
When a child widget sets this flag to any of the STICK_XXXX flags, the frame of the child will 
be resized and/or moved relative to the frame of the parent. You may bitwise-or the flags together to specify more than one.

@item ClearFrameAnchor(anchor_flags)
Clears the given STICK_XXXX flags.  You may bitwise-or the flags together to specify more than one.

@item SetMargin(size, where)
Creates a spacer, or margin, for docked or anchored widgets.  @code{size} pixels will be inserted between
the borders of the two widgets on the side indicated by @code{where}.

@item CaptureMouse()
Indicates that this widget wants all mouse events to come to it, irregardless of whether the mouse is over the
widget or not.  This is useful for dragging pieces of a widget around (like the slider and scrollbars knobs).

@item ReleaseMouse()
If the mouse has been captured, release it.

@item Show()
If a widget is invisible, make it visible.

@item Hide
If a widget is visible, make it invisible.

@end table

@node AWS2 Pen, AWS2 Texture, AWS2 Widget, AWS2
@subsection Pen object

The Pen object is used to draw.  It is vector based, so all drawing with the pen may be subject to transformations like scaling, translation, and rotation.

This object has a number of states that affect the output of the drawing.  These include the blending mode, the vertex color, the fill state, and the pen width.
Shapes are always specified using boxes (except for the triangle.)  The box is specified using: (xmin,ymin) - (xmax,ymax)

When drawing inside of a widget, (xmin,ymin) will always be equal to (0,0) and this (xmax,ymax) will be equal to (width,height).  You will see this paradigm
used over and over again in the default @sc{aws2} widget set.

@subsubsection Filling and Stroking

By default, all shapes are stroked.  In order to change this you must set the fill flag.

@example
pen.SetFlag(Pen.FLAG_FILL);
@end example

To reset the mode back to stroked mode, simply clear that flag.

@example
pen.ClearFlag(Pen.FLAG_FILL);
@end example

@subsubsection Texturing

Texturing is off by default.  In order to texture a shape you have to turn it on, and also set a texture.

@example
pen.SetFlag(Pen.FLAG_TEXTURE);
pen.SetTexture(my_tex);
@end example

To turn it back off, simply clear the flag.

@example
pen.ClearFlag(Pen.FLAG_TEXTURE);
@end example

It is very important to realize that the current color set will affect the texture.  For example, if you set the current color
to a bright white, the texture will be brighter than if you set it to black or a grey.  Setting the color to red will cause
the texture to have a reddish cast.  Setting the alpha component will make the texture more or less translucent.

What about texture coordinates?  All shapes are automatically textured.  The one exception is the triangle shape.  The Pen
object currently does not have a good way to specify texture coordinates for it.  This is likely to be corrected in the future.

For any given shape, the texture coordinates will be (0,0) at (xmin, ymin) and (1,1) at (xmax,ymax).  It is important to realize that 
this works great for texturing an entire widget.  However, if you which to texture sub-shapes within a widget, you must modify the 
transformation matrix so that texture coordinates will be properly generated.

Imagine that you have a widget that is 50 x 50 pixels.  Assume that you have a small knob, that is 10 x 10 pixels, and you wish to
texture it differently than the rest of the widget.  Note that it may also move around inside the widget.  The easiest way to do that
is by:

@example

pen.PushTransform();
pen.Translate(knob_x, knob_y, 0);

pen.SetFlag(Pen.FLAG_TEXTURE);
pen.SetTexture(my_tex);

pen.DrawRect(0,0,10,10);

pen.PopTransform();
@end example

This will normalize the coordinates of your shape and allow the pen to create correct texture coordinates for it.

@subsubsection Blending

There are two parts of blending to consider.  The first is the simplest, and involves alpha values in your color.  

@example
pen.SetColor(1,1,1,1);
@end example

This statement would set the color to a completely opaque white.

@example
pen.SetColor(1,1,1,0.5);
@end example

Whereas this one would set the color to a shade that is 50% transparent.  It is easy to see how this works, in that the transparency is a 
number from 0 to 1, where 0 is completely transparent, and 1 is completely opaque.

There is a more sophisticated sort of blending that Pen can also perform.  This is referred to more generally as @emph{compositing}.

@table @code

@item SetMixMode(mixmode_constant)
Set the blending mode used for further drawing to one of the Pen.MIX_XXX constants.  

@item SetMixMode(mixmode_object)
Set the blending mode used for further drawing by generating it from a Mixmode object
that allows you to specify any of the source and destination blending operations CS
supports.

@end table

The constants that can be used for blending are as follows:

@table @code

@item MIX_ADD
The source color and destination colors are added together.

@item MIX_ALPHA 
The source and destination colors are blended using the alpha value.

@item MIX_COPY
The destination color is overwritten by the source color. (No blending).

@item MIX_DST_ALPHA_ADD
The source color is multiplied by the alpha component of the destination color
and the result is added together.

@item MIX_FLAT
No shading is implemented for vertex colors.

@item MIX_MULTIPLY
To do

@item MIX_MULTIPLY2
To do

@item MIX_PRE_MULT_ALPHA
To do

@item MIX_SRC_ALPHA_ADD
To do

@item MIX_TRANSPARENT
To do
 
@item MIX_TRANSPARENT_TEST
To do
  
@item MIX_DST_ALPHA
Like MIX_DST_ALPHA_ADD, but the results are blended not added.

@item MIX_DST_ALPHA_MASK
To do

@end table

In order to do masking, for example, you might set the pen state like this:

@example
pen.SetMixMode(Pen.MIX_COPY);
pen.SetColor(1,1,1,1);
pen.DrawTriangle(5,0,10,10,0,10);

pen.SetMixMode(Pen.MIX_DST_ALPHA_ADD);
pen.SetFlag(Pen.FLAG_TEXTURE);
pen.SetTexture(my_tex);
pen.DrawRect(0,0,20,20);
@end example

The texture will only be drawn where the triangle was drawn.  The area around the triangle will be left clean.

Blending allows you to do a number of interesting special effects, including highlighting and complex texturing.  For an example of the use of blending 
see @file{data/aws/widgets/slider.js}

@subsubsection Pen Flags

@table @code
  
@item FLAG_FILL
Turns on shape filling.  When this is off, all shapes are stroked.
  
@item FLAG_SWAPCOLORS
Most shapes support color swapping.  This can be used to make simple gradients, or to draw a simple "3d" box look.

@item FLAG_TEXTURE
Turns on texturing.  You must also specify a texture using @code{SetTexture} in order for this flag to have effect.

@end table

@subsubsection Pen Text Drawing and Alignment

The pen is capable of aligning text inside of a box, without the user having to do all sorts of complex operations.  This makes text positioning
much easier to perform.

The following constants may be used to align text.

@table @code

@item ALIGN_TOP
Align text vertically to the top of the box.  The top of the text will touch the top of the box.

@item ALIGN_BOT
Align text vertically to the bottom of the box.  The bottom of the text will touch the bottom of the box.

@item ALIGN_LEFT
Align text horizontally to the left-hand side of the box.  The left edge of the text will touch the left side of the box.

@item ALIGN_RIGHT
Align text horizontally to the right-hand side of the box.  The right edge of the text will touch the right side of the box.

@item ALIGN_CENTER
Align text horizontally or vertically to the center of the box.  The center of the text
will be in the center of the box.

@end table

@subsubsection Pen methods


The following table summarizes all of the drawing functions available via Pen.

@table @code

@item Clear()
Clears a pen.  All previous drawing functions are removed.

@item SetFlag(flag_const)
Sets one or more Pen.FLAG_XXXX constants.

@item ClearFlag(flag_const)
Clears one or more Pen.FLAG_XXXX constants.

@item SetMixMode(mixmod_const)
Sets the blending mode to the given Pen.MIX_XXXX constant.

@item SetMixMode(mixmod_object)
Sets the blending mode to the given blending object.

@item SetColor(r,g,b,a)
Sets the color of the pen to the value specified by r,g,b,a

@item SetColor(color_object)
Sets the color of the pen to the value specified by the Color object.

@item SetTexture(tex)
Sets the current texture to tex.

@item SwapColors()
Swaps the current color with the alternate color.  SetColor sets the current
color, and drawing is always done in the current color.  However, sometimes
you want to swap between two colors frequently, and this provides an optimized
way to do so.

@item SetWidth(pen_width)
Sets the width of the stroke when drawing a stroked shape.  This number is in pixels
and may be fractional.

@item PushTransform()
Pushes the current transformation onto the stack.

@item PopTransform()
Pops the last saved transformation from the stack and makes it the current one.

@item ClearTransform()
Clear all transformations.  Sets the transformation matrix to the identity.

@item SetOrigin(x,y,z)
Sets the origin for the transformation matrix.  This helps with rotating objects
around a certain point.

@item Translate(x,y,z)
Translate the transformation matrix by x,y,z.

@item Rotate(radians)
Rotate the transformation matrix by radians.

@item DrawLine(xmin, ymin, xmax, ymax)
Draw a line from (xmin,ymin) to (xmax,ymax)

@item DrawRect(xmin, ymin, xmax, ymax)
Draw a rectangle from (xmin,ymin) to (xmax,ymax)


@item DrawMiteredRect(xmin, ymin, xmax, ymax, miter_in_pixels)
Draw a rectangle from (xmin,ymin) to (xmax,ymax), beveling the edges
by miter_in_pixels.  That is, the corners will be cut off at 
miter_in_pixels from @emph{each} edge.

@item DrawRoundedRect(xmin, ymin, xmax, ymax, roundness_in_pixels)
Draw a rectangle from (xmin,ymin) to (xmax,ymax), rounding the edges
by roundness_in_pixels.  That is, the corners will be cut off at 
roundness_in_pixels from @emph{each} edge, and an arc will be drawn
instead.

@item DrawArc(xmin, ymin, xmax, ymax, start_angle, end_angle)
Draw an arc that fills the box specified the rectangle 
(xmin,ymin) to (xmax,ymax).  The left and right edges will touch
xmin and xmax, while the top and bottom edges will touch ymin and
ymax.  The arc will be drawn from start_angle to end_angle.  To
draw a circle, start_angle should be 0, and end angle should be
slightly over PI*2.

@item DrawTriangle(x1, y2, x2, y2, x3, y3)
Draw a triangle connecting those points.  The points must be given in
clockwise order if you want the triangle filled.

@item Draw(pen)
Appends all of the draw operations performed on this pen, to the given
pen.

@item Render(texture)
Renders the pen to a texture.  In this way you can essentially create
procedural textures.  If the texture has any contents, they will be
cleared by this operation.  If you want to draw multiple objects onto
a texture, use the same pen, concatenate multiple pens into one pen,
or use compositing.

@item Write(font, x, y, text)
Write the text in the given font at coordinate x,y.

@item WriteBoxed(font, xmin, ymin, xmax, ymax, horizontal_alignment, vertical_alignment, text)
Write the text in the given font inside the box (xmin,ymin) - (xmax,ymax).  The text will
be aligned to the box using the Pen.ALIGN_XXXX constants.

@end table

@node AWS2 Texture, AWS2 Color, AWS2 Pen, AWS2
@subsection Texture object

The texture objects holds a @sc{cs} iTextureHandle.  The only things you can do with a Texture object are
Create and Load.  The system takes care of destroying them.  You may use a Pen to draw on them, or a Gradient
to render to them but that is outside the scope of the texture object itself.

The following static methods are available with Texture.

@table @code

@item Create(width,height)
Create a new, blank texture widthxheight pixels in area.

@item Load(filename)
Load any image that @sc{cs} supports as a texture.  The filename must
include the @sc{vfs} path of course.

@end table

To create a procedural texture:

@example
my_tex = Texture.Create(10,10);
@end example

To load an image as a texture:

@example
my_tex = Texture.Load("/path/to/image.png");
@end example

You may also retrieve the size of texture object by using the @code{GetDimensions} method.

@table @code

@item GetDimensions()
Returns a TextureDimensions object containing the width and height of the texture.

@end table

@example
dim = my_tex.GetDimensions()

Sys.Print("Texture width: ", dim.width, " Texture height: ", dim.height);
@end example

@node AWS2 Color, AWS2 Font, AWS2 Texture, AWS2
@subsection Color object

Allows you to create an encapsulation of a color. Color components may range from 0.0 to 1.0, where
the 0 is no intensity and 1 is full intensity of that component.

@table @code

@item constructor: new Color(r,g,b,a)
Set the color components and return a new Color object.

@item Set(r,g,b,a)
Set the color components.

@end table

An example of creating a new Color object:

@example
my_color = new Color(1,0.5,1,0.5);
@end example

You can also access the components of a Color object through it's properties.

@table @code

@item r
Return the red component.

@item g
Return the green component.

@item b
Return the blue component.

@item alpha
Return the alpha component.

@end table

@node AWS2 Font, AWS2 Gradient, AWS2 Color, AWS2
@subsection Font object

The Font object is used for representing a font to the drawing system.  You may Load fonts, and query them
for specific information such as their height, the height and width of a given piece of text in that font, 
and more.

The following static functions are available:

@table @code

@item Load(font_path, size)
This returns a new font object.  You must specify the path to the font, as well as the size of
the font you wish to load.  If the font cannot be found, the function will fail.

@end table

@example
my_font = new Font("VeraSans", 24);
another_font = Font.Load("VeraSerif", 10);
@end example

Once you have a font object, you may use it in drawing text with a pen, or you may also query it for
various bits of information.

@table @code

@item GetTextHeight()
Returns the line to line height for a font.  This is useful for determining how far to increment the
@code{y} coordinate for drawing text.

@item GetLength(text, max_width)
Returns an integer that is an index into text, indicating the last character that should be 
displayed to make sure that the text is no more than @code{max_width} pixels wide.

@item GetDimensions(text)
Returns a TextDimensions object indicating the width, maximum height, and descender of the 
given text.

@end table

@example
dim = my_font.GetDimensions("my text");

Sys.Print("Dimensions of text: ", dim.width, dim.height, dim.descender);
@end example

@node AWS2 Gradient, AWS2 XML Interface Reference, AWS2 Font, AWS2
@subsection Gradient object

The Gradient object lets you make some fairly sophisticated gradients.  These can then 
be used to texture a widget, or a part of a widget using masking.  There are currently
only five different kinds of gradients supported.  Also, it should be realized that 
using a gradient is more of an art than a science.  Things can get complex in a hurry.

The basic pattern behind using a gradient is to create a new Gradient object, and then
add colors to it.

@example
gr = new Gradient();
    			
gr.AddColor(new Color(1,1,1,1), 0.0);	
gr.AddColor(new Color(1,1,1,1), 0.1);	
gr.AddColor(new Color(0.6,0.6,0.6,1), 0.5);					
gr.AddColor(new Color(0.4,0.4,0.4,1), 0.51);				
gr.AddColor(new Color(0.7, 0.7, 0.7, 1), 0.9);
gr.AddColor(new Color(0.0, 0.0, 0.0, 1), 1.0);
@end example

Once you are done creating your gradient, it has to be rendered into a texture to actually be useful.

@example
gr.Render(tex, Gradient.VERTICAL);
@end example

For horizontal and vertical gradients, it's best to create a texture that is 1 pixel wide and N pixels high, or vice versa, and then using
that to texture your shape.  Other gradients require you to create a full width and height texture.

The following table lists all possible gradient types:

@table @code

@item HORIZONTAL
The gradient starts at the left and runs to the right.

@item VERTICAL
The gradient starts at the top and runs to the bottom.

@item RADIAL
The gradient starts in the center and runs to the edges in all directions.

@item LDIAG
The gradient starts in the upper left corner and runs to the bottom right corner.

@item RDIAG
The gradient starts in the upper right corner and runs to the bottom left corner.

@end table

The following methods are supported:

@table @code

@item AddColor(color_object, position)
Adds the given color at the given position.  The position must be between 0.0 and 1.0.  Colors
will be sorted automatically, so they don't have to be added in order.

@item Render(texture, gradient_constant)
Renders the gradient to the given Texture object.  Whatever was in the texture is overwritten.

@end table
