http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5ed4d983/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/source/sample.mxml.html ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/source/sample.mxml.html b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/source/sample.mxml.html index 8578012..0bffa33 100644 --- a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/source/sample.mxml.html +++ b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/source/sample.mxml.html @@ -14,77 +14,77 @@ See the License for the specific language governing permissions and limitations under the License. --> -<!-- saved from url=(0014)about:internet --> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> -<title>sample.mxml</title> -<link rel="stylesheet" type="text/css" href="../SourceStyles.css"/> -</head> - -<body><pre><span class="MXMLProcessing_Instruction"><?xml version="1.0" encoding="utf-8"?></span> -<span class="MXMLComponent_Tag"><s:Application</span><span class="MXMLDefault_Text"> xmlns:fx="</span><span class="MXMLString">http://ns.adobe.com/mxml/2009</span><span class="MXMLDefault_Text">" - xmlns:s="</span><span class="MXMLString">library://ns.adobe.com/flex/spark</span><span class="MXMLDefault_Text">" - xmlns:mx="</span><span class="MXMLString">library://ns.adobe.com/flex/mx</span><span class="MXMLDefault_Text">" - xmlns:my="</span><span class="MXMLString">*</span><span class="MXMLDefault_Text">" minWidth="</span><span class="MXMLString">600</span><span class="MXMLDefault_Text">" minHeight="</span><span class="MXMLString">350</span><span class="MXMLDefault_Text">" - applicationComplete="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" backgroundColor="</span><span class="MXMLString">0x323232</span><span class="MXMLDefault_Text">" viewSourceURL="</span><span class="MXMLString">srcview/index.html</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> - - <span class="MXMLSpecial_Tag"><fx:Script></span> - <![CDATA[ - <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">mx</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">collections</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">ArrayCollection</span>; - <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">mx</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">rpc</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">events</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">ResultEvent</span>; - - <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">components</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">Group</span>; - <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">components</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">supportClasses</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">GroupBase</span>; - <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">effects</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">animation</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">MotionPath</span>; - - <span class="ActionScriptBracket/Brace">[</span><span class="ActionScriptMetadata">Bindable</span><span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptReserved">private</span> <span class="ActionScriptvar">var</span> <span class="ActionScriptDefault_Text">photoFeed</span>:<span class="ActionScriptDefault_Text">ArrayCollection</span>; - - <span class="ActionScriptReserved">private</span> <span class="ActionScriptfunction">function</span> <span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span>:<span class="ActionScriptReserved">void</span> <span class="ActionScriptBracket/Brace">{</span> - <span class="ActionScriptvar">var</span> <span class="ActionScriptDefault_Text">params</span>:<span class="ActionScriptDefault_Text">Object</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptReserved">new</span> <span class="ActionScriptDefault_Text">Object</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span>; - <span class="ActionScriptDefault_Text">params</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">format</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptString">'rss_200_enc'</span>; - <span class="ActionScriptDefault_Text">params</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">tags</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptDefault_Text">searchTerms</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">text</span>; - <span class="ActionScriptDefault_Text">photoService</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">send</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">params</span><span class="ActionScriptBracket/Brace">)</span>; - <span class="ActionScriptBracket/Brace">}</span> - - <span class="ActionScriptReserved">private</span> <span class="ActionScriptfunction">function</span> <span class="ActionScriptDefault_Text">photoHandler</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">event</span>:<span class="ActionScriptDefault_Text">ResultEvent</span><span class="ActionScriptBracket/Brace">)</span>:<span class="ActionScriptReserved">void</span> <span class="ActionScriptBracket/Brace">{</span> - <span class="ActionScriptDefault_Text">photoFeed</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptDefault_Text">event</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">result</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">rss</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">channel</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">item</span> <span class="ActionScriptReserved">as</span> <span class="ActionScriptDefault_Text">ArrayCollection</span>; - <span class="ActionScriptBracket/Brace">}</span> - <span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptOperator">></span> - <span class="MXMLSpecial_Tag"></fx:Script></span> - - <span class="MXMLSpecial_Tag"><fx:Declarations></span> - <span class="MXMLComponent_Tag"><s:HTTPService</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">photoService</span><span class="MXMLDefault_Text">" - url="</span><span class="MXMLString">http://api.flickr.com/services/feeds/photos_public.gne</span><span class="MXMLDefault_Text">" - result="</span><span class="ActionScriptDefault_Text">photoHandler</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">event</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLSpecial_Tag"></fx:Declarations></span> - - <span class="MXMLComponent_Tag"><s:layout></span> - <span class="MXMLComponent_Tag"><s:VerticalLayout</span><span class="MXMLDefault_Text"> paddingTop="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingLeft="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingRight="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingBottom="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComponent_Tag"></s:layout></span> - - <span class="MXMLComponent_Tag"><s:HGroup</span><span class="MXMLDefault_Text"> verticalAlign="</span><span class="MXMLString">middle</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> - <span class="MXMLComponent_Tag"><s:Label</span><span class="MXMLDefault_Text"> text="</span><span class="MXMLString">Flickr tags or search terms:</span><span class="MXMLDefault_Text">" color="</span><span class="MXMLString">0xFFFFFF</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComponent_Tag"><s:TextInput</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">searchTerms</span><span class="MXMLDefault_Text">" - enter="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" text="</span><span class="MXMLString">bugs</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComponent_Tag"><s:Button</span><span class="MXMLDefault_Text"> label="</span><span class="MXMLString">Search</span><span class="MXMLDefault_Text">" - click="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComment"><!--</span><span class="MXMLComment"> The slider to control the axis angle </span><span class="MXMLComment">--></span> - <span class="MXMLComponent_Tag"><s:HSlider</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">axisSlider</span><span class="MXMLDefault_Text">" minimum="</span><span class="MXMLString">-90</span><span class="MXMLDefault_Text">" maximum="</span><span class="MXMLString">90</span><span class="MXMLDefault_Text">" - value="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" liveDragging="</span><span class="MXMLString">true</span><span class="MXMLDefault_Text">" width="</span><span class="MXMLString">300</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComponent_Tag"></s:HGroup></span> - - <span class="MXMLComponent_Tag"><s:List</span><span class="MXMLDefault_Text"> width="</span><span class="MXMLString">700</span><span class="MXMLDefault_Text">" height="</span><span class="MXMLString">225</span><span class="MXMLDefault_Text">" - dataProvider="</span><span class="MXMLString">{</span><span class="ActionScriptDefault_Text">photoFeed</span><span class="MXMLString">}</span><span class="MXMLDefault_Text">" - itemRenderer="</span><span class="MXMLString">FlickrThumbnail</span><span class="MXMLDefault_Text">" - id="</span><span class="MXMLString">theList</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> - - <span class="MXMLComponent_Tag"><s:layout></span> - <span class="MXMLComponent_Tag"><my:WheelLayout</span><span class="MXMLDefault_Text"> gap="</span><span class="MXMLString">20</span><span class="MXMLDefault_Text">" axisAngle="</span><span class="MXMLString">{</span><span class="ActionScriptDefault_Text">axisSlider</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">value</span><span class="MXMLString">}</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> - <span class="MXMLComponent_Tag"></s:layout></span> - <span class="MXMLComponent_Tag"></s:List></span> - - -<span class="MXMLComponent_Tag"></s:Application></span></pre></body> -</html> +<!-- saved from url=(0014)about:internet --> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> +<title>sample.mxml</title> +<link rel="stylesheet" type="text/css" href="../SourceStyles.css"/> +</head> + +<body><pre><span class="MXMLProcessing_Instruction"><?xml version="1.0" encoding="utf-8"?></span> +<span class="MXMLComponent_Tag"><s:Application</span><span class="MXMLDefault_Text"> xmlns:fx="</span><span class="MXMLString">http://ns.adobe.com/mxml/2009</span><span class="MXMLDefault_Text">" + xmlns:s="</span><span class="MXMLString">library://ns.adobe.com/flex/spark</span><span class="MXMLDefault_Text">" + xmlns:mx="</span><span class="MXMLString">library://ns.adobe.com/flex/mx</span><span class="MXMLDefault_Text">" + xmlns:my="</span><span class="MXMLString">*</span><span class="MXMLDefault_Text">" minWidth="</span><span class="MXMLString">600</span><span class="MXMLDefault_Text">" minHeight="</span><span class="MXMLString">350</span><span class="MXMLDefault_Text">" + applicationComplete="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" backgroundColor="</span><span class="MXMLString">0x323232</span><span class="MXMLDefault_Text">" viewSourceURL="</span><span class="MXMLString">srcview/index.html</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> + + <span class="MXMLSpecial_Tag"><fx:Script></span> + <![CDATA[ + <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">mx</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">collections</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">ArrayCollection</span>; + <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">mx</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">rpc</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">events</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">ResultEvent</span>; + + <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">components</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">Group</span>; + <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">components</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">supportClasses</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">GroupBase</span>; + <span class="ActionScriptReserved">import</span> <span class="ActionScriptDefault_Text">spark</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">effects</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">animation</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">MotionPath</span>; + + <span class="ActionScriptBracket/Brace">[</span><span class="ActionScriptMetadata">Bindable</span><span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptReserved">private</span> <span class="ActionScriptvar">var</span> <span class="ActionScriptDefault_Text">photoFeed</span>:<span class="ActionScriptDefault_Text">ArrayCollection</span>; + + <span class="ActionScriptReserved">private</span> <span class="ActionScriptfunction">function</span> <span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span>:<span class="ActionScriptReserved">void</span> <span class="ActionScriptBracket/Brace">{</span> + <span class="ActionScriptvar">var</span> <span class="ActionScriptDefault_Text">params</span>:<span class="ActionScriptDefault_Text">Object</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptReserved">new</span> <span class="ActionScriptDefault_Text">Object</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span>; + <span class="ActionScriptDefault_Text">params</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">format</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptString">'rss_200_enc'</span>; + <span class="ActionScriptDefault_Text">params</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">tags</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptDefault_Text">searchTerms</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">text</span>; + <span class="ActionScriptDefault_Text">photoService</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">send</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">params</span><span class="ActionScriptBracket/Brace">)</span>; + <span class="ActionScriptBracket/Brace">}</span> + + <span class="ActionScriptReserved">private</span> <span class="ActionScriptfunction">function</span> <span class="ActionScriptDefault_Text">photoHandler</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">event</span>:<span class="ActionScriptDefault_Text">ResultEvent</span><span class="ActionScriptBracket/Brace">)</span>:<span class="ActionScriptReserved">void</span> <span class="ActionScriptBracket/Brace">{</span> + <span class="ActionScriptDefault_Text">photoFeed</span> <span class="ActionScriptOperator">=</span> <span class="ActionScriptDefault_Text">event</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">result</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">rss</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">channel</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">item</span> <span class="ActionScriptReserved">as</span> <span class="ActionScriptDefault_Text">ArrayCollection</span>; + <span class="ActionScriptBracket/Brace">}</span> + <span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptBracket/Brace">]</span><span class="ActionScriptOperator">></span> + <span class="MXMLSpecial_Tag"></fx:Script></span> + + <span class="MXMLSpecial_Tag"><fx:Declarations></span> + <span class="MXMLComponent_Tag"><s:HTTPService</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">photoService</span><span class="MXMLDefault_Text">" + url="</span><span class="MXMLString">http://api.flickr.com/services/feeds/photos_public.gne</span><span class="MXMLDefault_Text">" + result="</span><span class="ActionScriptDefault_Text">photoHandler</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptDefault_Text">event</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLSpecial_Tag"></fx:Declarations></span> + + <span class="MXMLComponent_Tag"><s:layout></span> + <span class="MXMLComponent_Tag"><s:VerticalLayout</span><span class="MXMLDefault_Text"> paddingTop="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingLeft="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingRight="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" paddingBottom="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComponent_Tag"></s:layout></span> + + <span class="MXMLComponent_Tag"><s:HGroup</span><span class="MXMLDefault_Text"> verticalAlign="</span><span class="MXMLString">middle</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> + <span class="MXMLComponent_Tag"><s:Label</span><span class="MXMLDefault_Text"> text="</span><span class="MXMLString">Flickr tags or search terms:</span><span class="MXMLDefault_Text">" color="</span><span class="MXMLString">0xFFFFFF</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComponent_Tag"><s:TextInput</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">searchTerms</span><span class="MXMLDefault_Text">" + enter="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" text="</span><span class="MXMLString">bugs</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComponent_Tag"><s:Button</span><span class="MXMLDefault_Text"> label="</span><span class="MXMLString">Search</span><span class="MXMLDefault_Text">" + click="</span><span class="ActionScriptDefault_Text">requestPhotos</span><span class="ActionScriptBracket/Brace">(</span><span class="ActionScriptBracket/Brace">)</span><span class="MXMLDefault_Text">" </span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComment"><!--</span><span class="MXMLComment"> The slider to control the axis angle </span><span class="MXMLComment">--></span> + <span class="MXMLComponent_Tag"><s:HSlider</span><span class="MXMLDefault_Text"> id="</span><span class="MXMLString">axisSlider</span><span class="MXMLDefault_Text">" minimum="</span><span class="MXMLString">-90</span><span class="MXMLDefault_Text">" maximum="</span><span class="MXMLString">90</span><span class="MXMLDefault_Text">" + value="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" liveDragging="</span><span class="MXMLString">true</span><span class="MXMLDefault_Text">" width="</span><span class="MXMLString">300</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComponent_Tag"></s:HGroup></span> + + <span class="MXMLComponent_Tag"><s:List</span><span class="MXMLDefault_Text"> width="</span><span class="MXMLString">700</span><span class="MXMLDefault_Text">" height="</span><span class="MXMLString">225</span><span class="MXMLDefault_Text">" + dataProvider="</span><span class="MXMLString">{</span><span class="ActionScriptDefault_Text">photoFeed</span><span class="MXMLString">}</span><span class="MXMLDefault_Text">" + itemRenderer="</span><span class="MXMLString">FlickrThumbnail</span><span class="MXMLDefault_Text">" + id="</span><span class="MXMLString">theList</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">></span> + + <span class="MXMLComponent_Tag"><s:layout></span> + <span class="MXMLComponent_Tag"><my:WheelLayout</span><span class="MXMLDefault_Text"> gap="</span><span class="MXMLString">20</span><span class="MXMLDefault_Text">" axisAngle="</span><span class="MXMLString">{</span><span class="ActionScriptDefault_Text">axisSlider</span><span class="ActionScriptOperator">.</span><span class="ActionScriptDefault_Text">value</span><span class="MXMLString">}</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/></span> + <span class="MXMLComponent_Tag"></s:layout></span> + <span class="MXMLComponent_Tag"></s:List></span> + + +<span class="MXMLComponent_Tag"></s:Application></span></pre></body> +</html>
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5ed4d983/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/FlickrThumbnail.mxml ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/FlickrThumbnail.mxml b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/FlickrThumbnail.mxml index 8667a8f..7a7ff88 100644 --- a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/FlickrThumbnail.mxml +++ b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/FlickrThumbnail.mxml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more @@ -17,64 +17,64 @@ limitations under the License. --> -<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" - xmlns:s="library://ns.adobe.com/flex/spark" - xmlns:mx="library://ns.adobe.com/flex/mx" click="itemrenderer1_clickHandler(event)"> - - <fx:Script> - <![CDATA[ - import spark.components.supportClasses.GroupBase; - import spark.effects.Animate; - import spark.effects.animation.MotionPath; - import spark.effects.animation.SimpleMotionPath; - protected function itemrenderer1_clickHandler(event:MouseEvent):void - { - var g:GroupBase = parent as GroupBase; - var p:Point = g.layout.getScrollPositionDeltaToElement(this.itemIndex); - if (p) - { - var startX:Number = g.horizontalScrollPosition; - var startY:Number = g.verticalScrollPosition; - var anim:Animate = new Animate(); - anim.motionPaths = new <MotionPath>[ - new SimpleMotionPath("horizontalScrollPosition", startX, startX + p.x, 500), - new SimpleMotionPath("verticalScrollPosition", startY, startY + p.y, 500) - ]; - - var interpolator:NumberInterpolatorWrapping = new NumberInterpolatorWrapping(0, g.contentWidth - g.width); - var scrollLength:Number = interpolator.getLength(startX, startX + p.x); - anim.interpolator = interpolator; - anim.duration = Math.max(550, Math.min(2500, scrollLength * 2)); - - anim.play([g]); - } - } - ]]> - </fx:Script> - - - <s:states> - <s:State name="normal"/> - <s:State name="hovered"/> - <s:State name="selected"/> - </s:states> - - <s:Rect id="border" left="0" right="0" top="0" bottom="0"> - <s:fill> - <s:SolidColor color="0xDFDFDF" color.hovered="0xFF0000" color.selected="0x00FF00"/> - </s:fill> - </s:Rect> - - <s:Group left="1" right="1" top="1" bottom="1"> - <s:layout> - <s:VerticalLayout horizontalAlign="center"/> - </s:layout> - - <mx:Image - width="75" height="75" - source="{data.thumbnail.url}" /> - <s:Label text="{data.credit}" maxWidth="100" textAlign="center"/> - </s:Group> - -</s:ItemRenderer> - +<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" click="itemrenderer1_clickHandler(event)"> + + <fx:Script> + <![CDATA[ + import spark.components.supportClasses.GroupBase; + import spark.effects.Animate; + import spark.effects.animation.MotionPath; + import spark.effects.animation.SimpleMotionPath; + protected function itemrenderer1_clickHandler(event:MouseEvent):void + { + var g:GroupBase = parent as GroupBase; + var p:Point = g.layout.getScrollPositionDeltaToElement(this.itemIndex); + if (p) + { + var startX:Number = g.horizontalScrollPosition; + var startY:Number = g.verticalScrollPosition; + var anim:Animate = new Animate(); + anim.motionPaths = new <MotionPath>[ + new SimpleMotionPath("horizontalScrollPosition", startX, startX + p.x, 500), + new SimpleMotionPath("verticalScrollPosition", startY, startY + p.y, 500) + ]; + + var interpolator:NumberInterpolatorWrapping = new NumberInterpolatorWrapping(0, g.contentWidth - g.width); + var scrollLength:Number = interpolator.getLength(startX, startX + p.x); + anim.interpolator = interpolator; + anim.duration = Math.max(550, Math.min(2500, scrollLength * 2)); + + anim.play([g]); + } + } + ]]> + </fx:Script> + + + <s:states> + <s:State name="normal"/> + <s:State name="hovered"/> + <s:State name="selected"/> + </s:states> + + <s:Rect id="border" left="0" right="0" top="0" bottom="0"> + <s:fill> + <s:SolidColor color="0xDFDFDF" color.hovered="0xFF0000" color.selected="0x00FF00"/> + </s:fill> + </s:Rect> + + <s:Group left="1" right="1" top="1" bottom="1"> + <s:layout> + <s:VerticalLayout horizontalAlign="center"/> + </s:layout> + + <mx:Image + width="75" height="75" + source="{data.thumbnail.url}" /> + <s:Label text="{data.credit}" maxWidth="100" textAlign="center"/> + </s:Group> + +</s:ItemRenderer> + http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5ed4d983/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/NumberInterpolatorWrapping.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/NumberInterpolatorWrapping.as b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/NumberInterpolatorWrapping.as index 8613d7b..175bb5a 100644 --- a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/NumberInterpolatorWrapping.as +++ b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/NumberInterpolatorWrapping.as @@ -16,95 +16,95 @@ // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// -package -{ -import spark.effects.interpolation.IInterpolator; - -public class NumberInterpolatorWrapping implements IInterpolator -{ - private var _rangeBegin:Number; - private var _rangeEnd:Number; - public function NumberInterpolatorWrapping(rangeBegin:Number, rangeEnd:Number) - { - _rangeBegin = rangeBegin; - _rangeEnd = rangeEnd; - } - - /** - * Returns the type that an implementor can handle - */ - public function get interpolatedType():Class - { - return Number; - } - - /** - * Given an elapsed fraction of an animation between 0 and 1, - * and start and end values, this function returns some value - * based on whatever interpolation the implementor chooses to - * provide. - */ - public function interpolate(fraction:Number, startValue:Object, endValue:Object):Object - { - if (fraction == 0) - return startValue; - else if (fraction == 1) - return endValue; - var start:Number = Number(startValue); - var end:Number = Number(endValue); - - if (Math.abs(end - start) < Math.abs(_rangeEnd - _rangeBegin) - Math.abs(end - start)) - { - return start + fraction * (end - start); - } - else - { - var result:Number; - if (start < end) - { - result = start - fraction * (_rangeEnd - _rangeBegin - Math.abs(start - end)); - if (result < _rangeBegin) - result += _rangeEnd - _rangeBegin; - return result; - } - else - { - result = start + fraction * (_rangeEnd - _rangeBegin - Math.abs(start - end)); - if (result > _rangeEnd) - result -= _rangeEnd - _rangeBegin; - return result; - } - } - } - - public function increment(baseValue:Object, incrementValue:Object):Object - { - var result:Number = Number(baseValue) + Number(incrementValue); - // This won't handle situations where we're adding more than - // the range itself, but since this will only be called when - // the user submits a 'byValue' that large, it seems unlikely - // at the very least - if (result > _rangeEnd) - result = _rangeBegin + (result - _rangeEnd); - return result; - } - - public function decrement(baseValue:Object, decrementValue:Object):Object - { - var result:Number = Number(baseValue) - Number(decrementValue); - // This won't handle situations where we're subtracting more than - // the range itself, but since this will only be called when - // the user submits a 'byValue' that large, it seems unlikely - // at the very least - if (result < _rangeBegin) - result = _rangeEnd + (_rangeBegin - result); - return result; - } - - public function getLength(startValue:Number, endValue:Number):Number - { - return Math.min( Math.abs(startValue - endValue), Math.abs(_rangeEnd - _rangeBegin - Math.abs(startValue - endValue))); - } - -} +package +{ +import spark.effects.interpolation.IInterpolator; + +public class NumberInterpolatorWrapping implements IInterpolator +{ + private var _rangeBegin:Number; + private var _rangeEnd:Number; + public function NumberInterpolatorWrapping(rangeBegin:Number, rangeEnd:Number) + { + _rangeBegin = rangeBegin; + _rangeEnd = rangeEnd; + } + + /** + * Returns the type that an implementor can handle + */ + public function get interpolatedType():Class + { + return Number; + } + + /** + * Given an elapsed fraction of an animation between 0 and 1, + * and start and end values, this function returns some value + * based on whatever interpolation the implementor chooses to + * provide. + */ + public function interpolate(fraction:Number, startValue:Object, endValue:Object):Object + { + if (fraction == 0) + return startValue; + else if (fraction == 1) + return endValue; + var start:Number = Number(startValue); + var end:Number = Number(endValue); + + if (Math.abs(end - start) < Math.abs(_rangeEnd - _rangeBegin) - Math.abs(end - start)) + { + return start + fraction * (end - start); + } + else + { + var result:Number; + if (start < end) + { + result = start - fraction * (_rangeEnd - _rangeBegin - Math.abs(start - end)); + if (result < _rangeBegin) + result += _rangeEnd - _rangeBegin; + return result; + } + else + { + result = start + fraction * (_rangeEnd - _rangeBegin - Math.abs(start - end)); + if (result > _rangeEnd) + result -= _rangeEnd - _rangeBegin; + return result; + } + } + } + + public function increment(baseValue:Object, incrementValue:Object):Object + { + var result:Number = Number(baseValue) + Number(incrementValue); + // This won't handle situations where we're adding more than + // the range itself, but since this will only be called when + // the user submits a 'byValue' that large, it seems unlikely + // at the very least + if (result > _rangeEnd) + result = _rangeBegin + (result - _rangeEnd); + return result; + } + + public function decrement(baseValue:Object, decrementValue:Object):Object + { + var result:Number = Number(baseValue) - Number(decrementValue); + // This won't handle situations where we're subtracting more than + // the range itself, but since this will only be called when + // the user submits a 'byValue' that large, it seems unlikely + // at the very least + if (result < _rangeBegin) + result = _rangeEnd + (_rangeBegin - result); + return result; + } + + public function getLength(startValue:Number, endValue:Number):Number + { + return Math.min( Math.abs(startValue - endValue), Math.abs(_rangeEnd - _rangeBegin - Math.abs(startValue - endValue))); + } + +} } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5ed4d983/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/WheelLayout.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/WheelLayout.as b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/WheelLayout.as index 1ce4bb6..7340a09 100644 --- a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/WheelLayout.as +++ b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/WheelLayout.as @@ -16,501 +16,501 @@ // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// -package -{ - -import flash.geom.Matrix; -import flash.geom.Matrix3D; -import flash.geom.Point; -import flash.geom.Rectangle; -import flash.geom.Vector3D; - -import mx.core.ILayoutElement; -import mx.core.IVisualElement; - -import spark.components.supportClasses.GroupBase; -import spark.core.NavigationUnit; -import spark.layouts.supportClasses.LayoutBase; - -public class WheelLayout extends LayoutBase -{ - //-------------------------------------------------------------------------- - // - // Constructor - // - //-------------------------------------------------------------------------- - - public function WheelLayout() - { - super(); - } - - //-------------------------------------------------------------------------- - // - // Properties - // - //-------------------------------------------------------------------------- - - //---------------------------------- - // gap - //---------------------------------- - - private var _gap:Number = 0; - - /** - * The gap between the items - */ - public function get gap():Number - { - return _gap; - } - - public function set gap(value:Number):void - { - _gap = value; - var layoutTarget:GroupBase = target; - if (layoutTarget) - { - layoutTarget.invalidateSize(); - layoutTarget.invalidateDisplayList(); - } - } - - //---------------------------------- - // axisAngle - //---------------------------------- - - /** - * @private - * The total width of all items, including gap space. - */ - private var _totalWidth:Number; - - /** - * @private - * Cache which item is currently in view, to facilitate scrollposition delta calculations - */ - private var _centeredItemIndex:int = 0; - private var _centeredItemCircumferenceBegin:Number = 0; - private var _centeredItemCircumferenceEnd:Number = 0; - private var _centeredItemDegrees:Number = 0; - - /** - * The axis to tilt the 3D wheel - */ - private var _axis:Vector3D = new Vector3D(0, 1, 0.1); - - /** - * The angle to tilt the axis of the wheel - */ - public function set axisAngle(value:Number):void - { - _axis = new Vector3D(0, Math.cos(Math.PI * value /180), Math.sin(Math.PI * value /180)); - var layoutTarget:GroupBase = target; - if (layoutTarget) - { - layoutTarget.invalidateSize(); - layoutTarget.invalidateDisplayList(); - } - } - - /** - * @private - * Given the radius of the sphere, return the radius of the - * projected sphere. Uses the projection matrix of the - * layout target to calculate. - */ - private function projectSphere(radius:Number, radius1:Number):Number - { - var fl:Number = target.transform.perspectiveProjection.focalLength; - var alpha:Number = Math.asin( radius1 / (radius + fl) ); - return fl * Math.tan(alpha) * 2; - } - - /** - * @private - * Given the totalWidth, maxHeight and maxHalfWidthDiagonal, calculate the bounds of the items - * on screen. Uses the projection matrix of the layout target to calculate. - */ - private function projectBounds(totalWidth:Number, maxWidth:Number, maxHeight:Number, maxHalfWidthDiagonal:Number):Point - { - // Use the the total width as a circumference of an imaginary circle which we will use to - // align the items in 3D: - var radius:Number = _totalWidth * 0.5 / Math.PI; - - // Now since we are going to arrange all the items along circle, middle of the item being the tangent point, - // we need to calculate the minimum bounding circle. It is easily calculated from the maximum width item: - var boundingRadius:Number = Math.sqrt(radius * radius + 0.25 * maxWidth * maxWidth); - - var projectedBoundsW:Number = _axis.z * _axis.z * (maxHalfWidthDiagonal + 2 * radius) + - projectSphere(radius, boundingRadius ) * _axis.y * _axis.y; - - var projectedBoundsH:Number = Math.abs(_axis.z) * (maxHalfWidthDiagonal + 2 * radius) + - maxHeight * _axis.y * _axis.y; - - return new Point(projectedBoundsW + 10, projectedBoundsH + 10); - } - - /** - * @private - * Iterates through all the items, calculates the projected bounds on screen, updates _totalWidth member variable. - */ - private function calculateBounds():Point - { - // Calculate total width: - _totalWidth = 0; - - var maxHeight:Number = 0; - var maxWidth:Number = 0; - var maxD:Number = 0; - - // Add up all the widths - var iter:LayoutIterator = new LayoutIterator(target); - var el:ILayoutElement; - while (el = iter.nextElement()) - { - var preferredWidth:Number = el.getPreferredBoundsWidth(false /*postTransform*/); - var preferredHeight:Number = el.getPreferredBoundsHeight(false /*postTransform*/); - - // Add up item width - _totalWidth += preferredWidth; - - // Max up item size - maxWidth = Math.max(maxWidth, preferredWidth); - maxHeight = Math.max(maxHeight, preferredHeight); - - maxD = Math.max(maxD, Math.sqrt(preferredWidth * preferredWidth / 4 + - preferredHeight * preferredHeight)); - } - - // Add up the gap - _totalWidth += gap * iter.numVisited; - - // Project - return projectBounds(_totalWidth, maxWidth, maxHeight, maxD); - } - - //-------------------------------------------------------------------------- - // - // Overridden methods: LayoutBase - // - //-------------------------------------------------------------------------- - - /** - * @private - */ - override public function set target(value:GroupBase):void - { - // Make sure that if layout is swapped out, we clean up - if (!value && target) - { - target.maintainProjectionCenter = false; - - var iter:LayoutIterator = new LayoutIterator(target); - var el:ILayoutElement; - while (el = iter.nextElement()) - { - el.setLayoutMatrix(new Matrix(), false /*triggerLayout*/); - } - } - - super.target = value; - - // Make sure we turn on projection the first time the layout - // gets assigned to the group - if (target) - target.maintainProjectionCenter = true; - } - - override public function measure():void - { - var bounds:Point = calculateBounds(); - - target.measuredWidth = bounds.x; - target.measuredHeight = bounds.y; - } - - override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void - { - // Get the bounds, this will also update _totalWidth - var bounds:Point = calculateBounds(); - - // Update the content size - target.setContentSize(_totalWidth + unscaledWidth, bounds.y); - var radius:Number = _totalWidth * 0.5 / Math.PI; - var gap:Number = this.gap; - _centeredItemDegrees = Number.MAX_VALUE; - - var scrollPosition:Number = target.horizontalScrollPosition; - var totalWidthSoFar:Number = 0; - // Subtract the half width of the first element from totalWidthSoFar: - var iter:LayoutIterator = new LayoutIterator(target); - var el:ILayoutElement = iter.nextElement(); - if (!el) - return; - totalWidthSoFar -= el.getPreferredBoundsWidth(false /*postTransform*/) / 2; - - // Set the 3D Matrix for all the elements: - iter.reset(); - while (el = iter.nextElement()) - { - // Size the item, no need to position it, since we'd set the computed matrix - // which defines the position. - el.setLayoutBoundsSize(NaN, NaN, false /*postTransform*/); - var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); - var elementHeight:Number = el.getLayoutBoundsHeight(false /*postTransform*/); - var degrees:Number = 360 * (totalWidthSoFar + elementWidth/2 - scrollPosition) / _totalWidth; - - // Remember which item is centered, this is used during scrolling - var curDegrees:Number = degrees % 360; - if (Math.abs(curDegrees) < Math.abs(_centeredItemDegrees)) - { - _centeredItemDegrees = curDegrees; - _centeredItemIndex = iter.curIndex; - _centeredItemCircumferenceBegin = totalWidthSoFar - gap; - _centeredItemCircumferenceEnd = totalWidthSoFar + elementWidth + gap; - } - - // Calculate and set the 3D Matrix - var m:Matrix3D = new Matrix3D(); - m.appendTranslation(-elementWidth/2, -elementHeight/2 + radius * _axis.z, -radius * _axis.y ); - m.appendRotation(-degrees, _axis); - m.appendTranslation(unscaledWidth/2, unscaledHeight/2, radius * _axis.y); - el.setLayoutMatrix3D(m, false /*triggerLayout*/); - - // Update the layer for a correct z-order - if (el is IVisualElement) - IVisualElement(el).depth = Math.abs( Math.floor(180 - Math.abs(degrees % 360)) ); - - // Move on to next item - totalWidthSoFar += elementWidth + gap; - } - } - - private function scrollPositionFromCenterToNext(next:Boolean):Number - { - var iter:LayoutIterator = new LayoutIterator(target, _centeredItemIndex); - var el:ILayoutElement = next ? iter.nextElementWrapped() : iter.prevElementWrapped(); - if (!el) - return 0; - - var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); - - var value:Number; - if (next) - { - if (_centeredItemDegrees > 0.1) - return (_centeredItemCircumferenceEnd + _centeredItemCircumferenceBegin) / 2; - - value = _centeredItemCircumferenceEnd + elementWidth/2; - if (value > _totalWidth) - value -= _totalWidth; - } - else - { - if (_centeredItemDegrees < -0.1) - return (_centeredItemCircumferenceEnd + _centeredItemCircumferenceBegin) / 2; - - value = _centeredItemCircumferenceBegin - elementWidth/2; - if (value < 0) - value += _totalWidth; - } - return value; - } - - override protected function scrollPositionChanged():void - { - if (target) - target.invalidateDisplayList(); - } - - override public function getHorizontalScrollPositionDelta(navigationUnit:uint):Number - { - var g:GroupBase = target; - if (!g || g.numElements == 0) - return 0; - - var value:Number; - - switch (navigationUnit) - { - case NavigationUnit.LEFT: - { - value = target.horizontalScrollPosition - 30; - if (value < 0) - value += _totalWidth; - return value - target.horizontalScrollPosition; - } - - case NavigationUnit.RIGHT: - { - value = target.horizontalScrollPosition + 30; - if (value > _totalWidth) - value -= _totalWidth; - return value - target.horizontalScrollPosition; - } - - case NavigationUnit.PAGE_LEFT: - return scrollPositionFromCenterToNext(false) - target.horizontalScrollPosition; - - case NavigationUnit.PAGE_RIGHT: - return scrollPositionFromCenterToNext(true) - target.horizontalScrollPosition; - - case NavigationUnit.HOME: - return 0; - - case NavigationUnit.END: - return _totalWidth; - - default: - return 0; - } - } - - /** - * @private - */ - override public function getScrollPositionDeltaToElement(index:int):Point - { - var layoutTarget:GroupBase = target; - if (!layoutTarget) - return null; - - var gap:Number = this.gap; - var totalWidthSoFar:Number = 0; - var iter:LayoutIterator = new LayoutIterator(layoutTarget); - - var el:ILayoutElement = iter.nextElement(); - if (!el) - return null; - totalWidthSoFar -= el.getLayoutBoundsWidth(false /*postTransform*/) / 2; - - iter.reset(); - while (null != (el = iter.nextElement()) && iter.curIndex <= index) - { - var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); - totalWidthSoFar += gap + elementWidth; - } - return new Point(totalWidthSoFar - elementWidth / 2 -gap - layoutTarget.horizontalScrollPosition, 0); - } - - /** - * @private - */ - override public function updateScrollRect(w:Number, h:Number):void - { - var g:GroupBase = target; - if (!g) - return; - - if (clipAndEnableScrolling) - { - // Since scroll position is reflected in our 3D calculations, - // always set the top-left of the srcollRect to (0,0). - g.scrollRect = new Rectangle(0, verticalScrollPosition, w, h); - } - else - g.scrollRect = null; - } -} -} - -import mx.core.ILayoutElement; - -import spark.components.supportClasses.GroupBase; - -class LayoutIterator -{ - private var _curIndex:int; - private var _numVisited:int = 0; - private var totalElements:int; - private var _target:GroupBase; - private var _loopIndex:int = -1; - private var _useVirtual:Boolean; - - public function get curIndex():int - { - return _curIndex; - } - - public function LayoutIterator(target:GroupBase, index:int=-1):void - { - totalElements = target.numElements; - _target = target; - _curIndex = index; - _useVirtual = _target.layout.useVirtualLayout; - } - - public function nextElement():ILayoutElement - { - while (_curIndex < totalElements - 1) - { - var el:ILayoutElement = _useVirtual ? _target.getVirtualElementAt(++_curIndex) : - _target.getElementAt(++_curIndex); - if (el && el.includeInLayout) - { - ++_numVisited; - return el; - } - } - return null; - } - - public function prevElement():ILayoutElement - { - while (_curIndex > 0) - { - var el:ILayoutElement = _useVirtual ? _target.getVirtualElementAt(--_curIndex) : - _target.getElementAt(--_curIndex); - if (el && el.includeInLayout) - { - ++_numVisited; - return el; - } - } - return null; - } - - public function nextElementWrapped():ILayoutElement - { - if (_loopIndex == -1) - _loopIndex = _curIndex; - else if (_loopIndex == _curIndex) - return null; - - var el:ILayoutElement = nextElement(); - if (el) - return el; - else if (_curIndex == totalElements - 1) - _curIndex = -1; - return nextElement(); - } - - public function prevElementWrapped():ILayoutElement - { - if (_loopIndex == -1) - _loopIndex = _curIndex; - else if (_loopIndex == _curIndex) - return null; - - var el:ILayoutElement = prevElement(); - if (el) - return el; - else if (_curIndex == 0) - _curIndex = totalElements; - return prevElement(); - } - - public function reset():void - { - _curIndex = -1; - _numVisited = 0; - _loopIndex = -1; - } - - public function get numVisited():int - { - return _numVisited; - } -} - +package +{ + +import flash.geom.Matrix; +import flash.geom.Matrix3D; +import flash.geom.Point; +import flash.geom.Rectangle; +import flash.geom.Vector3D; + +import mx.core.ILayoutElement; +import mx.core.IVisualElement; + +import spark.components.supportClasses.GroupBase; +import spark.core.NavigationUnit; +import spark.layouts.supportClasses.LayoutBase; + +public class WheelLayout extends LayoutBase +{ + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + public function WheelLayout() + { + super(); + } + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // gap + //---------------------------------- + + private var _gap:Number = 0; + + /** + * The gap between the items + */ + public function get gap():Number + { + return _gap; + } + + public function set gap(value:Number):void + { + _gap = value; + var layoutTarget:GroupBase = target; + if (layoutTarget) + { + layoutTarget.invalidateSize(); + layoutTarget.invalidateDisplayList(); + } + } + + //---------------------------------- + // axisAngle + //---------------------------------- + + /** + * @private + * The total width of all items, including gap space. + */ + private var _totalWidth:Number; + + /** + * @private + * Cache which item is currently in view, to facilitate scrollposition delta calculations + */ + private var _centeredItemIndex:int = 0; + private var _centeredItemCircumferenceBegin:Number = 0; + private var _centeredItemCircumferenceEnd:Number = 0; + private var _centeredItemDegrees:Number = 0; + + /** + * The axis to tilt the 3D wheel + */ + private var _axis:Vector3D = new Vector3D(0, 1, 0.1); + + /** + * The angle to tilt the axis of the wheel + */ + public function set axisAngle(value:Number):void + { + _axis = new Vector3D(0, Math.cos(Math.PI * value /180), Math.sin(Math.PI * value /180)); + var layoutTarget:GroupBase = target; + if (layoutTarget) + { + layoutTarget.invalidateSize(); + layoutTarget.invalidateDisplayList(); + } + } + + /** + * @private + * Given the radius of the sphere, return the radius of the + * projected sphere. Uses the projection matrix of the + * layout target to calculate. + */ + private function projectSphere(radius:Number, radius1:Number):Number + { + var fl:Number = target.transform.perspectiveProjection.focalLength; + var alpha:Number = Math.asin( radius1 / (radius + fl) ); + return fl * Math.tan(alpha) * 2; + } + + /** + * @private + * Given the totalWidth, maxHeight and maxHalfWidthDiagonal, calculate the bounds of the items + * on screen. Uses the projection matrix of the layout target to calculate. + */ + private function projectBounds(totalWidth:Number, maxWidth:Number, maxHeight:Number, maxHalfWidthDiagonal:Number):Point + { + // Use the the total width as a circumference of an imaginary circle which we will use to + // align the items in 3D: + var radius:Number = _totalWidth * 0.5 / Math.PI; + + // Now since we are going to arrange all the items along circle, middle of the item being the tangent point, + // we need to calculate the minimum bounding circle. It is easily calculated from the maximum width item: + var boundingRadius:Number = Math.sqrt(radius * radius + 0.25 * maxWidth * maxWidth); + + var projectedBoundsW:Number = _axis.z * _axis.z * (maxHalfWidthDiagonal + 2 * radius) + + projectSphere(radius, boundingRadius ) * _axis.y * _axis.y; + + var projectedBoundsH:Number = Math.abs(_axis.z) * (maxHalfWidthDiagonal + 2 * radius) + + maxHeight * _axis.y * _axis.y; + + return new Point(projectedBoundsW + 10, projectedBoundsH + 10); + } + + /** + * @private + * Iterates through all the items, calculates the projected bounds on screen, updates _totalWidth member variable. + */ + private function calculateBounds():Point + { + // Calculate total width: + _totalWidth = 0; + + var maxHeight:Number = 0; + var maxWidth:Number = 0; + var maxD:Number = 0; + + // Add up all the widths + var iter:LayoutIterator = new LayoutIterator(target); + var el:ILayoutElement; + while (el = iter.nextElement()) + { + var preferredWidth:Number = el.getPreferredBoundsWidth(false /*postTransform*/); + var preferredHeight:Number = el.getPreferredBoundsHeight(false /*postTransform*/); + + // Add up item width + _totalWidth += preferredWidth; + + // Max up item size + maxWidth = Math.max(maxWidth, preferredWidth); + maxHeight = Math.max(maxHeight, preferredHeight); + + maxD = Math.max(maxD, Math.sqrt(preferredWidth * preferredWidth / 4 + + preferredHeight * preferredHeight)); + } + + // Add up the gap + _totalWidth += gap * iter.numVisited; + + // Project + return projectBounds(_totalWidth, maxWidth, maxHeight, maxD); + } + + //-------------------------------------------------------------------------- + // + // Overridden methods: LayoutBase + // + //-------------------------------------------------------------------------- + + /** + * @private + */ + override public function set target(value:GroupBase):void + { + // Make sure that if layout is swapped out, we clean up + if (!value && target) + { + target.maintainProjectionCenter = false; + + var iter:LayoutIterator = new LayoutIterator(target); + var el:ILayoutElement; + while (el = iter.nextElement()) + { + el.setLayoutMatrix(new Matrix(), false /*triggerLayout*/); + } + } + + super.target = value; + + // Make sure we turn on projection the first time the layout + // gets assigned to the group + if (target) + target.maintainProjectionCenter = true; + } + + override public function measure():void + { + var bounds:Point = calculateBounds(); + + target.measuredWidth = bounds.x; + target.measuredHeight = bounds.y; + } + + override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + // Get the bounds, this will also update _totalWidth + var bounds:Point = calculateBounds(); + + // Update the content size + target.setContentSize(_totalWidth + unscaledWidth, bounds.y); + var radius:Number = _totalWidth * 0.5 / Math.PI; + var gap:Number = this.gap; + _centeredItemDegrees = Number.MAX_VALUE; + + var scrollPosition:Number = target.horizontalScrollPosition; + var totalWidthSoFar:Number = 0; + // Subtract the half width of the first element from totalWidthSoFar: + var iter:LayoutIterator = new LayoutIterator(target); + var el:ILayoutElement = iter.nextElement(); + if (!el) + return; + totalWidthSoFar -= el.getPreferredBoundsWidth(false /*postTransform*/) / 2; + + // Set the 3D Matrix for all the elements: + iter.reset(); + while (el = iter.nextElement()) + { + // Size the item, no need to position it, since we'd set the computed matrix + // which defines the position. + el.setLayoutBoundsSize(NaN, NaN, false /*postTransform*/); + var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); + var elementHeight:Number = el.getLayoutBoundsHeight(false /*postTransform*/); + var degrees:Number = 360 * (totalWidthSoFar + elementWidth/2 - scrollPosition) / _totalWidth; + + // Remember which item is centered, this is used during scrolling + var curDegrees:Number = degrees % 360; + if (Math.abs(curDegrees) < Math.abs(_centeredItemDegrees)) + { + _centeredItemDegrees = curDegrees; + _centeredItemIndex = iter.curIndex; + _centeredItemCircumferenceBegin = totalWidthSoFar - gap; + _centeredItemCircumferenceEnd = totalWidthSoFar + elementWidth + gap; + } + + // Calculate and set the 3D Matrix + var m:Matrix3D = new Matrix3D(); + m.appendTranslation(-elementWidth/2, -elementHeight/2 + radius * _axis.z, -radius * _axis.y ); + m.appendRotation(-degrees, _axis); + m.appendTranslation(unscaledWidth/2, unscaledHeight/2, radius * _axis.y); + el.setLayoutMatrix3D(m, false /*triggerLayout*/); + + // Update the layer for a correct z-order + if (el is IVisualElement) + IVisualElement(el).depth = Math.abs( Math.floor(180 - Math.abs(degrees % 360)) ); + + // Move on to next item + totalWidthSoFar += elementWidth + gap; + } + } + + private function scrollPositionFromCenterToNext(next:Boolean):Number + { + var iter:LayoutIterator = new LayoutIterator(target, _centeredItemIndex); + var el:ILayoutElement = next ? iter.nextElementWrapped() : iter.prevElementWrapped(); + if (!el) + return 0; + + var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); + + var value:Number; + if (next) + { + if (_centeredItemDegrees > 0.1) + return (_centeredItemCircumferenceEnd + _centeredItemCircumferenceBegin) / 2; + + value = _centeredItemCircumferenceEnd + elementWidth/2; + if (value > _totalWidth) + value -= _totalWidth; + } + else + { + if (_centeredItemDegrees < -0.1) + return (_centeredItemCircumferenceEnd + _centeredItemCircumferenceBegin) / 2; + + value = _centeredItemCircumferenceBegin - elementWidth/2; + if (value < 0) + value += _totalWidth; + } + return value; + } + + override protected function scrollPositionChanged():void + { + if (target) + target.invalidateDisplayList(); + } + + override public function getHorizontalScrollPositionDelta(navigationUnit:uint):Number + { + var g:GroupBase = target; + if (!g || g.numElements == 0) + return 0; + + var value:Number; + + switch (navigationUnit) + { + case NavigationUnit.LEFT: + { + value = target.horizontalScrollPosition - 30; + if (value < 0) + value += _totalWidth; + return value - target.horizontalScrollPosition; + } + + case NavigationUnit.RIGHT: + { + value = target.horizontalScrollPosition + 30; + if (value > _totalWidth) + value -= _totalWidth; + return value - target.horizontalScrollPosition; + } + + case NavigationUnit.PAGE_LEFT: + return scrollPositionFromCenterToNext(false) - target.horizontalScrollPosition; + + case NavigationUnit.PAGE_RIGHT: + return scrollPositionFromCenterToNext(true) - target.horizontalScrollPosition; + + case NavigationUnit.HOME: + return 0; + + case NavigationUnit.END: + return _totalWidth; + + default: + return 0; + } + } + + /** + * @private + */ + override public function getScrollPositionDeltaToElement(index:int):Point + { + var layoutTarget:GroupBase = target; + if (!layoutTarget) + return null; + + var gap:Number = this.gap; + var totalWidthSoFar:Number = 0; + var iter:LayoutIterator = new LayoutIterator(layoutTarget); + + var el:ILayoutElement = iter.nextElement(); + if (!el) + return null; + totalWidthSoFar -= el.getLayoutBoundsWidth(false /*postTransform*/) / 2; + + iter.reset(); + while (null != (el = iter.nextElement()) && iter.curIndex <= index) + { + var elementWidth:Number = el.getLayoutBoundsWidth(false /*postTransform*/); + totalWidthSoFar += gap + elementWidth; + } + return new Point(totalWidthSoFar - elementWidth / 2 -gap - layoutTarget.horizontalScrollPosition, 0); + } + + /** + * @private + */ + override public function updateScrollRect(w:Number, h:Number):void + { + var g:GroupBase = target; + if (!g) + return; + + if (clipAndEnableScrolling) + { + // Since scroll position is reflected in our 3D calculations, + // always set the top-left of the srcollRect to (0,0). + g.scrollRect = new Rectangle(0, verticalScrollPosition, w, h); + } + else + g.scrollRect = null; + } +} +} + +import mx.core.ILayoutElement; + +import spark.components.supportClasses.GroupBase; + +class LayoutIterator +{ + private var _curIndex:int; + private var _numVisited:int = 0; + private var totalElements:int; + private var _target:GroupBase; + private var _loopIndex:int = -1; + private var _useVirtual:Boolean; + + public function get curIndex():int + { + return _curIndex; + } + + public function LayoutIterator(target:GroupBase, index:int=-1):void + { + totalElements = target.numElements; + _target = target; + _curIndex = index; + _useVirtual = _target.layout.useVirtualLayout; + } + + public function nextElement():ILayoutElement + { + while (_curIndex < totalElements - 1) + { + var el:ILayoutElement = _useVirtual ? _target.getVirtualElementAt(++_curIndex) : + _target.getElementAt(++_curIndex); + if (el && el.includeInLayout) + { + ++_numVisited; + return el; + } + } + return null; + } + + public function prevElement():ILayoutElement + { + while (_curIndex > 0) + { + var el:ILayoutElement = _useVirtual ? _target.getVirtualElementAt(--_curIndex) : + _target.getElementAt(--_curIndex); + if (el && el.includeInLayout) + { + ++_numVisited; + return el; + } + } + return null; + } + + public function nextElementWrapped():ILayoutElement + { + if (_loopIndex == -1) + _loopIndex = _curIndex; + else if (_loopIndex == _curIndex) + return null; + + var el:ILayoutElement = nextElement(); + if (el) + return el; + else if (_curIndex == totalElements - 1) + _curIndex = -1; + return nextElement(); + } + + public function prevElementWrapped():ILayoutElement + { + if (_loopIndex == -1) + _loopIndex = _curIndex; + else if (_loopIndex == _curIndex) + return null; + + var el:ILayoutElement = prevElement(); + if (el) + return el; + else if (_curIndex == 0) + _curIndex = totalElements; + return prevElement(); + } + + public function reset():void + { + _curIndex = -1; + _numVisited = 0; + _loopIndex = -1; + } + + public function get numVisited():int + { + return _numVisited; + } +} + http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5ed4d983/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/sample.mxml ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/sample.mxml b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/sample.mxml index 4ba1a44..11cc4df 100644 --- a/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/sample.mxml +++ b/TourDeFlex/TourDeFlex_content/flex4.0/CustomLayout-FlickrWheel/srcview/src/sample.mxml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more @@ -17,67 +17,67 @@ limitations under the License. --> -<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" - xmlns:s="library://ns.adobe.com/flex/spark" - xmlns:mx="library://ns.adobe.com/flex/mx" - xmlns:my="*" minWidth="600" minHeight="350" - applicationComplete="requestPhotos()" backgroundColor="0x323232" viewSourceURL="srcview/index.html"> - - <fx:Script> - <![CDATA[ - import mx.collections.ArrayCollection; - import mx.rpc.events.ResultEvent; - - import spark.components.Group; - import spark.components.supportClasses.GroupBase; - import spark.effects.animation.MotionPath; - - [Bindable] - private var photoFeed:ArrayCollection; - - private function requestPhotos():void { - var params:Object = new Object(); - params.format = 'rss_200_enc'; - params.tags = searchTerms.text; - photoService.send(params); - } - - private function photoHandler(event:ResultEvent):void { - photoFeed = event.result.rss.channel.item as ArrayCollection; - } - ]]> - </fx:Script> - - <fx:Declarations> - <s:HTTPService id="photoService" - url="http://api.flickr.com/services/feeds/photos_public.gne" - result="photoHandler(event)" /> - </fx:Declarations> - - <s:layout> - <s:VerticalLayout paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10"/> - </s:layout> - - <s:HGroup verticalAlign="middle"> - <s:Label text="Flickr tags or search terms:" color="0xFFFFFF"/> - <s:TextInput id="searchTerms" - enter="requestPhotos()" text="bugs" /> - <s:Button label="Search" - click="requestPhotos()" /> - <!-- The slider to control the axis angle --> - <s:HSlider id="axisSlider" minimum="-90" maximum="90" - value="10" liveDragging="true" width="300"/> - </s:HGroup> - - <s:List width="700" height="225" - dataProvider="{photoFeed}" - itemRenderer="FlickrThumbnail" - id="theList"> - - <s:layout> - <my:WheelLayout gap="20" axisAngle="{axisSlider.value}"/> - </s:layout> - </s:List> - - -</s:Application> +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + xmlns:my="*" minWidth="600" minHeight="350" + applicationComplete="requestPhotos()" backgroundColor="0x323232" viewSourceURL="srcview/index.html"> + + <fx:Script> + <![CDATA[ + import mx.collections.ArrayCollection; + import mx.rpc.events.ResultEvent; + + import spark.components.Group; + import spark.components.supportClasses.GroupBase; + import spark.effects.animation.MotionPath; + + [Bindable] + private var photoFeed:ArrayCollection; + + private function requestPhotos():void { + var params:Object = new Object(); + params.format = 'rss_200_enc'; + params.tags = searchTerms.text; + photoService.send(params); + } + + private function photoHandler(event:ResultEvent):void { + photoFeed = event.result.rss.channel.item as ArrayCollection; + } + ]]> + </fx:Script> + + <fx:Declarations> + <s:HTTPService id="photoService" + url="http://api.flickr.com/services/feeds/photos_public.gne" + result="photoHandler(event)" /> + </fx:Declarations> + + <s:layout> + <s:VerticalLayout paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10"/> + </s:layout> + + <s:HGroup verticalAlign="middle"> + <s:Label text="Flickr tags or search terms:" color="0xFFFFFF"/> + <s:TextInput id="searchTerms" + enter="requestPhotos()" text="bugs" /> + <s:Button label="Search" + click="requestPhotos()" /> + <!-- The slider to control the axis angle --> + <s:HSlider id="axisSlider" minimum="-90" maximum="90" + value="10" liveDragging="true" width="300"/> + </s:HGroup> + + <s:List width="700" height="225" + dataProvider="{photoFeed}" + itemRenderer="FlickrThumbnail" + id="theList"> + + <s:layout> + <my:WheelLayout gap="20" axisAngle="{axisSlider.value}"/> + </s:layout> + </s:List> + + +</s:Application>