////////////////////////////////////////////////////////////////////////////////
//
// 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 mx.graphics
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Matrix;
import mx.core.mx_internal;
import mx.events.PropertyChangeEvent;
import mx.geom.CompoundTransform;
use namespace mx_internal;
[DefaultProperty("entries")]
/**
* The GradientBase class is the base class for
* LinearGradient, LinearGradientStroke, and RadialGradient.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class GradientBase extends EventDispatcher
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function GradientBase()
{
super();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
mx_internal var colors:Array /* of uint */ = [];
/**
* @private
*/
mx_internal var ratios:Array /* of Number */ = [];
/**
* @private
*/
mx_internal var alphas:Array /* of Number */ = [];
//--------------------------------------------------------------------------
//
// Class Properties
//
//--------------------------------------------------------------------------
/**
* Value of the width and height of the untransformed gradient
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public static const GRADIENT_DIMENSION:Number = 1638.4;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// angle
//----------------------------------
/**
* @private
* Storage for the angle property.
*/
mx_internal var _angle:Number;
[Inspectable(category="General")]
[Deprecated(replacement="rotation")]
/**
* By default, the LinearGradientStroke defines a transition
* from left to right across the control.
* Use the angle
property to control the transition direction.
* For example, a value of 180.0 causes the transition
* to occur from right to left, rather than from left to right.
*
* @default 0.0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get angle():Number
{
return _angle / Math.PI * 180;
}
/**
* @private
*/
public function set angle(value:Number):void
{
var oldValue:Number = _angle;
_angle = value / 180 * Math.PI;
dispatchGradientChangedEvent("angle", oldValue, _angle);
}
//----------------------------------
// compoundTransform
//----------------------------------
/**
* Holds the matrix and the convenience transform properties (x
, y
, and rotation
).
* The compoundTransform is only created when the matrix
property is set.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected var compoundTransform:CompoundTransform;
//----------------------------------
// entries
//----------------------------------
/**
* @private
* Storage for the entries property.
*/
private var _entries:Array = [];
[Bindable("propertyChange")]
[Inspectable(category="General", arrayType="mx.graphics.GradientEntry")]
/**
* An Array of GradientEntry objects
* defining the fill patterns for the gradient fill.
*
* @default []
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get entries():Array
{
return _entries;
}
/**
* @private
*/
public function set entries(value:Array):void
{
var oldValue:Array = _entries;
_entries = value;
processEntries();
dispatchGradientChangedEvent("entries", oldValue, value);
}
//----------------------------------
// interpolationMethod
//----------------------------------
/**
* @private
* Storage for the interpolationMethod property.
*/
private var _interpolationMethod:String = "rgb";
[Inspectable(category="General", enumeration="rgb,linearRGB", defaultValue="rgb")]
/**
* A value from the InterpolationMethod class
* that specifies which interpolation method to use.
*
*
Valid values are InterpolationMethod.LINEAR_RGB
* and InterpolationMethod.RGB
.
The gradient scaleX
and scaleY
properties represent pixels while the Matrix scale properties represent multipliers.
* Thus they are not compatible.
* Another difference is the most of the transform properties (x
, y
, scaleX
, and scaleY
)
* support NaN values while the matrix does not. A NaN value means that the gradient will choose an appropriate value.
The scaleX
and scaleY
properties can not be represented by the matrix.
* Once the matrix is set, scaleX
and scaleY
can no longer be set.
* Also, x
and y
can not be set to NaN.
* The matrix can be set back to null which also resets all of the convenience transform properties back to their default values.
If the matrix is set, then the gradient draw logic will scale the gradient to fit the bounds of the graphic element. * It will then position the gradient in the upper left corner of the graphic element. * Finally, it will apply the matrix transformations.
*By default, the LinearGradientStroke defines a transition
* from left to right across the control.
* Use the rotation
property to control the transition direction.
* For example, a value of 180.0 causes the transition
* to occur from right to left, rather than from left to right.
rotation
property to control the transition direction.
* For example, a value of 180.0 causes the transition
* to occur from right to left, rather than from left to right.
*
* @default 0.0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get rotation():Number
{
return compoundTransform ? compoundTransform.rotationZ : _rotation;
}
/**
* @private
*/
public function set rotation(value:Number):void
{
if (value != rotation)
{
var oldValue:Number = rotation;
if (compoundTransform)
compoundTransform.rotationZ = value;
else
_rotation = value;
dispatchGradientChangedEvent("rotation", oldValue, value);
}
}
//----------------------------------
// spreadMethod
//----------------------------------
/**
* @private
* Storage for the spreadMethod property.
*/
private var _spreadMethod:String = "pad";
[Bindable("propertyChange")]
[Inspectable(category="General", enumeration="pad,reflect,repeat", defaultValue="pad")]
/**
* A value from the SpreadMethod class
* that specifies which spread method to use.
*
* Valid values are SpreadMethod.PAD
,
* SpreadMethod.REFLECT
,
* and SpreadMethod.REPEAT
.
entries
* Array into the internal colors
, ratios
,
* and alphas
arrays.
*/
private function processEntries():void
{
colors = [];
ratios = [];
alphas = [];
if (!_entries || _entries.length == 0)
return;
var ratioConvert:Number = 255;
var i:int;
var n:int = _entries.length;
for (i = 0; i < n; i++)
{
var e:GradientEntry = _entries[i];
e.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
entry_propertyChangeHandler, false, 0, true);
colors.push(e.color);
alphas.push(e.alpha);
ratios.push(e.ratio * ratioConvert);
}
if (isNaN(ratios[0]))
ratios[0] = 0;
if (isNaN(ratios[n - 1]))
ratios[n - 1] = 255;
i = 1;
while (true)
{
while (i < n && !isNaN(ratios[i]))
{
i++;
}
if (i == n)
break;
var start:int = i - 1;
while (i < n && isNaN(ratios[i]))
{
i++;
}
var br:Number = ratios[start];
var tr:Number = ratios[i];
for (var j:int = 1; j < i - start; j++)
{
ratios[j] = br + j * (tr - br) / (i - start);
}
}
}
/**
* Dispatch a gradientChanged event.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
mx_internal function dispatchGradientChangedEvent(prop:String,
oldValue:*, value:*):void
{
dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, prop,
oldValue, value));
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
*/
private function entry_propertyChangeHandler(event:Event):void
{
processEntries();
dispatchGradientChangedEvent("entries", entries, entries);
}
}
}