http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicShape.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicShape.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicShape.as new file mode 100644 index 0000000..7e0391e --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicShape.as @@ -0,0 +1,213 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.geom.Point; + import flash.geom.Rectangle; + } + COMPILE::JS + { + import org.apache.flex.core.WrappedHTMLElement; + } + + import org.apache.flex.core.UIBase; + + public class GraphicShape extends UIBase + { + private var _fill:IFill; + private var _stroke:IStroke; + + public function get stroke():IStroke + { + return _stroke; + } + + /** + * A solid color fill. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion FlexJS 0.0 + */ + public function set stroke(value:IStroke):void + { + _stroke = value; + } + + public function get fill():IFill + { + return _fill; + } + /** + * A solid color fill. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion FlexJS 0.0 + */ + public function set fill(value:IFill):void + { + _fill = value; + } + + /** + * Constructor + * + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function GraphicShape() + { + COMPILE::JS + { + element = document.createElementNS('http://www.w3.org/2000/svg', 'svg') as WrappedHTMLElement; + element.flexjs_wrapper = this; + element.style.left = 0; + element.style.top = 0; + //element.offsetParent = null; + positioner = element; + positioner.style.position = 'relative'; + } + } + + COMPILE::AS3 + protected function applyStroke():void + { + if(stroke) + { + stroke.apply(this); + } + } + + COMPILE::AS3 + protected function beginFill(targetBounds:Rectangle,targetOrigin:Point):void + { + if(fill) + { + fill.begin(this, targetBounds,targetOrigin); + } + } + + COMPILE::AS3 + protected function endFill():void + { + if(fill) + { + fill.end(this); + } + } + + /** + * This is where the drawing methods get called from + */ + protected function draw():void + { + //Overwrite in subclass + } + + override public function addedToParent():void + { + COMPILE::AS3 + { + super.addedToParent(); + } + draw(); + COMPILE::JS + { + element.style.overflow = 'visible'; + } + } + + /** + * @return {string} The style attribute. + */ + COMPILE::JS + public function getStyleStr():String + { + var fillStr:String; + if (fill) + { + fillStr = fill.addFillAttrib(this); + } + else + { + fillStr = 'fill:none'; + } + + var strokeStr:String; + if (stroke) + { + strokeStr = stroke.addStrokeAttrib(this); + } + else + { + strokeStr = 'stroke:none'; + } + + + return fillStr + ';' + strokeStr; + } + + + /** + * @param x X position. + * @param y Y position. + * @param bbox The bounding box of the svg element. + */ + COMPILE::JS + public function resize(x:Number, y:Number, bbox:SVGRect):void + { + var useWidth:Number = Math.max(this.width, bbox.width); + var useHeight:Number = Math.max(this.height, bbox.height); + + element.style.position = 'absolute'; + if (!isNaN(x)) element.style.top = String(x) + 'px'; + if (!isNaN(y)) element.style.left = String(y) + 'px'; + element.style.width = String(useWidth) + 'px'; + element.style.height = String(useHeight) + 'px'; + element.style.left = x; + element.style.top = y; + } + + COMPILE::JS + private var _x:Number; + COMPILE::JS + private var _y:Number; + COMPILE::JS + private var _xOffset:Number; + COMPILE::JS + private var _yOffset:Number; + + /** + * @param x X position. + * @param y Y position. + * @param xOffset offset from x position. + * @param yOffset offset from y position. + */ + COMPILE::JS + public function setPosition(x:Number, y:Number, xOffset:Number, yOffset:Number):void + { + _x = x; + _y = y; + _xOffset = xOffset; + _yOffset = yOffset; + element.style.left = xOffset; + element.style.top = yOffset; + } + } +}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicsContainer.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicsContainer.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicsContainer.as new file mode 100644 index 0000000..4927eb9 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/GraphicsContainer.as @@ -0,0 +1,302 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.display.GraphicsPath; + import flash.display.Shape; + import flash.display.Sprite; + import flash.geom.Point; + import flash.geom.Rectangle; + import flash.text.TextFieldType; + + import org.apache.flex.core.CSSTextField; + } + COMPILE::JS + { + import org.apache.flex.core.WrappedHTMLElement; + } + import org.apache.flex.core.graphics.utils.PathHelper; + + /** + * GraphicsContainer is a surface on which you can + * draw various graphic elements such as Rect, Circle, + * Ellipse, Path etc. + * Use this class if you want to draw multiple graphic + * shapes on a single container. + * + */ + public class GraphicsContainer extends GraphicShape + { + /** + * Removes all of the drawn elements of the container. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0.3 + */ + public function removeAllElements():void + { + COMPILE::AS3 + { + graphics.clear(); + } + COMPILE::JS + { + var svg:HTMLElement = element; + while (svg.lastChild) { + svg.removeChild(svg.lastChild); + } + } + } + + /** + * Draw the rectangle. + * @param x The x position of the top-left corner of the rectangle. + * @param y The y position of the top-left corner. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0.3 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawRect(x:Number, y:Number, width:Number, height:Number):void + { + COMPILE::AS3 + { + applyStroke(); + beginFill(new Rectangle(x, y, width, height), new Point(x,y) ); + graphics.drawRect(x, y, width, height); + endFill(); + } + COMPILE::JS + { + var style:String = getStyleStr(); + var rect:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect') as WrappedHTMLElement; + rect.flexjs_wrapper = this; + rect.style.left = x; + rect.style.top = y; + rect.setAttribute('style', style); + rect.setAttribute('x', String(x) + 'px'); + rect.setAttribute('y', String(y) + 'px'); + rect.setAttribute('width', String(width) + 'px'); + rect.setAttribute('height', String(height) + 'px'); + element.appendChild(rect); + } + } + + COMPILE::AS3 + public function createRect(x:Number, y:Number, width:Number, height:Number):void + { + var color:uint = (fill as SolidColor).color; + var alpha:uint = (fill as SolidColor).alpha; + + var shape:Sprite = new Sprite(); + shape.graphics.beginFill(color,alpha); + shape.graphics.drawRect(0, 0, width, height); + shape.graphics.endFill(); + shape.x = x; + shape.y = y; + addChild(shape); + } + + /** + * Draw the ellipse. + * @param x The x position of the top-left corner of the bounding box of the ellipse. + * @param y The y position of the top-left corner of the bounding box of the ellipse. + * @param width The width of the ellipse. + * @param height The height of the ellipse. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0.3 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawEllipse(x:Number, y:Number, width:Number, height:Number):void + { + COMPILE::AS3 + { + applyStroke(); + beginFill(new Rectangle(x,y,width,height), new Point(x,y)); + graphics.drawEllipse(x,y,width,height); + endFill(); + } + COMPILE::JS + { + var style:String = getStyleStr(); + var ellipse:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse') as WrappedHTMLElement; + ellipse.flexjs_wrapper = this; + ellipse.style.left = x; + ellipse.style.top = y; + ellipse.setAttribute('style', style); + ellipse.setAttribute('cx', String(x + width / 2)); + ellipse.setAttribute('cy', String(y + height / 2)); + ellipse.setAttribute('rx', String(width / 2)); + ellipse.setAttribute('ry', String(height / 2)); + element.appendChild(ellipse); + } + } + + /** + * Draw the circle. + * @param x The x location of the center of the circle + * @param y The y location of the center of the circle. + * @param radius The radius of the circle. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawCircle(x:Number, y:Number, radius:Number):void + { + COMPILE::AS3 + { + applyStroke(); + beginFill(new Rectangle(x,y,radius*2, radius*2),new Point(x-radius,y-radius)); + graphics.drawCircle(x,y,radius); + endFill(); + } + COMPILE::JS + { + var style:String = getStyleStr(); + var circle:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse') as WrappedHTMLElement; + circle.flexjs_wrapper = this; + circle.style.left = x; + circle.style.top = y; + circle.setAttribute('style', style); + circle.setAttribute('cx', String(x)); + circle.setAttribute('cy', String(y)); + circle.setAttribute('rx', String(radius)); + circle.setAttribute('ry', String(radius)); + element.appendChild(circle); + + } + } + + /** + * Draw the path. + * @param data A string containing a compact represention of the path segments. + * The value is a space-delimited string describing each path segment. Each + * segment entry has a single character which denotes the segment type and + * two or more segment parameters. + * + * If the segment command is upper-case, the parameters are absolute values. + * If the segment command is lower-case, the parameters are relative values. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawPath(data:String):void + { + COMPILE::AS3 + { + applyStroke(); + var bounds:Rectangle = PathHelper.getBounds(data); + beginFill(bounds,bounds.topLeft); + var graphicsPath:GraphicsPath = PathHelper.getSegments(data); + graphics.drawPath(graphicsPath.commands, graphicsPath.data); + endFill(); + } + COMPILE::JS + { + var style:String = getStyleStr(); + var path:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'path') as WrappedHTMLElement; + path.flexjs_wrapper = this; + path.style.left = 0; + path.style.top = 0; + path.setAttribute('style', style); + path.setAttribute('d', data); + element.appendChild(path); + } + } + + public function drawLine():void + { + + } + + public function drawPolygon():void + { + + } + + /** + * Draw a string of characters. + * @param value The string to draw. + * @param x The x location of the center of the circle + * @param y The y location of the center of the circle. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + * @flexjsignorecoercion Text + * @flexjsignorecoercion Node + */ + public function drawText(value:String, x:Number, y:Number):Object + { + COMPILE::AS3 + { + var textField:CSSTextField = new CSSTextField(); + addChild(textField); + + textField.selectable = false; + textField.type = TextFieldType.DYNAMIC; + textField.mouseEnabled = false; + textField.autoSize = "left"; + textField.text = value; + + var lineColor:SolidColorStroke = stroke as SolidColorStroke; + if (lineColor) { + textField.textColor = lineColor.color; + textField.alpha = lineColor.alpha; + } + + textField.x = x; + textField.y = y + textField.textHeight/4; + + return textField; + + } + COMPILE::JS + { + var style:String = getStyleStr(); + var text:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'text') as WrappedHTMLElement; + text.flexjs_wrapper = this; + text.style.left = x; + text.style.top = y; + text.setAttribute('style', style); + text.setAttribute('x', String(x) + 'px'); + text.setAttribute('y', String(y + 15) + 'px'); + var textNode:Text = document.createTextNode(value) as Text; + text.appendChild(textNode as Node); + element.appendChild(text); + return text; + } + } + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IFill.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IFill.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IFill.as new file mode 100644 index 0000000..f0101ab --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IFill.as @@ -0,0 +1,32 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.geom.Point; + import flash.geom.Rectangle; + } + + public interface IFill + { + COMPILE::AS3 + function begin(s:GraphicShape,targetBounds:Rectangle, targetOrigin:Point):void; + COMPILE::AS3 + function end(s:GraphicShape):void; + COMPILE::JS + function addFillAttrib(s:GraphicShape):String; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IStroke.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IStroke.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IStroke.as new file mode 100644 index 0000000..be3f022 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/IStroke.as @@ -0,0 +1,29 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + public interface IStroke + { + COMPILE::AS3 + function apply(s:GraphicShape):void; + + COMPILE::JS + function get weight():Number; + + COMPILE::JS + function addStrokeAttrib(s:GraphicShape):String; + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/LinearGradient.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/LinearGradient.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/LinearGradient.as new file mode 100644 index 0000000..c36a37b --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/LinearGradient.as @@ -0,0 +1,123 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.display.GradientType; + import flash.display.InterpolationMethod; + import flash.display.SpreadMethod; + import flash.geom.Matrix; + import flash.geom.Point; + import flash.geom.Rectangle; + } + + public class LinearGradient extends GradientBase implements IFill + { + COMPILE::AS3 + private static var commonMatrix:Matrix = new Matrix(); + + private var _scaleX:Number; + + /** + * The horizontal scale of the gradient transform, which defines the width of the (unrotated) gradient + */ + public function get scaleX():Number + { + return _scaleX; + } + + public function set scaleX(value:Number):void + { + _scaleX = value; + } + + COMPILE::AS3 + public function begin(s:GraphicShape,targetBounds:Rectangle, targetOrigin:Point):void + { + commonMatrix.identity(); + commonMatrix.createGradientBox(targetBounds.width,targetBounds.height,toRad(this.rotation),targetOrigin.x, targetOrigin.y); + + s.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, + commonMatrix, SpreadMethod.PAD, InterpolationMethod.RGB); + + } + + COMPILE::AS3 + public function end(s:GraphicShape):void + { + s.graphics.endFill(); + } + + /** + * addFillAttrib() + * + * @param value The GraphicShape object on which the fill must be added. + * @return {string} + * @flexjsignorecoercion Node + */ + COMPILE::JS + public function addFillAttrib(value:GraphicShape):String + { + //Create and add a linear gradient def + var svgNS:String = value.element.namespaceURI; + var grad:HTMLElement = document.createElementNS(svgNS, 'linearGradient') as HTMLElement; + var gradientId:String = this.newId; + grad.setAttribute('id', gradientId); + + //Set x1, y1, x2, y2 of gradient + grad.setAttribute('x1', '0%'); + grad.setAttribute('y1', '0%'); + grad.setAttribute('x2', '100%'); + grad.setAttribute('y2', '0%'); + + //Apply rotation to the gradient if rotation is a number + if (rotation) + { + grad.setAttribute('gradientTransform', 'rotate(' + rotation + ' 0.5 0.5)'); + } + + //Process gradient entries and create a stop for each entry + var entries:Array = this.entries; + for (var i:int = 0; i < entries.length; i++) + { + var gradientEntry:GradientEntry = entries[i]; + var stop:HTMLElement = document.createElementNS(svgNS, 'stop') as HTMLElement; + //Set Offset + stop.setAttribute('offset', String(gradientEntry.ratio * 100) + '%'); + //Set Color + var color:String = Number(gradientEntry.color).toString(16); + if (color.length == 1) color = '00' + color; + if (color.length == 2) color = '00' + color; + if (color.length == 4) color = '00' + color; + stop.setAttribute('stop-color', '#' + String(color)); + //Set Alpha + stop.setAttribute('stop-opacity', String(gradientEntry.alpha)); + + grad.appendChild(stop); + } + + //Add defs element if not available already + //Add newly created gradient to defs element + var defs:Node = value.element.querySelector('defs') || + value.element.insertBefore(document.createElementNS(svgNS, 'defs'), value.element.firstChild); + defs.appendChild(grad); + + //Return the fill attribute + return 'fill:url(#' + gradientId + ')'; + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Path.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Path.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Path.as new file mode 100644 index 0000000..2d69364 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Path.as @@ -0,0 +1,103 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.display.GraphicsPath; + import flash.geom.Point; + import flash.geom.Rectangle; + } + COMPILE::JS + { + import org.apache.flex.core.WrappedHTMLElement; + } + + import org.apache.flex.core.graphics.utils.PathHelper; + + public class Path extends GraphicShape + { + + private var _data:String; + + public function get data():String + { + return _data; + } + + public function set data(value:String):void + { + _data = value; + } + + /** + * Draw the path. + * @param data A string containing a compact represention of the path segments. + * The value is a space-delimited string describing each path segment. Each + * segment entry has a single character which denotes the segment type and + * two or more segment parameters. + * + * If the segment command is upper-case, the parameters are absolute values. + * If the segment command is lower-case, the parameters are relative values. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawPath(x:Number,y:Number,data:String):void + { + COMPILE::AS3 + { + graphics.clear(); + applyStroke(); + var bounds:Rectangle = PathHelper.getBounds(data); + this.width = bounds.width; + this.height = bounds.height; + beginFill(bounds,new Point(bounds.left + x, bounds.top + y) ); + var graphicsPath:GraphicsPath = PathHelper.getSegments(data,x,y); + graphics.drawPath(graphicsPath.commands, graphicsPath.data); + endFill(); + } + COMPILE::JS + { + if (data == null || data.length === 0) return; + var style:String = getStyleStr(); + var path:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'path') as WrappedHTMLElement; + path.flexjs_wrapper = this; + path.setAttribute('style', style); + path.setAttribute('d', data); + element.appendChild(path); + if (stroke) + { + setPosition(x, y, stroke.weight, stroke.weight); + } + else + { + setPosition(x, y, 0, 0); + } + + resize(x, y, path['getBBox']()); + + } + } + + override protected function draw():void + { + drawPath(0, 0, data); + } + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Rect.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Rect.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Rect.as new file mode 100644 index 0000000..fd1daa8 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Rect.as @@ -0,0 +1,87 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.display.CapsStyle; + import flash.display.JointStyle; + import flash.geom.Point; + import flash.geom.Rectangle; + } + COMPILE::JS + { + import org.apache.flex.core.WrappedHTMLElement; + } + + public class Rect extends GraphicShape + { + + /** + * Draw the rectangle. + * @param x The x position of the top-left corner of the rectangle. + * @param y The y position of the top-left corner. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + */ + public function drawRect(x:Number, y:Number, width:Number, height:Number):void + { + COMPILE::AS3 + { + graphics.clear(); + applyStroke(); + beginFill(new Rectangle(x, y, width, height), new Point(x,y)); + graphics.drawRect(x, y, width, height); + endFill(); + } + COMPILE::JS + { + var style:String = this.getStyleStr(); + var rect:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect') as WrappedHTMLElement; + rect.flexjs_wrapper = this; + rect.setAttribute('style', style); + if (stroke) + { + rect.setAttribute('x', String(stroke.weight / 2) + 'px'); + rect.setAttribute('y', String(stroke.weight / 2) + 'px'); + setPosition(x, y, stroke.weight, stroke.weight); + } + else + { + rect.setAttribute('x', '0' + 'px'); + rect.setAttribute('y', '0' + 'px'); + setPosition(x, y, 0, 0); + } + rect.setAttribute('width', String(width) + 'px'); + rect.setAttribute('height', String(height) + 'px'); + element.appendChild(rect); + + resize(x, y, rect['getBBox']()); + } + } + + override protected function draw():void + { + drawRect(0,0,width,height); + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColor.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColor.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColor.as new file mode 100644 index 0000000..73e99b0 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColor.as @@ -0,0 +1,112 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.geom.Point; + import flash.geom.Rectangle; + } + + public class SolidColor implements IFill + { + + //---------------------------------- + // alpha + //---------------------------------- + + private var _alpha:Number = 1.0; + //---------------------------------- + // color + //---------------------------------- + + private var _color:uint = 0x000000; + + /** + * The transparency of a color. + * Possible values are 0.0 (invisible) through 1.0 (opaque). + * + * @default 1.0 + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.3 + */ + public function get alpha():Number + { + return _alpha; + } + + public function set alpha(value:Number):void + { + var oldValue:Number = _alpha; + if (value != oldValue) + { + _alpha = value; + } + } + + /** + * A color value. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion FlexJS 0.3 + */ + public function get color():uint + { + return _color; + } + + public function set color(value:uint):void + { + var oldValue:uint = _color; + if (value != oldValue) + { + _color = value; + } + } + + COMPILE::AS3 + public function begin(s:GraphicShape,targetBounds:Rectangle,targetOrigin:Point):void + { + s.graphics.beginFill(color,alpha); + } + + COMPILE::AS3 + public function end(s:GraphicShape):void + { + s.graphics.endFill(); + } + + /** + * addFillAttrib() + * + * @param value The GraphicShape object on which the fill must be added. + * @return {string} + */ + COMPILE::JS + public function addFillAttrib(value:GraphicShape):String + { + var color:String = Number(this.color).toString(16); + if (color.length == 1) color = '00' + color; + if (color.length == 2) color = '00' + color; + if (color.length == 4) color = '00' + color; + return 'fill:#' + String(color) + ';fill-opacity:' + String(alpha); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColorStroke.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColorStroke.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColorStroke.as new file mode 100644 index 0000000..9535cdc --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/SolidColorStroke.as @@ -0,0 +1,130 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.display.CapsStyle; + import flash.display.JointStyle; + } + + public class SolidColorStroke implements IStroke + { + + //---------------------------------- + // alpha + //---------------------------------- + private var _alpha:Number = 1.0; + + //---------------------------------- + // color + //---------------------------------- + private var _color:uint = 0x000000; + + //---------------------------------- + // weight + //---------------------------------- + private var _weight:Number = 1; + + /** + * The transparency of a color. + * Possible values are 0.0 (invisible) through 1.0 (opaque). + * + * @default 1.0 + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.3 + */ + public function get alpha():Number + { + return _alpha; + } + + public function set alpha(value:Number):void + { + var oldValue:Number = _alpha; + if (value != oldValue) + { + _alpha = value; + } + } + + /** + * A color value. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion FlexJS 0.3 + */ + public function get color():uint + { + return _color; + } + + public function set color(value:uint):void + { + var oldValue:uint = _color; + if (value != oldValue) + { + _color = value; + } + } + + public function get weight():Number + { + return _weight; + } + + /** + * A color value. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion FlexJS 0.3 + */ + public function set weight(value:Number):void + { + _weight = value; + } + + COMPILE::AS3 + public function apply(s:GraphicShape):void + { + s.graphics.lineStyle(weight,color,alpha,false,"normal",CapsStyle.SQUARE,JointStyle.MITER); + } + + /** + * addStrokeAttrib() + * + * @param value The GraphicShape object on which the stroke must be added. + * @return {string} + */ + COMPILE::JS + public function addStrokeAttrib(value:GraphicShape):String + { + var strokeColor:String = Number(color).toString(16); + if (strokeColor.length == 1) strokeColor = '00' + strokeColor; + if (strokeColor.length == 2) strokeColor = '00' + strokeColor; + if (strokeColor.length == 4) strokeColor = '00' + strokeColor; + return 'stroke:#' + String(strokeColor) + ';stroke-width:' + + String(weight) + ';stroke-opacity:' + String(alpha); + }; + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Text.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Text.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Text.as new file mode 100644 index 0000000..24dd840 --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/Text.as @@ -0,0 +1,140 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.core.graphics +{ + COMPILE::AS3 + { + import flash.text.TextFieldType; + import org.apache.flex.core.CSSTextField; + } + COMPILE::JS + { + import org.apache.flex.core.WrappedHTMLElement; + } + + /** + * Draws a string of characters at a specific location using the stroke + * value of color and alpha. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * // TODO (aharui) ignore imports of external linkage interfaces? + * @flexjsignoreimport SVGLocatable + */ + public class Text extends GraphicShape + { + /** + * constructor. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + */ + public function Text() + { + super(); + + COMPILE::AS3 + { + _textField = new CSSTextField(); + addChild(_textField); + } + } + + + COMPILE::AS3 + private var _textField:CSSTextField; + + /** + * @copy org.apache.flex.core.ITextModel#textField + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + */ + COMPILE::AS3 + public function get textField() : CSSTextField + { + return _textField; + } + + /** + * Draws text at the given point. + * @param value The string to draw. + * @param x The x position of the top-left corner of the rectangle. + * @param y The y position of the top-left corner. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement + * @flexjsignorecoercion Text + * @flexjsignorecoercion Node + * @flexjsignorecoercion SVGLocatable + */ + public function drawText(value:String, x:Number, y:Number):void + { + COMPILE::AS3 + { + textField.selectable = false; + textField.type = TextFieldType.DYNAMIC; + textField.mouseEnabled = false; + textField.autoSize = "left"; + textField.text = value; + + var color:SolidColorStroke = stroke as SolidColorStroke; + if (color) { + textField.textColor = color.color; + textField.alpha = color.alpha; + } + + textField.x = x; + textField.y = y; + } + COMPILE::JS + { + var style:String = this.getStyleStr(); + var text:WrappedHTMLElement = document.createElementNS('http://www.w3.org/2000/svg', 'text') as WrappedHTMLElement; + text.flexjs_wrapper = this; + text.setAttribute('style', style); + text.setAttribute('x', String(x) + 'px'); + text.setAttribute('y', String(y) + 'px'); + setPosition(x, y, 0, 0); + var textNode:Text = document.createTextNode(value) as Text; + text.appendChild(textNode as Node); + element.appendChild(text); + + resize(x, y, (text as SVGLocatable).getBBox()); + + } + } + + COMPILE::JS + override protected function draw():void + { + + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a95bd7a0/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/AdvancedLayoutFeatures.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/AdvancedLayoutFeatures.as b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/AdvancedLayoutFeatures.as new file mode 100644 index 0000000..14cc5af --- /dev/null +++ b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/AdvancedLayoutFeatures.as @@ -0,0 +1,1140 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flex.core.graphics.utils +{ + import flash.events.Event; + import flash.geom.Matrix; + import flash.geom.Matrix3D; + import flash.geom.Point; + import flash.geom.Vector3D; + import flash.system.Capabilities; + + import org.apache.flex.core.graphics.utils.IAssetLayoutFeatures; + + + /** + * @private + * Transform Offsets can be assigned to any Component or GraphicElement to modify the transform + * of the object beyond where its parent layout places it. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public class AdvancedLayoutFeatures implements IAssetLayoutFeatures + { + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + /** + * Constructor. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function AdvancedLayoutFeatures() + { + layout = new CompoundTransform(); + } + + + + /** + * @private + * a flag for use by the owning object indicating whether the owning object has a pending update + * to the computed matrix. it is the owner's responsibility to set this flag. + */ + public var updatePending:Boolean = false; + + /** + * storage for the depth value. Layering is considered 'advanced' layout behavior, and not something + * that gets used by the majority of the components out there. So if a component has a non-zero depth, + * it will allocate a AdvancedLayoutFeatures object and store the value here. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public var depth:Number = 0; + + /** + * @private + * slots for the various 2D and 3D matrices for layout, offset, and computed transforms. Note that + * these are only allocated and computed on demand -- many component instances will never use a 3D + * matrix, for example. + */ + protected var _computedMatrix:Matrix; + protected var _computedMatrix3D:Matrix3D; + + /** + * @private + * the layout visible transform as defined by the user and parent layout. + */ + protected var layout:CompoundTransform; + + /** + * @private + * offset values applied by the user + */ + private var _postLayoutTransformOffsets:TransformOffsets; + + /** + * @private + * bit field flags for indicating which transforms are valid -- the layout properties, the matrices, + * and the 3D matrices. Since developers can set any of the three programmatically, the last one set + * will always be valid, and the others will be invalid until validated on demand. + */ + private static const COMPUTED_MATRIX_VALID:uint = 0x1; + private static const COMPUTED_MATRIX3D_VALID:uint = 0x2; + + /** + * @private + * general storage for all of our flags. + */ + private var _flags:uint = 0; + + /** + * @private + * static data used by utility methods below + */ + private static var reVT:Vector3D = new Vector3D(0,0,0); + private static var reVR:Vector3D = new Vector3D(0,0,0); + private static var reVS:Vector3D = new Vector3D(1,1,1); + + private static var reV:Vector.<Vector3D> = new Vector.<Vector3D>(); + reV.push(reVT); + reV.push(reVR); + reV.push(reVS); + + + private static const RADIANS_PER_DEGREES:Number = Math.PI / 180; + + private static const ZERO_REPLACEMENT_IN_3D:Number = .00000000000001; + + private static var tempLocalPosition:Vector3D; + + /** + * @private + * a pointer to the function we use to transform vectors, to work around a bug + * in early versions of the flash player. + */ + private static var transformVector:Function = initTransformVectorFunction; + + /** + * @private + * an actionscript implementation to transform a vector by a matrix. Bugs in early versions of + * flash 10's implementation of Matrix.transformVector force us to do it ourselves in actionscript. + */ + private static function pre10_0_22_87_transformVector(m:Matrix3D,v:Vector3D):Vector3D + { + var r:Vector.<Number> = m.rawData; + return new Vector3D( + r[0] * v.x + r[4] * v.y + r[8] * v.z + r[12], + r[1] * v.x + r[5] * v.y + r[9] * v.z + r[13], + r[2] * v.x + r[6] * v.y + r[10] * v.z + r[14], + 1); + } + + /** + * @private + * a function to transform vectors using the built in player API, if we're in a late enough player version + * that we won't run into bugs.s + */ + private static function nativeTransformVector(m:Matrix3D,v:Vector3D):Vector3D + { + return m.transformVector(v); + } + + /** + * @private + * the first time someone calls transformVector, they'll get this function. It checks the player version, + * and if decides which implementation to use based on whether a bug is present or not. + */ + private static function initTransformVectorFunction(m:Matrix3D,v:Vector3D):Vector3D + { + var canUseNative:Boolean = false; + var version:Array = Capabilities.version.split(' ')[1].split(','); + if (parseFloat(version[0]) > 10) + canUseNative = true; + else if (parseFloat(version[1]) > 0) + canUseNative = true; + else if (parseFloat(version[2]) > 22) + canUseNative = true; + else if (parseFloat(version[3]) >= 87) + canUseNative = true; + if (canUseNative) + transformVector = nativeTransformVector; + else + transformVector = pre10_0_22_87_transformVector; + + return transformVector(m,v); + } + + + //------------------------------------------------------------------------------ + + /** + * layout transform convenience property. Represents the x value of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutX(value:Number):void + { + layout.x = value; + invalidate(); + } + + /** + * @private + */ + public function get layoutX():Number + { + return layout.x; + } + /** + * layout transform convenience property. Represents the y value of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutY(value:Number):void + { + layout.y = value; + invalidate(); + } + + /** + * @private + */ + public function get layoutY():Number + { + return layout.y; + } + + /** + * layout transform convenience property. Represents the z value of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutZ(value:Number):void + { + layout.z = value; + invalidate(); + } + + /** + * @private + */ + public function get layoutZ():Number + { + return layout.z; + } + + //---------------------------------- + // layoutWidth + //---------------------------------- + + private var _layoutWidth:Number = 0; + + /** + * Used by the mirroring transform. See the mirror property. + * @default 0 + */ + public function get layoutWidth():Number + { + return _layoutWidth; + } + + /** + * @private + */ + public function set layoutWidth(value:Number):void + { + if (value == _layoutWidth) + return; + _layoutWidth = value; + invalidate(); + } + + + //------------------------------------------------------------------------------ + + /** + * @private + * the x value of the point around which any rotation and scale is performed in both the layout and computed matrix. + */ + public function set transformX(value:Number):void + { + layout.transformX = value; + invalidate(); + } + /** + * @private + */ + public function get transformX():Number + { + return layout.transformX; + } + + /** + * @private + * the y value of the point around which any rotation and scale is performed in both the layout and computed matrix. + */ + public function set transformY(value:Number):void + { + layout.transformY = value; + invalidate(); + } + + /** + * @private + */ + public function get transformY():Number + { + return layout.transformY; + } + + /** + * @private + * the z value of the point around which any rotation and scale is performed in both the layout and computed matrix. + */ + public function set transformZ(value:Number):void + { + layout.transformZ = value; + invalidate(); + } + + /** + * @private + */ + public function get transformZ():Number + { + return layout.transformZ; + } + + //------------------------------------------------------------------------------ + + + /** + * layout transform convenience property. Represents the rotation around the X axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutRotationX(value:Number):void + { + layout.rotationX= value; + invalidate(); + } + + /** + * @private + */ + public function get layoutRotationX():Number + { + return layout.rotationX; + } + + /** + * layout transform convenience property. Represents the rotation around the Y axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutRotationY(value:Number):void + { + layout.rotationY= value; + invalidate(); + } + + /** + * @private + */ + public function get layoutRotationY():Number + { + return layout.rotationY; + } + + /** + * layout transform convenience property. Represents the rotation around the Z axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutRotationZ(value:Number):void + { + layout.rotationZ= value; + invalidate(); + } + + /** + * @private + */ + public function get layoutRotationZ():Number + { + return layout.rotationZ; + } + + //------------------------------------------------------------------------------ + + + /** + * layout transform convenience property. Represents the scale along the X axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutScaleX(value:Number):void + { + layout.scaleX = value; + invalidate(); + } + + /** + * @private + */ + public function get layoutScaleX():Number + { + return layout.scaleX; + } + + /** + * layout transform convenience property. Represents the scale along the Y axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutScaleY(value:Number):void + { + layout.scaleY= value; + invalidate(); + } + + /** + * @private + */ + public function get layoutScaleY():Number + { + return layout.scaleY; + } + + + /** + * layout transform convenience property. Represents the scale along the Z axis of the layout matrix used in layout and in + * the computed transform. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set layoutScaleZ(value:Number):void + { + layout.scaleZ= value; + invalidate(); + } + + /** + * @private + */ + public function get layoutScaleZ():Number + { + return layout.scaleZ; + } + + /** + * @private + * The 2D matrix used during layout calculations to determine the layout and size of the component and its parent and siblings. + * If the convenience properties are set, this matrix is built from those properties. + * If the matrix is set directly, the convenience properties will be updated to values derived from this matrix. + * This matrix is used in the calculation of the computed transform if possible. Under certain circumstances, such as when + * offsets are provided, the decomposed layout properties will be used instead. + */ + public function set layoutMatrix(value:Matrix):void + { + layout.matrix = value; + invalidate(); + } + + + /** + * @private + */ + public function get layoutMatrix():Matrix + { + return layout.matrix; + + } + + + /** + * @private + * The 3D matrix used during layout calculations to determine the layout and size of the component and its parent and siblings. + * This matrix is only used by parents that respect 3D layoyut. + * If the convenience properties are set, this matrix is built from those properties. + * If the matrix is set directly, the convenience properties will be updated to values derived from this matrix. + * This matrix is used in the calculation of the computed transform if possible. Under certain circumstances, such as when + * offsets are provided, the decomposed layout properties will be used instead. + */ + public function set layoutMatrix3D(value:Matrix3D):void + { + layout.matrix3D = value; + invalidate(); + } + + /** + * @private + */ + public function get layoutMatrix3D():Matrix3D + { + return layout.matrix3D; + } + + /** + * true if the computed transform has 3D values. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get is3D():Boolean + { + return (layout.is3D || (postLayoutTransformOffsets != null && postLayoutTransformOffsets.is3D)); + } + + /** + * true if the layout transform has 3D values. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get layoutIs3D():Boolean + { + return layout.is3D; + } + + //------------------------------------------------------------------------------ + + /** offsets to the transform convenience properties that are applied when a component is rendered. If this + * property is set, its values will be added to the layout transform properties to determine the true matrix used to render + * the component + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function set postLayoutTransformOffsets(value:TransformOffsets):void + { + if (_postLayoutTransformOffsets != null) + { + _postLayoutTransformOffsets.removeEventListener(Event.CHANGE,postLayoutTransformOffsetsChangedHandler); + _postLayoutTransformOffsets.owner = null; + } + _postLayoutTransformOffsets = value; + if (_postLayoutTransformOffsets != null) + { + _postLayoutTransformOffsets.addEventListener(Event.CHANGE,postLayoutTransformOffsetsChangedHandler); + _postLayoutTransformOffsets.owner = this; + } + invalidate(); + } + + public function get postLayoutTransformOffsets():TransformOffsets + { + return _postLayoutTransformOffsets; + } + + private function postLayoutTransformOffsetsChangedHandler(e:Event):void + { + invalidate(); + } + + //---------------------------------- + // mirror + //---------------------------------- + + private var _mirror:Boolean = false; + + /** + * If true the X axis is scaled by -1 and the x coordinate of the origin + * is translated by the component's width. + * + * The net effect of this "mirror" transform is to flip the direction + * that the X axis increases in without changing the layout element's + * location relative to the parent's origin. + * + * @default false + */ + public function get mirror():Boolean + { + return _mirror; + } + + /** + * @private + */ + public function set mirror(value:Boolean):void + { + _mirror = value; + invalidate(); + } + + + //---------------------------------- + // stretchX + //---------------------------------- + + private var _stretchX:Number = 1; + + /** + * The stretchY is the horizontal component of the stretch scale factor which + * is applied before any other transformation property. + * @default 1 + */ + public function get stretchX():Number + { + return _stretchX; + } + + /** + * @private + */ + public function set stretchX(value:Number):void + { + if (value == _stretchX) + return; + _stretchX = value; + invalidate(); + } + + //---------------------------------- + // stretchY + //---------------------------------- + + private var _stretchY:Number = 1; + + /** + * The stretchY is the vertical component of the stretch scale factor which + * is applied before any other transformation property. + * @default 1 + */ + public function get stretchY():Number + { + return _stretchY; + } + + /** + * @private + */ + public function set stretchY(value:Number):void + { + if (value == _stretchY) + return; + _stretchY = value; + invalidate(); + } + + //------------------------------------------------------------------------------ + + /** + * @private + * invalidates our various cached values. Any change to the AdvancedLayoutFeatures object that affects + * the various transforms should call this function. + * @param reason - the code indicating what changes to cause the invalidation. + * @param affects3D - a flag indicating whether the change affects the 2D/3D nature of the various transforms. + * @param dispatchChangeEvent - if true, the AdvancedLayoutFeatures will dispatch a change indicating that its underlying transforms + * have been modified. + */ + private function invalidate():void + { + _flags &= ~COMPUTED_MATRIX_VALID; + _flags &= ~COMPUTED_MATRIX3D_VALID; + } + + + /** + * the computed matrix, calculated by combining the layout matrix and and any offsets provided.. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get computedMatrix():Matrix + { + if (_flags & COMPUTED_MATRIX_VALID) + return _computedMatrix; + + if (!postLayoutTransformOffsets && !mirror && stretchX == 1 && stretchY == 1) + { + return layout.matrix; + } + + var m:Matrix = _computedMatrix; + if (m == null) + m = _computedMatrix = new Matrix(); + else + m.identity(); + + var tx:Number = layout.transformX; + var ty:Number = layout.transformY; + var sx:Number = layout.scaleX; + var sy:Number = layout.scaleY; + var rz:Number = layout.rotationZ; + var x:Number = layout.x; + var y:Number = layout.y; + + if (mirror) + { + sx *= -1; + x += layoutWidth; + } + + if (postLayoutTransformOffsets) + { + sx *= postLayoutTransformOffsets.scaleX; + sy *= postLayoutTransformOffsets.scaleY; + rz += postLayoutTransformOffsets.rotationZ; + x += postLayoutTransformOffsets.x; + y += postLayoutTransformOffsets.y; + } + + if (stretchX != 1 || stretchY != 1) + m.scale(stretchX, stretchY); + build2DMatrix(m, tx, ty, sx, sy, rz, x, y); + + _flags |= COMPUTED_MATRIX_VALID; + return m; + } + + /** + * the computed 3D matrix, calculated by combining the 3D layout matrix and and any offsets provided.. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get computedMatrix3D():Matrix3D + { + if (_flags & COMPUTED_MATRIX3D_VALID) + return _computedMatrix3D; + + + if (!postLayoutTransformOffsets && !mirror && stretchX == 1 && stretchY == 1) + { + return layout.matrix3D; + } + + var m:Matrix3D = _computedMatrix3D; + if (m == null) + m = _computedMatrix3D = new Matrix3D(); + else + m.identity(); + + var tx:Number = layout.transformX; + var ty:Number = layout.transformY; + var tz:Number = layout.transformZ; + var sx:Number = layout.scaleX; + var sy:Number = layout.scaleY; + var sz:Number = layout.scaleZ; + var rx:Number = layout.rotationX; + var ry:Number = layout.rotationY; + var rz:Number = layout.rotationZ; + var x:Number = layout.x; + var y:Number = layout.y; + var z:Number = layout.z; + + if (mirror) + { + sx *= -1; + x += layoutWidth; + } + + if (postLayoutTransformOffsets) + { + sx *= postLayoutTransformOffsets.scaleX; + sy *= postLayoutTransformOffsets.scaleY; + sz *= postLayoutTransformOffsets.scaleZ; + rx += postLayoutTransformOffsets.rotationX; + ry += postLayoutTransformOffsets.rotationY; + rz += postLayoutTransformOffsets.rotationZ; + x += postLayoutTransformOffsets.x; + y += postLayoutTransformOffsets.y; + z += postLayoutTransformOffsets.z; + } + + build3DMatrix(m, tx, ty, tz, sx, sy, sz, rx, ry, rz, x, y, z); + // Always prepend last + if (stretchX != 1 || stretchY != 1) + m.prependScale(stretchX, stretchY, 1); + + _flags |= COMPUTED_MATRIX3D_VALID; + return m; + } + + + /** + * @private + * convenience function for building a 2D matrix from the convenience properties + */ + public static function build2DMatrix(m:Matrix, + tx:Number,ty:Number, + sx:Number,sy:Number, + rz:Number, + x:Number,y:Number):void + { + m.translate(-tx,-ty); + m.scale(sx,sy); + m.rotate(rz* RADIANS_PER_DEGREES); + m.translate(x+tx,y+ty); + } + + + /** + * @private + * convenience function for building a 3D matrix from the convenience properties + */ + public static function build3DMatrix(m:Matrix3D, + tx:Number,ty:Number,tz:Number, + sx:Number,sy:Number,sz:Number, + rx:Number,ry:Number,rz:Number, + x:Number,y:Number,z:Number):void + { + reVR.x = rx * RADIANS_PER_DEGREES; + reVR.y = ry * RADIANS_PER_DEGREES; + reVR.z = rz * RADIANS_PER_DEGREES; + m.recompose(reV); + if (sx == 0) + sx = ZERO_REPLACEMENT_IN_3D; + if (sy == 0) + sy = ZERO_REPLACEMENT_IN_3D; + if (sz == 0) + sz = ZERO_REPLACEMENT_IN_3D; + m.prependScale(sx,sy,sz); + m.prependTranslation(-tx,-ty,-tz); + m.appendTranslation(tx+x,ty+y,tz+z); + } + + + /** + * A utility method to transform a point specified in the local + * coordinates of this object to its location in the object's parent's + * coordinates. The pre-layout and post-layout result will be set on + * the <code>position</code> and <code>postLayoutPosition</code> + * parameters, if they are non-null. + * + * @param propertyIs3D A boolean reflecting whether the calculation needs + * to take into account the 3D matrix of the object. + * @param localPoint The point to be transformed, specified in the + * local coordinates of the object. + * @position A Vector3D point that will hold the pre-layout + * result. If null, the parameter is ignored. + * @postLayoutPosition A Vector3D point that will hold the post-layout + * result. If null, the parameter is ignored. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function transformPointToParent(propertyIs3D:Boolean, + localPosition:Vector3D, position:Vector3D, + postLayoutPosition:Vector3D):void + { + var transformedV:Vector3D; + var transformedP:Point; + tempLocalPosition = + localPosition ? + localPosition.clone() : + new Vector3D(); + + if (is3D || propertyIs3D) + { + if (position != null) + { + transformedV = transformVector(layoutMatrix3D, tempLocalPosition); + position.x = transformedV.x; + position.y = transformedV.y; + position.z = transformedV.z; + } + + if (postLayoutPosition != null) + { + // computedMatrix factor in stretchXY, so divide it out of position first + tempLocalPosition.x /= stretchX; + tempLocalPosition.y /= stretchY; + transformedV = transformVector(computedMatrix3D, tempLocalPosition); + postLayoutPosition.x = transformedV.x; + postLayoutPosition.y = transformedV.y; + postLayoutPosition.z = transformedV.z; + } + } + else + { + var localP:Point = new Point(tempLocalPosition.x, + tempLocalPosition.y); + if (position != null) + { + transformedP = layoutMatrix.transformPoint(localP); + position.x = transformedP.x; + position.y = transformedP.y; + position.z = 0; + } + + if (postLayoutPosition != null) + { + // computedMatrix factor in stretchXY, so divide it out of position first + localP.x /= stretchX; + localP.y /= stretchY; + transformedP = computedMatrix.transformPoint(localP); + postLayoutPosition.x = transformedP.x; + postLayoutPosition.y = transformedP.y; + postLayoutPosition.z = 0; + } + } + } + + /** + * @private + * call when you've changed the inputs to the computed transform to make + * any adjustments to keep a particular point fixed in parent coordinates. + */ + private function completeTransformCenterAdjustment(changeIs3D:Boolean, + transformCenter:Vector3D, targetPosition:Vector3D, + targetPostLayoutPosition:Vector3D):void + { + // TODO (chaase): optimize for transformCenter == (0,0,0) + if (is3D || changeIs3D) + { + if (targetPosition != null) + { + var adjustedLayoutCenterV:Vector3D = transformVector(layoutMatrix3D, transformCenter); + if (adjustedLayoutCenterV.equals(targetPosition) == false) + { + layout.translateBy(targetPosition.x - adjustedLayoutCenterV.x, + targetPosition.y - adjustedLayoutCenterV.y, + targetPosition.z - adjustedLayoutCenterV.z); + invalidate(); + } + } + if (targetPostLayoutPosition != null && _postLayoutTransformOffsets != null) + { + // computedMatrix factor in stretchXY, so divide it out of transform center first + var tmpPos:Vector3D = new Vector3D(transformCenter.x, transformCenter.y, transformCenter.z); + tmpPos.x /= stretchX; + tmpPos.y /= stretchY; + var adjustedComputedCenterV:Vector3D = transformVector(computedMatrix3D, tmpPos); + if (adjustedComputedCenterV.equals(targetPostLayoutPosition) == false) + { + postLayoutTransformOffsets.x +=targetPostLayoutPosition.x - adjustedComputedCenterV.x; + postLayoutTransformOffsets.y += targetPostLayoutPosition.y - adjustedComputedCenterV.y; + postLayoutTransformOffsets.z += targetPostLayoutPosition.z - adjustedComputedCenterV.z; + invalidate(); + } + } + } + else + { + var transformCenterP:Point = new Point(transformCenter.x,transformCenter.y); + if (targetPosition != null) + { + var currentPositionP:Point = layoutMatrix.transformPoint(transformCenterP); + if (currentPositionP.x != targetPosition.x || + currentPositionP.y != targetPosition.y) + { + layout.translateBy(targetPosition.x - currentPositionP.x, + targetPosition.y - currentPositionP.y, 0); + invalidate(); + } + } + + if (targetPostLayoutPosition != null && _postLayoutTransformOffsets != null) + { + // computedMatrix factor in stretchXY, so divide it out of transform center first + transformCenterP.x /= stretchX; + transformCenterP.y /= stretchY; + var currentPostLayoutPosition:Point = + computedMatrix.transformPoint(transformCenterP); + if (currentPostLayoutPosition.x != targetPostLayoutPosition.x || + currentPostLayoutPosition.y != targetPostLayoutPosition.y) + { + _postLayoutTransformOffsets.x += targetPostLayoutPosition.x - currentPostLayoutPosition.x; + _postLayoutTransformOffsets.y += targetPostLayoutPosition.y - currentPostLayoutPosition.y; + invalidate(); + } + } + } + } + + private static var staticTranslation:Vector3D = new Vector3D(); + private static var staticOffsetTranslation:Vector3D = new Vector3D(); + + /** + * A utility method to update the rotation and scale of the transform + * while keeping a particular point, specified in the component's own + * coordinate space, fixed in the parent's coordinate space. This + * function will assign the rotation and scale values provided, then + * update the x/y/z properties as necessary to keep tx/ty/tz fixed. + * @param transformCenter the point, in the component's own coordinates, + * to keep fixed relative to its parent. + * @param rotation the new values for the rotation of the transform + * @param scale the new values for the scale of the transform + * @param translation the new values for the translation of the transform + */ + public function transformAround(transformCenter:Vector3D, + scale:Vector3D, + rotation:Vector3D, + transformCenterPosition:Vector3D, + postLayoutScale:Vector3D = null, + postLayoutRotation:Vector3D = null, + postLayoutTransformCenterPosition:Vector3D = null):void + { + var is3D:Boolean = (scale != null && scale.z != 1) || + (rotation != null && ((rotation.x != 0 ) || (rotation.y != 0))) || + (transformCenterPosition != null && transformCenterPosition.z != 0) || + (postLayoutScale != null && postLayoutScale.z != 1) || + (postLayoutRotation != null && + (postLayoutRotation.x != 0 || postLayoutRotation.y != 0)) || + (postLayoutTransformCenterPosition != null && postLayoutTransformCenterPosition.z != 0); + + var needOffsets:Boolean = _postLayoutTransformOffsets == null && + (postLayoutScale != null || postLayoutRotation != null || + postLayoutTransformCenterPosition != null); + if (needOffsets) + _postLayoutTransformOffsets = new TransformOffsets(); + + // now if they gave us a non-trivial transform center, and didn't tell us where they want it, + // we need to calculate where it is so that we can make sure we keep it there. + if (transformCenter != null && + (transformCenterPosition == null || postLayoutTransformCenterPosition == null)) + { + transformPointToParent(is3D, transformCenter, staticTranslation, + staticOffsetTranslation); + if (postLayoutTransformCenterPosition == null && transformCenterPosition != null) + { + staticOffsetTranslation.x = transformCenterPosition.x + staticOffsetTranslation.x - staticTranslation.x; + staticOffsetTranslation.y = transformCenterPosition.y + staticOffsetTranslation.y - staticTranslation.y; + staticOffsetTranslation.z = transformCenterPosition.z + staticOffsetTranslation.z - staticTranslation.z; + } + + } + // if targetPosition/postLayoutTargetPosition is null here, it might be because the caller passed in + // requested values, so we haven't calculated it yet. So that means our target position is the values + // they passed in. + var targetPosition:Vector3D = (transformCenterPosition == null)? staticTranslation:transformCenterPosition; + var postLayoutTargetPosition:Vector3D = (postLayoutTransformCenterPosition == null)? staticOffsetTranslation:postLayoutTransformCenterPosition; + + // now update our transform values. + if (rotation != null) + { + if (!isNaN(rotation.x)) + layout.rotationX = rotation.x; + if (!isNaN(rotation.y)) + layout.rotationY = rotation.y; + if (!isNaN(rotation.z)) + layout.rotationZ = rotation.z; + } + if (scale != null) + { + if (!isNaN(scale.x)) + layout.scaleX = scale.x; + if (!isNaN(scale.y)) + layout.scaleY = scale.y; + if (!isNaN(scale.z)) + layout.scaleZ = scale.z; + } + + if (postLayoutRotation != null) + { + _postLayoutTransformOffsets.rotationX = postLayoutRotation.x; + _postLayoutTransformOffsets.rotationY = postLayoutRotation.y; + _postLayoutTransformOffsets.rotationZ = postLayoutRotation.z; + } + if (postLayoutScale != null) + { + _postLayoutTransformOffsets.scaleX = postLayoutScale.x; + _postLayoutTransformOffsets.scaleY = postLayoutScale.y; + _postLayoutTransformOffsets.scaleZ = postLayoutScale.z; + } + + // if they didn't pass us a transform center, + // then we assume it's the origin. In that case, it's trivially easy + // to make sure the origin is at a particular point...we simply set + // the transformCenterPosition portion of our transforms to that point. + if (transformCenter == null) + { + if (transformCenterPosition != null) + { + layout.x = transformCenterPosition.x; + layout.y = transformCenterPosition.y; + layout.z = transformCenterPosition.z; + } + if (postLayoutTransformCenterPosition != null) + { + _postLayoutTransformOffsets.x = postLayoutTransformCenterPosition.x - layout.x; + _postLayoutTransformOffsets.y = postLayoutTransformCenterPosition.y - layout.y; + _postLayoutTransformOffsets.z = postLayoutTransformCenterPosition.z - layout.z; + } + } + invalidate(); + + // if they did pass in a transform center, go do the adjustments necessary to keep it fixed in place. + if (transformCenter != null) + completeTransformCenterAdjustment(is3D, transformCenter, + targetPosition, postLayoutTargetPosition); + + + } + + } +} +