http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.json ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.json b/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.json new file mode 100755 index 0000000..89bdd43 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.json @@ -0,0 +1,236 @@ +{ catalog : [ + + { "productId" :"1", + "name" : "Andrew Brilliam", + "description" : "15 years experience. 8 years with Flex. Specializing in Text Layout Framework", + "price" : 60.00, + "image" : "assets/pic/abrilliam.jpg", + "experience" : 15, + "blazeds" : false, + "mobile" : false, + "video" : false, + "highlight1" : "Text Layout Framework", + "highlight2" : "Parsley" + }, + + { "productId" : "2", + "name" : "Annette Kotter", + "description" : "Specializing in custom components. PHP servers.", + "price" : 55, + "image" : "assets/pic/akotter.jpg", + "experience" : 3, + "blazeds" : true, + "mobile" : false, + "video" : false, + "highlight1" : "Custom Components", + "highlight2" : "PHP" + }, + + { "productId" : "3", + "name" : "Ben Crater", + "description" : "Specializing in BlazeDS backends.", + "price" : 55, + "image" : "assets/pic/bcrater.jpg", + "experience" : 4, + "blazeds" : true, + "mobile" : false, + "video" : false, + "highlight1" : "BlazeDS", + "highlight2" : "Remote Object" + }, + + { "productId" : "4", + "name" : "Beth Leporte", + "description" : "BlazeDS or PHP servers. Multimedia messagin.", + "price" : 70.00, + "image" : "assets/pic/bleporte.jpg", + "experience" : 6, + "blazeds" : true, + "mobile" : false, + "video" : false, + "highlight1" : "Multimedia messaging", + "highlight2" : "BlazeDS" + }, + + { "productId" : "5", + "name" : "Brad Van Brocklin", + "description" : "Emphasis on mobile application development", + "price" : 80, + "image" : "assets/pic/bvanbrocklin.jpg", + "experience" : 6, + "blazeds" : false, + "mobile" : true, + "video" : false, + "highlight1" : "Mobile", + "highlight2" : "Android" + }, + + { "productId" : "6", + "name" : "Carlos Carpenter", + "description" : "Built many mobile apps and video apps.", + "price" : 80, + "image" : "assets/pic/ccarpenter.jpg", + "experience" : 4, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Mobile", + "highlight2" : "Video" + }, + + { "productId" : "7", + "name" : "Christine Lampberto", + "description" : "7 years experience building mobile applications.", + "price" : 90, + "image" : "assets/pic/clampberto.jpg", + "experience" : 7, + "blazeds" : true, + "mobile" : true, + "video" : false, + "highlight1" : "BlazeDS", + "highlight2" : "Mobile" + }, + + { "productId" : "8", + "name" : "Dee Dee Avenon", + "description" : "I've been making video apps for over 5 years and mobile apps for about 3 years.", + "price" : 100, + "image" : "assets/pic/davenon.jpg", + "experience" : 10, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "9", + "name" : "Denise McGoyal", + "description" : "Specializing in video sharing applicaions. MObile apps too.", + "price" : 100, + "image" : "assets/pic/dmcgoyal.jpg", + "experience" : 5, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "10", + "name" : "Daniel Willhelm", + "description" : "I'm into mobile apps, video apps and social apps.", + "price" : 70, + "image" : "assets/pic/dwillhelm.jpg", + "experience" : 90, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "11", + "name" : "Eunice Sunderland", + "description" : "My recent focus is on mobile apps, but I have considerable experience in video apps as well.", + "price" : 150, + "image" : "assets/pic/esunderland.jpg", + "experience" : 30, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "12", + "name" : "Jane Proctor", + "description" : "I've been developing mobile companion apps for the past 3 years.", + "price" : 75, + "image" : "assets/pic/jproctor.jpg", + "experience" : 6, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "13", + "name" : "Mark Fields", + "description" : "Video is my favorite thing. Mobile is also a favorite.", + "price" : 60, + "image" : "assets/pic/mfields.jpg", + "experience" : 70, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "14", + "name" : "Patricia Dempsey", + "description" : "I've been cranking out mobile apps for the past 6 years. A few have involved video as well.", + "price" : 120, + "image" : "assets/pic/pdempsey.jpg", + "experience" : 7, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "15", + "name" : "Paul Trandep", + "description" : "I've been working on a mobile app that incorporates music. It just shipped so now I'm looking for the next fun thing to work on.'", + "price" : 50, + "image" : "assets/pic/ptranep.jpg", + "experience" : 6, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "16", + "name" : "Roscoe Crawley", + "description" : "My main specialty is in BlazeDS connected to Flex.", + "price" : 59, + "image" : "assets/pic/rcrawley.jpg", + "experience" : 9, + "blazeds" : true, + "mobile" : false, + "video" : false, + "highlight1" : "BlazeDS", + "highlight2" : "Remote Object" + }, + + { "productId" : "17", + "name" : "Renee Dreifus", + "description" : "I can do it all: BlazeDS, Mobile, Video.", + "price" : 79, + "image" : "assets/pic/rdreifus.jpg", + "experience" : 90, + "blazeds" : true, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + }, + + { "productId" : "18", + "name" : "Tina Wong", + "description" : "I've been developing Flex apps since 1.5. Most of my recent work has been on mobile apps.", + "price" : 109, + "image" : "assets/pic/twong.jpg", + "experience" : 9, + "blazeds" : false, + "mobile" : true, + "video" : true, + "highlight1" : "Video Applications", + "highlight2" : "Mobile Applications" + +];
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.xml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.xml b/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.xml new file mode 100755 index 0000000..423e177 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/data/catalog.xml @@ -0,0 +1,256 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + 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. + + --> +<catalog> + + <product productId="1"> + <name>Andrew Brilliam</name> + <description>15 years experience. 8 years with Flex. Specializing in Text Layout Framework</description> + <price>60.00</price> + <image>assets/pic/abrilliam.jpg</image> + <experience>15</experience> + <blazeds>false</blazeds> + <mobile>false</mobile> + <video>false</video> + <highlight1>Text Layout Framework</highlight1> + <highlight2>Parsley</highlight2> + </product> + + <product productId="2"> + <name>Annette Kotter</name> + <description>Specializing in custom components. PHP servers.</description> + <price>55</price> + <image>assets/pic/akotter.jpg</image> + <experience>3</experience> + <blazeds>true</blazeds> + <mobile>false</mobile> + <video>false</video> + <highlight1>Custom Components</highlight1> + <highlight2>PHP</highlight2> + </product> + + <product productId="3"> + <name>Ben Crater</name> + <description>Specializing in BlazeDS backends.</description> + <price>55</price> + <image>assets/pic/bcrater.jpg</image> + <experience>4</experience> + <blazeds>true</blazeds> + <mobile>false</mobile> + <video>false</video> + <highlight1>BlazeDS</highlight1> + <highlight2>Remote Object</highlight2> + </product> + + <product productId="4"> + <name>Beth Leporte</name> + <description>BlazeDS or PHP servers. Multimedia messagin.</description> + <price>70.00</price> + <image>assets/pic/bleporte.jpg</image> + <experience>6</experience> + <blazeds>true</blazeds> + <mobile>false</mobile> + <video>false</video> + <highlight1>Multimedia messaging</highlight1> + <highlight2>BlazeDS</highlight2> + </product> + + <product productId="5"> + <name>Brad Van Brocklin</name> + <description>Emphasis on mobile application development</description> + <price>80</price> + <image>assets/pic/bvanbrocklin.jpg</image> + <experience>6</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>false</video> + <highlight1>Mobile</highlight1> + <highlight2>Android</highlight2> + </product> + + <product productId="6"> + <name>Carlos Carpenter</name> + <description>Built many mobile apps and video apps.</description> + <price>80</price> + <image>assets/pic/ccarpenter.jpg</image> + <experience>4</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Mobile</highlight1> + <highlight2>Video</highlight2> + </product> + + <product productId="7"> + <name>Christine Lampberto</name> + <description>7 years experience building mobile applications.</description> + <price>90</price> + <image>assets/pic/clampberto.jpg</image> + <experience>7</experience> + <blazeds>true</blazeds> + <mobile>true</mobile> + <video>false</video> + <highlight1>BlazeDS</highlight1> + <highlight2>Mobile</highlight2> + </product> + + <product productId="8"> + <name>Dee Dee Avenon</name> + <description>I've been making video apps for over 5 years and mobile apps for about 3 years.</description> + <price>100</price> + <image>assets/pic/davenon.jpg</image> + <experience>10</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="9"> + <name>Denise McGoyal</name> + <description>Specializing in video sharing applicaions. MObile apps too.</description> + <price>100</price> + <image>assets/pic/dmcgoyal.jpg</image> + <experience>5</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="10"> + <name>Daniel Willhelm</name> + <description>I'm into mobile apps, video apps and social apps.</description> + <price>70</price> + <image>assets/pic/dwillhelm.jpg</image> + <experience>90</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="11"> + <name>Eunice Sunderland</name> + <description>My recent focus is on mobile apps, but I have considerable experience in video apps as well.</description> + <price>150</price> + <image>assets/pic/esunderland.jpg</image> + <experience>30</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="12"> + <name>Jane Proctor</name> + <description>I've been developing mobile companion apps for the past 3 years.</description> + <price>75</price> + <image>assets/pic/jproctor.jpg</image> + <experience>6</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="13"> + <name>Mark Fields</name> + <description>Video is my favorite thing. Mobile is also a favorite.</description> + <price>60</price> + <image>assets/pic/mfields.jpg</image> + <experience>70</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="14"> + <name>Patricia Dempsey</name> + <description>I've been cranking out mobile apps for the past 6 years. A few have involved video as well.</description> + <price>120</price> + <image>assets/pic/pdempsey.jpg</image> + <experience>7</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="15"> + <name>Paul Trandep</name> + <description>I've been working on a mobile app that incorporates music. It just shipped so now I'm looking for the next fun thing to work on.'</description> + <price>50</price> + <image>assets/pic/ptranep.jpg</image> + <experience>6</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="16"> + <name>Roscoe Crawley</name> + <description>My main specialty is in BlazeDS connected to Flex.</description> + <price>59</price> + <image>assets/pic/rcrawley.jpg</image> + <experience>9</experience> + <blazeds>true</blazeds> + <mobile>false</mobile> + <video>false</video> + <highlight1>BlazeDS</highlight1> + <highlight2>Remote Object</highlight2> + </product> + + <product productId="17"> + <name>Renee Dreifus</name> + <description>I can do it all: BlazeDS, Mobile, Video.</description> + <price>79</price> + <image>assets/pic/rdreifus.jpg</image> + <experience>90</experience> + <blazeds>true</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + + <product productId="18"> + <name>Tina Wong</name> + <description>I've been developing Flex apps since 1.5. Most of my recent work has been on mobile apps.</description> + <price>109</price> + <image>assets/pic/twong.jpg</image> + <experience>9</experience> + <blazeds>false</blazeds> + <mobile>true</mobile> + <video>true</video> + <highlight1>Video Applications</highlight1> + <highlight2>Mobile Applications</highlight2> + </product> + +</catalog> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/main.css ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/main.css b/examples/flexjs/FlexJSStore/src/main/flex/main.css new file mode 100755 index 0000000..f678354 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/main.css @@ -0,0 +1,100 @@ +/* +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +*/ + +@namespace basic "library://ns.apache.org/flexjs/basic"; + +/* +//---------------------------- +// Global styles +//---------------------------- +*/ +.global { + IStatesImpl: ClassReference("org.apache.flex.core.StatesWithTransitionsImpl"); + color: #170505; + fillAlphas: 1.00, 1.00; /* last pair are for OVER state */ + fillColors: #FFFFFF, #DDDDDD, #FFFFFF, #EEEEEE; +} + +global { + IStatesImpl: ClassReference("org.apache.flex.core.StatesWithTransitionsImpl"); +} + +/* +//---------------------------- +// Type selectors +//---------------------------- + +HRule +{ + color: #666666; +} +*/ + +/* +//---------------------------- +// Named styles +//---------------------------- +*/ +.glass { + borderColor: #767473; + fillAlphas: .60, .60, .60, .60; + fillColors: #888888, #F3F3F3, #9E9E9E, #FCFCFC; + highlightAlphas: .07, .45; +} + +.glassSlider +{ + fillAlphas: .80, .80, .80, .80; + fillColors: #F3F3F3, #BBBBBB, #FCFCFC, #CCCCCC; +} + +.listItem +{ + paddingLeft: 4; + paddingRight: 4; + horizontalGap: 5; + verticalAlign: "middle"; + backgroundColor: #FFFFFF; + backgroundAlpha: .5; + borderStyle: "outset"; +} + +basic|Container +{ + IBeadLayout: ClassReference("org.apache.flex.html.beads.layouts.BasicLayout"); +} + +.sectionHeader +{ + fontWeight: "bold"; + fontSize: 11; +} + +.homeSection +{ + cornerRadius: 4; + borderStyle: "solid"; +} + +.hoverButton +{ + height: 20px; +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/CatalogTitleButtons.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/CatalogTitleButtons.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/CatalogTitleButtons.mxml new file mode 100755 index 0000000..75830ef --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/CatalogTitleButtons.mxml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:HContainer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + currentState="showFilter"> + <js:style> + <js:SimpleCSSStyles verticalAlign="middle" + paddingTop="0" + paddingBottom="0" /> + </js:style> + <js:beads> + <js:ParentDocumentBead id="pdb" /> + <js:ContainerDataBinding /> + <js:LayoutChangeNotifier watchedProperty="{viewCart.text}" initialValue="#FFFFFF" /> + </js:beads> + <fx:Script> + <![CDATA[ + [Bindable] + public var cartCount:int; + + private function rollOverLabel(event:MouseEvent):void + { + try { + Label(event.target).className = "catalogTitleButtonHighlighted"; + } catch (e:Error) {} + } + + private function rollOutLabel(event:MouseEvent):void + { + Label(event.target).className = "catalogTitleButtonDeselected"; + } + ]]> + </fx:Script> + <fx:Binding source="ProductCatalogPanel(pdb.parentDocument).cartCount" destination="cartCount" /> + <!-- two-way binding between the states of panel title buttons and the product view state --> + <fx:Binding source="ProductsView(ProductCatalogPanel(pdb.parentDocument).pdb.parentDocument).currentState" destination="currentState" /> + <fx:Binding destination="ProductsView(ProductCatalogPanel(pdb.parentDocument).pdb.parentDocument).currentState" source="currentState" /> + + <js:Label id="findPhones" text="Find Developers" click="currentState = 'showFilter'" + className.showFilter="catalogTitleButtonSelected" + className.showCart="catalogTitleButtonDeselected" + rollOver.showCart="rollOverLabel(event)" + rollOut.showCart="rollOutLabel(event)"/> + <js:VRule height="{findPhones.height * .75}" alpha=".75" style="color:#333333" /> + <js:Label id="viewCart" text="View Cart ({cartCount} items)" click="currentState = 'showCart'" + className.showFilter="catalogTitleButtonDeselected" + className.showCart="catalogTitleButtonSelected" + rollOver.showFilter="rollOverLabel(event)" + rollOut.showFilter="rollOutLabel(event)"/> + + <js:states> + <js:State name="showFilter" /> + <js:State name="showCart" /> + </js:states> +</js:HContainer> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/Grip.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/Grip.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/Grip.mxml new file mode 100755 index 0000000..abd3ce5 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/Grip.mxml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Container xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + width="17" height="100%" > + <js:style> + <js:SimpleCSSStyles paddingTop="10" /> + </js:style> + + <fx:Script> + <![CDATA[ + [Bindable] + public var gripTip:String; + + [Bindable] + public var gripIcon:String; + ]]> + </fx:Script> + <js:beads> + <js:ContainerDataBinding /> + <js:OneFlexibleChildVerticalLayout flexibleChild="grip" /> + </js:beads> + + <js:Image id="icon" source="{gripIcon}" /> + <js:Image id="grip" source="assets/grip.png" > + <js:beads> + <js:ToolTipBead toolTip="{gripTip}" /> + </js:beads> + </js:Image> + +</js:Container> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCart.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCart.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCart.mxml new file mode 100755 index 0000000..3469806 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCart.mxml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Container xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + xmlns:productsView="productsView.*" + > + <js:style> + <js:SimpleCSSStyles + paddingTop="8" + paddingBottom="8" + paddingRight="4" + paddingLeft="4" /> + </js:style> + <js:beads> + <js:ContainerDataBinding /> + <js:OneFlexibleChildVerticalLayout id="flexLayout" flexibleChild="productList" /> + </js:beads> + <fx:Script> + <![CDATA[ + + import org.apache.flex.html.SimpleAlert; + + import samples.flexstore.Product; + import samples.flexstore.ProductListEvent; + + [Bindable] + public var numProducts:int=0; + + [Bindable] + private var total:Number = 0; + + private const SHIPPING:Number = 1.99; + + private function productListEventHandler(event:ProductListEvent):void + { + switch (event.type) + { + case ProductListEvent.ADD_PRODUCT: + event.product.qty = 0; + //fall through into the same logic as dup + case ProductListEvent.DUPLICATE_PRODUCT: + event.product.qty++; + //total += event.product.price; + total = total + event.product.price; + numProducts++; + break; + case ProductListEvent.PRODUCT_QTY_CHANGE: + case ProductListEvent.REMOVE_PRODUCT: + var items:Array = productList.items; + total = 0; + numProducts = 0; + for (var i:int=0; i < items.length; i++) + { + var product:Product = items[i].product; + //total += product.qty * product.price; + //numProducts += product.qty; + total = total + product.qty * product.price; + numProducts = numProducts + product.qty; + } + break; + default: + break; + } + } + + ]]> + </fx:Script> + <fx:Declarations> + <js:CurrencyFormatter currencySymbol="$" id="cf" fractionalDigits="2"/> + </fx:Declarations> + + <js:Label width="100%" text="Your Shopping Cart" className="sectionHeader"/> + + <productsView:ProductList id="productList" width="100%" + newItemStartX="-100" newItemStartY="-100" + addProduct="productListEventHandler(event)" + duplicateProduct="productListEventHandler(event)" + productQtyChange="productListEventHandler(event)" + removeProduct="productListEventHandler(event)" + showQuantity="true" /> + + <js:Container style="right:0" id="totalContainer"> + <js:beads> + <js:VerticalColumnLayout numColumns="2" /> + </js:beads> + <js:Label text="Total:" /> + <js:Label width="70" text="{cf.format(total)}" id="lblTotal" style="textAlign:'right'"/> + + <js:Label text="Service Fee:" /> + <js:Label width="70" text="{cf.format(numProducts * SHIPPING)}" id="lblFee" style="textAlign:'right'"/> + + <js:Label text="Grand Total:" style="fontWeight:'bold'" /> + <js:Label width="70" text="{cf.format(total + (numProducts * SHIPPING))}" id="lblGrandTotal" style="textAlign:'right'"/> + + </js:Container> + + <js:TextButton text="Submit Order" click="SimpleAlert.show('This feature is not implemented in this sample', 'Submit Order')" + style="right:0"/> + +</js:Container> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanel.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanel.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanel.mxml new file mode 100755 index 0000000..3e04263 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanel.mxml @@ -0,0 +1,546 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + implements="org.apache.flex.core.IDragInitiator" + xmlns:productsView="productsView.*" + currentState="browse" + title="SpaceHolder" + title.browse="Browse" + title.compare="Product Comparison" + title.details="Product Details" + className="catalogPanel" + > + + <fx:Metadata> + [Event(name="purchase", type="samples.flexstore.ProductThumbEvent")] + [Event(name="compare", type="samples.flexstore.ProductThumbEvent")] + [Event(name="details", type="samples.flexstore.ProductThumbEvent")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + import org.apache.flex.core.IUIBase; + import org.apache.flex.effects.Effect; + import org.apache.flex.effects.Fade; + import org.apache.flex.effects.Move; + import org.apache.flex.effects.Parallel; + import org.apache.flex.effects.Tween; + import org.apache.flex.events.DragEvent; + import org.apache.flex.events.Event; + import org.apache.flex.collections.LazyCollection; + + import samples.flexstore.Product; + import samples.flexstore.ProductFilter; + import samples.flexstore.ProductFilterEvent; + import samples.flexstore.ProductThumbEvent; + + + private var accepted:Object = new Object(); + private var thumbnails:Array; + private var filterCount:int; + private var thumbnailState:String = 'browse'; //either 'browse' or 'compare' + + [Bindable] + public var cartCount:int; + + //----------------------------- + // catalog + //----------------------------- + + private var _catalog:LazyCollection; + + [Bindable] + public function set catalog(c:LazyCollection):void + { + _catalog = c; + createThumbnails(); + } + + public function get catalog():LazyCollection + { + return _catalog; + } + + //---------------------------------------------------------------------- + // methods + //---------------------------------------------------------------------- + + private function createThumbnails():void + { + var i:int; //variables are hoisted up in scope so declare here to avoid warning + if (thumbnails != null) + { + for (i=0; i < thumbnails.length; i++) + { + thumbContentGroup.removeElement(thumbnails[i]); + } + } + + var row:int = 0; + var col:int = -1; + var n:int = catalog.length; + thumbnails = new Array(n); + filterCount = n; + + for (i=0; i < n; i++) + { + var thumb:ProductCatalogThumbnail = new ProductCatalogThumbnail(); + thumb.x = 0; + thumb.y = 0; + thumbnails[i] = thumb; + // thumbnails[i].showInAutomationHierarchy = true; + thumb.product = catalog.getItemAt(i) as Product; + accepted[thumb.product.productId.toString()] = true; + thumbContentGroup.addElement(thumb); + thumb.addEventListener(ProductThumbEvent.PURCHASE, productThumbEventHandler); + thumb.addEventListener(ProductThumbEvent.COMPARE, productThumbEventHandler); + thumb.addEventListener(ProductThumbEvent.DETAILS, productThumbEventHandler); + thumb.addEventListener(DragEvent.DRAG_START,thumbDragStartHandler); + } + + var lastMove:Effect = layoutCatalog(); + if (lastMove) + { + lastMove.addEventListener(Tween.TWEEN_UPDATE, updateLayout); + lastMove.addEventListener(Tween.TWEEN_END, updateLayout); + } + } + + private function updateLayout(event:org.apache.flex.events.Event):void + { + thumbContentGroup.dispatchEvent(new org.apache.flex.events.Event("layoutNeeded")); + } + + private function thumbDragStartHandler(event:MouseEvent):void + { + if (DragMouseController.dragging == false) + { + var thumb:ProductCatalogThumbnail = event.target as ProductCatalogThumbnail; + DragEvent.dragSource = thumb.product; + + var di:ProductCatalogThumbnail = new ProductCatalogThumbnail(); + di.product = thumb.product; + di.currentState = thumb.currentState; + DragMouseController.dragImage = di; + + DragEvent.dragInitiator = this; + } + } + + public function filter(productFilter:ProductFilter, live:Boolean):void + { + currentState = "browse"; + thumbnailState = "browse"; + var count:int=0; + var n:int = thumbnails.length; + var targets:Array = []; + for (var i:int = 0; i < n; i++) + { + var thumb:ProductCatalogThumbnail = thumbnails[i]; + var product:Product = thumb.product; + if (productFilter.accept(product)) + { + accepted[product.productId.toString()] = true; + thumb.alpha = 1; + count++; + } + else + { + accepted[product.productId.toString()] = false; + if (live) + { + thumb.alpha = .1; + } + else if (thumb.alpha == 1) //only fade if we hadn't started + { + targets.push(thumb); + } + } + } + productFilter.count = count; + filterCount = count; + + if (targets.length > 0) + { + var p:Parallel = new Parallel(); + n = targets.length; + for (i = 0; i < n; i++) + { + var fadeOut:Fade = new Fade(targets[i] as IUIBase); + fadeOut.alphaFrom = 1; + fadeOut.alphaTo = .1; + p.addChild(fadeOut); + } + p.play(); + p.addEventListener(Effect.EFFECT_END, + function(event:org.apache.flex.events.Event):void + { + layoutCatalog(); + }); + } + else if (!live) + { + layoutCatalog(); + } + } + + private function layoutCatalog():Effect + { + var tileWidth:Number; + var tileHeight:Number; + var numCols:int; + + if (filterCount > 9 || currentState == "compare") + { + numCols = 4; + tileWidth = ProductCatalogThumbnail.COL_WIDTH_4; + tileWidth = currentState == "compare" + ? ProductCatalogThumbnail.COMPARE_WIDTH + : ProductCatalogThumbnail.COL_WIDTH_4 + tileHeight = currentState == "compare" + ? height - 4 + : ProductCatalogThumbnail.COL_HEIGHT_4; + } + else if (filterCount > 4) + { + numCols = 3; + tileWidth = ProductCatalogThumbnail.COL_WIDTH_3; + tileHeight = ProductCatalogThumbnail.COL_HEIGHT_3; + } + else if (filterCount <= 9) + { + numCols = 2; + tileWidth = ProductCatalogThumbnail.COL_WIDTH_2; + tileHeight = ProductCatalogThumbnail.COL_HEIGHT_2; + } + else + { + } + + var row:int = 0; + var col:int = -1; + + var move:Move = null; + + var n:int = catalog.length; + for (var i:int = 0 ; i < n ; i++) + { + var product:Product = catalog.getItemAt(i) as Product; + var thumb:ProductCatalogThumbnail = thumbnails[i]; + if (accepted[product.productId.toString()]) + { + thumb.currentState = "x" + numCols + "cols"; + col++; + if (col > numCols - 1) + { + row++; + col = 0; + } + + var xTo:Number = col * (tileWidth + ProductCatalogThumbnail.HORIZONTAL_GAP); + var yTo:Number = row * (tileHeight + ProductCatalogThumbnail.VERTICAL_GAP); + + // If the thumbnail is already visible + // animate it to its new position. + if (thumb.visible) + { + // Animate only if the position is different + // from its current position. + if (thumb.x != xTo || thumb.y != yTo) + { + move = new Move(thumb); + move.xTo = xTo; + move.yTo = yTo; + move.play(); + } + } + + // If the thumbnail was not previously visible, sets its + // x and y coordinates. We'll make it reappear after all + // the visible thumbnails have reached their new position. + else + { + thumb.x = xTo; + thumb.y = yTo; +// thumb.includeInLayout = true; + } + } + else + { + thumb.visible = false; +// thumb.includeInLayout = false; + } + } + + if (!move) + { + // No visible thumbnails were animated to a new position; + // fade in newly selected thumbnails right away. + fadeInThumbnails(); + } + else + { + //since movement is happening get the scrollbar back to the top + scv.verticalScrollPosition = 0; + // Fade in newly selected thumbnails after the last + // visible thumbnail has moved to its new position. + move.addEventListener(Effect.EFFECT_END, + function(event:org.apache.flex.events.Event):void + { + fadeInThumbnails(); + }); + } + thumbContentGroup.dispatchEvent(new org.apache.flex.events.Event("layoutNeeded")); + //return the last move to watch + return move; + } + + //return the last effect so we could add effectEnd handler if desired + private function fadeInThumbnails():void + { + var n:int = thumbnails.length; + var targets:Array = []; + for (var i:int = 0; i < n ; i++) + { + var thumb:ProductCatalogThumbnail = thumbnails[i]; + if (accepted[thumb.product.productId.toString()] && !thumb.visible) + { + thumb.alpha = 0; + thumb.visible = true; + targets.push(thumb); + } + } + if (targets.length > 0) + { + n = targets.length; + for (i = 0; i < n; i++) + { + var effect:Fade = new Fade(targets[i] as IUIBase); + effect.alphaTo = 1; + effect.play(); + } + } + } + + private function showDetails(product:Product):void + { + if (currentState == "details") + { + details.product = product; + return; + } + + var row:int = -1; + + //should be computed using border metrics instead of hard-coding the 20, but... + var xTo:Number = thumbContentGroup.width - ProductCatalogThumbnail.COL_WIDTH_4 - 20; + var yTo:Number; + + var move:Move; + var first:Boolean = true; + var selectedThumb:ProductCatalogThumbnail; + + var n:int = thumbnails.length; + for (var i:int = 0; i < n; i++) + { + var thumb:ProductCatalogThumbnail = thumbnails[i]; + if (thumb.visible) + { + row++; + yTo = row * (ProductCatalogThumbnail.COL_HEIGHT_4 + ProductCatalogThumbnail.VERTICAL_GAP); + + thumb.currentState = "x4cols"; + + if (thumb.x != xTo || thumb.y != yTo) + { + move = new Move(thumb); + if (first) + { + move.addEventListener(Effect.EFFECT_END, + function(event:org.apache.flex.events.Event):void + { + details.product = product; + currentState = "details"; + }); + + first = false; + } + move.xTo = xTo; + move.yTo = yTo; + move.play(); + } + + if (thumb.product == product) + { + selectedThumb = thumb; + } + } + } + if (selectedThumb != null) + { + //make sure that the selected thumb is visible in the list on the right + move.addEventListener(Effect.EFFECT_END, + function(e:org.apache.flex.events.Event):void + { + var curpos:int = scv.verticalScrollPosition; + if (selectedThumb.y < curpos) + { + scv.verticalScrollPosition = y; + } + else if (selectedThumb.y + ProductCatalogThumbnail.COL_HEIGHT_4 > curpos + thumbContentGroup.height) + { + //this logic doesn't seem to be perfect but it will do + var diff:int = selectedThumb.y - (curpos + thumbContentGroup.height) + scv.verticalScrollPosition += diff + ProductCatalogThumbnail.COL_HEIGHT_4 + ProductCatalogThumbnail.VERTICAL_GAP; + } + }); + } + + } + + private function productThumbEventHandler(event:ProductThumbEvent):void + { + if (event.type == ProductThumbEvent.DETAILS) + { + showDetails(event.product); + } + else if (event.type == ProductThumbEvent.BROWSE) + { + if (thumbnailState == "browse") + { + currentState = "browse"; + layoutCatalog(); + } + else + { + compare(); + } + } + else + { + dispatchEvent(event); + } + } + + public function compare(toCompare:Array=null):void + { + currentState = "compare"; + thumbnailState = "compare"; + if (toCompare != null) + { + var n:int = thumbnails.length; + for (var i:int = 0; i < n; i++) + { + accepted[thumbnails[i].product.productId.toString()] = false; + } + for (i=0; i < toCompare.length; i++) + { + accepted[toCompare[i].productId.toString()] = true; + } + } + var lastEffect:Effect = layoutCatalog(); + if (lastEffect != null) + { + lastEffect.addEventListener(Effect.EFFECT_END, + function (event:org.apache.flex.events.Event):void + { + setCompareState(); + }); + } + else + { + setCompareState(); + } + } + + private function setCompareState():void + { + //avoid an issue if the user clicks quickly where we move into + //compare state even though we're no longer in compare + if (currentState == "compare") + { + var n:int = thumbnails.length; + for (var i:int = 0; i < n; i++) + { + var thumb:ProductCatalogThumbnail = thumbnails[i]; + if (accepted[thumb.product.productId.toString()]) + { + thumb.currentState = "compare"; + } + } + + } + } + + public function acceptingDrop(dropTarget:Object, type:String):void + { + + } + + public function acceptedDrop(dropTarget:Object, type:String):void + { + + } + + ]]> + </fx:Script> + + <js:beads> + <js:ContainerDataBinding /> + <js:VerticalLayout /> + <js:DragMouseController id="dragger" /> + <js:ParentDocumentBead id="pdb" /> + <js:PanelView> + <js:titleBar> + <js:TitleBar height="20" > + <js:style> + <js:SimpleCSSStyles backgroundColor="0xA65904" /> + </js:style> + <js:beads> + <productsView:ProductCatalogPanelTitleBarView /> + </js:beads> + </js:TitleBar> + </js:titleBar> + </js:PanelView> + </js:beads> + <js:Container width="100%" height="100%"> + <js:Container id="thumbContentGroup" width="100%" height="100%"> + <js:beads> + <js:ScrollingViewport id="scv" /> + </js:beads> + </js:Container> + <productsView:ProductDetails id="details" y="0" + width="{ProductCatalogThumbnail.COL_WIDTH_4 * 3}" + height="100%" + visible="false" + visible.details="true" + compare="productThumbEventHandler(event)" + purchase="productThumbEventHandler(event)" + browse="productThumbEventHandler(event)" /> + </js:Container> + + <js:states> + <js:State name="browse" /> + <js:State name="compare" /> + <js:State name="details" /> + </js:states> + +</js:Panel> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanelTitleBarView.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanelTitleBarView.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanelTitleBarView.mxml new file mode 100755 index 0000000..f2cb397 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogPanelTitleBarView.mxml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:MXMLBeadView xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + xmlns:productsView="productsView.*" + > + <fx:Script> + <![CDATA[ + import org.apache.flex.html.TitleBar; + import org.apache.flex.core.ITitleBarModel; + import org.apache.flex.core.UIBase; + import org.apache.flex.events.Event; + + private function clickHandler():void + { + var newEvent:org.apache.flex.events.Event = new org.apache.flex.events.Event('close',true); + UIBase(_strand).dispatchEvent(newEvent) + } + ]]> + </fx:Script> + <js:beads> + <js:MXMLBeadViewDataBinding /> + <js:ParentDocumentBead id="pdb" /> + <js:LayoutChangeNotifier watchedProperty="{buttons.width}" /> + </js:beads> + <js:Label id="titleLabel" text="{ITitleBarModel(model).title}" + /> + <js:CloseButton id="closeButton" click="clickHandler()" + visible="{ITitleBarModel(model).showCloseButton}"; + /> + <productsView:CatalogTitleButtons id="buttons" /> +</js:MXMLBeadView> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogThumbnail.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogThumbnail.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogThumbnail.mxml new file mode 100755 index 0000000..1abc428 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductCatalogThumbnail.mxml @@ -0,0 +1,220 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Container xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + width="{COL_WIDTH_4}" height="{COL_HEIGHT_4}" height.compare="502" + width.x4cols="{COL_WIDTH_4}" height.x4cols="{COL_HEIGHT_4}" + width.x3cols="{COL_WIDTH_3}" height.x3cols="{COL_HEIGHT_3}" + width.x2cols="{COL_WIDTH_2}" height.x2cols="{COL_HEIGHT_2}" + rollOver="rollOverHandler(event)" + rollOut="rollOutHandler(event)" + mouseDown="mouseDownHandler(event)" + mouseMove="mouseMoveHandler(event)" + mouseUp="mouseUpHandler(event)" + click="clickHandler(event)" + currentState="x4cols" + > + <!-- automationName="{product.name}" --> + <js:beads> + <js:ContainerDataBinding /> + <js:LayoutChangeNotifier watchedProperty="{borderStyles.borderColor}" initialValue="#FFFFFF" /> + </js:beads> + <js:style> + <js:BindableCSSStyles id="borderStyles" borderStyle="solid" borderWidth="1" + borderColor="#FFFFFF" backgroundColor="#FFFFFF"/> + </js:style> + <fx:Metadata> + [Event(name="purchase", type="samples.flexstore.ProductThumbEvent")] + [Event(name="compare", type="samples.flexstore.ProductThumbEvent")] + [Event(name="details", type="samples.flexstore.ProductThumbEvent")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + + import org.apache.flex.events.*; + import org.apache.flex.utils.PointUtils; + + import samples.flexstore.Product; + import samples.flexstore.ProductThumbEvent; + + public static const COL_WIDTH_4:int = 162; + public static const COL_HEIGHT_4:int = 122; + public static const COL_WIDTH_3:int = 217; + public static const COL_HEIGHT_3:int = 165; + public static const COL_WIDTH_2:int = 327; + public static const COL_HEIGHT_2:int = 250; + public static const COMPARE_WIDTH:int = 162; + public static const HORIZONTAL_GAP:int = 2; + public static const VERTICAL_GAP:int = 3; + + [Bindable] + public var product:Product; + + private function rollOverHandler(event:MouseEvent):void + { + borderStyles.borderColor = "#CCCCCC"; + //style["dropShadowEnabled"] = true; + buttons.visible = true; + } + + private function rollOutHandler(event:MouseEvent):void + { + borderStyles.borderColor = "#FFFFFF"; + //style["dropShadowEnabled"] = false; + buttons.visible = false; + } + + private var dragStartPoint:Point; + + public function mouseDownHandler(event:MouseEvent):void + { + if (event.target != purchase && + event.target != compare && + event.target != details) + { + dragStartPoint = new Point(event.clientX, event.clientY); + } + } + + public function mouseMoveHandler(event:MouseEvent):void + { + if (dragStartPoint != null) + { + var dragEvent:DragEvent = new DragEvent(DragEvent.DRAG_START, true); + dragEvent.clientX = dragStartPoint.x; + dragEvent.clientY = dragStartPoint.y; + dragEvent.buttonDown = true; + dispatchEvent(dragEvent); + + rollOutHandler(event); + + dragStartPoint = null; + } + } + + public function mouseUpHandler(event:MouseEvent):void + { + if (dragStartPoint != null) + { + dragStartPoint = null; + } + } + + public function clickHandler(event:org.apache.flex.events.MouseEvent):void + { + if (event.target != purchase && + event.target != compare && + event.target != details) + { + dispatchEvent(new ProductThumbEvent(ProductThumbEvent.DETAILS, product)); + } + } + + ]]> + </fx:Script> + <fx:Declarations> + <js:CurrencyFormatter currencySymbol="$" id="cf" fractionalDigits="2"/> + </fx:Declarations> + + <js:VContainer id="vb" width="100%" height="100%"> + <js:style> + <js:SimpleCSSStyles paddingLeft="6" paddingTop="4" paddingRight="8" paddingBottom="4" /> + <!-- gap="0"> --> + </js:style> + + + <js:Label text="{product.name}" style="fontWeight:bold"/> + + <js:HContainer width="100%" > + <js:style> + <js:SimpleCSSStyles paddingTop="0" /> <!-- gap="4 -->" + </js:style> + + <js:Image id="img" height="45" width="45" + width.x3cols="60" height.x3cols="60" + width.x2cols="60" height.x2cols="60" + source="{product.image}" /> + + <js:VContainer id="descr" height="100%" > + <js:style> + <js:SimpleCSSStyles paddingTop="0" right="0" /> <!-- gap="0" --> + </js:style> + <js:Label text="{product.featureString}" width="60" height="48" /> + <js:Label text="{cf.format(product.price)}" style="fontWeight:bold"/> + <js:Spacer height="4"/> + <js:Label text="{product.highlight1}" style="color:#EE8D0C" includeIn="x3cols, x2cols"/> + <js:Label text="{product.highlight2}" style="color:#EE8D0C" includeIn="x3cols, x2cols"/> + </js:VContainer> + + </js:HContainer> + + <js:Spacer height="8"/> + + <js:Label id="compYears" text="Years: {product.experience}" includeIn="compare"/> + <js:Label id="compBlaze" text="BlazeDS: {product.blazeds}" includeIn="compare"/> + <js:Label id="compMobile" text="Mobile: {product.mobile}" includeIn="compare"/> + <js:Label id="compVideo" text="Video: {product.video}" includeIn="compare"/> + <js:Label id="compHigh1" text="Highlight: {product.highlight1}" includeIn="compare"/> + <js:Label id="compHigh2" text="Highlight: {product.highlight2}" includeIn="compare"/> + <js:Label text="Description:" includeIn="compare"/> + <js:MultilineLabel id="compDesc" text="{product.description}" width="100%" includeIn="compare"/> + </js:VContainer> + + + <js:VContainer id="buttons" visible="false" width="30"> + <js:style> + <js:SimpleCSSStyles paddingRight="8" right="8" top="12" /> <!-- gap="4" --> + </js:style> + <js:ImageButton id="purchase" source="assets/button_cart_empty.png" className="hoverButton" + click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.PURCHASE, product))" + width="30"> + <js:beads> + <js:ToolTipBead toolTip="Add to cart"/> + </js:beads> + </js:ImageButton> + <js:ImageButton id="compare" source="assets/button_compare.png" className="hoverButton" + click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.COMPARE, product))" + width="30"> + <js:beads> + <js:ToolTipBead toolTip="Add to compare list"/> + </js:beads> + </js:ImageButton> + <js:ImageButton id="details" source="assets/button_details.png" className="hoverButton" + click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.DETAILS, product))" + width="30"> + <js:beads> + <js:ToolTipBead toolTip="Show details"/> + </js:beads> + </js:ImageButton> + </js:VContainer> + + <js:states> + + <js:State name="compare" /> + + <js:State name="x4cols" /> + + <js:State name="x3cols" /> + + <js:State name="x2cols"/> + </js:states> + +</js:Container> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductDetails.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductDetails.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductDetails.mxml new file mode 100755 index 0000000..309cb41 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductDetails.mxml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Container xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + xmlns:productsView="productsView.*" + > + <js:beads> + <js:ContainerDataBinding /> + </js:beads> + + <fx:Metadata> + [Event(name="purchase", type="samples.flexstore.ProductThumbEvent")] + [Event(name="compare", type="samples.flexstore.ProductThumbEvent")] + [Event(name="browse", type="samples.flexstore.ProductThumbEvent")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + + import samples.flexstore.Product; + import samples.flexstore.ProductThumbEvent; + + private var _product:Product; + + [Bindable] + public function get product():Product + { + return _product; + } + + public function set product(p:Product):void + { + _product = p; + tn.selectedIndex = 0; + } + + ]]> + </fx:Script> + + <fx:Declarations> + <js:CurrencyFormatter currencySymbol="$" id="cf" fractionalDigits="2"/> + </fx:Declarations> + + <js:states> + <js:State name="Features" /> + <js:State name="Support" /> + </js:states> + + <js:transitions> + <js:Transition> + <js:Fade /> + </js:Transition> + </js:transitions> + + <js:ButtonBar id="tn" width="100%" change="currentState = tn.selectedItem as String"> + <js:dataProvider> + <fx:Array> + <fx:String>Features</fx:String> + <fx:String>Support</fx:String> + </fx:Array> + </js:dataProvider> + </js:ButtonBar> + <js:Container > + <js:style> + <js:SimpleCSSStyles left="4" right="8" top="34" bottom="4" /> + </js:style> + + + <js:VContainer includeIn="Features" > + <js:style> + <!--<js:SimpleCSSStyles gap="8"--> + <js:SimpleCSSStyles + left="8" top="8" right="8" bottom="8"/> + </js:style> + <js:Container style="left:0px;right:0px"> + + <js:Image id="img" width="101" height="101" source="{product.image}"/> + + <js:VContainer id="descr" > + <js:style> + <js:SimpleCSSStyles top="0" left="105" right="0" bottom="20" /> + <!--<js:SimpleCSSStyles paddingTop="0" gap="4" />--> + </js:style> + + <js:Label text="{product.name}" style="fontSize:11;fontWeight:'bold'"/> + + <js:Label text="{product.featureString}" width="80" height="48" /> + + <js:Label text="{product.highlight1}" style="color:#EE8D0C"/> + + <js:Label text="{product.highlight2}" style="color:#EE8D0C"/> + + <js:Label text="{cf.format(product.price)}" style="fontWeight:'bold'"/> + + </js:VContainer> + </js:Container> + + <js:Label id="descriptionText" style="left:0px;right:0px;bottom:0px" text="{product.description}"/> + + </js:VContainer> + + <productsView:ProductSupport width="100%" height="100%" includeIn="Support" /> + + </js:Container> + + <js:VContainer> + <js:style> + <js:SimpleCSSStyles marginTop="4" right="16" top="36" /> + </js:style> + <js:Spacer width="100%"/> + <js:ImageButton id="purchase" source="assets/button_cart_empty.png" click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.PURCHASE, product))" width="30"> + <js:beads> + <js:ToolTipBead toolTip="Add to cart"/> + </js:beads> + </js:ImageButton> + <js:ImageButton id="compare" source="assets/button_compare.png" click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.COMPARE, product))" width="30"> + <js:beads> + <js:ToolTipBead toolTip="Add to compare list"/> + </js:beads> + </js:ImageButton> + <js:ImageButton id="tiles" source="assets/button_tiles.png" click="dispatchEvent(new ProductThumbEvent(ProductThumbEvent.BROWSE, product));" width="30"> + <js:beads> + <js:ToolTipBead toolTip="Back to thumbnail view"/> + </js:beads> + </js:ImageButton> + </js:VContainer> + +</js:Container> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductFilterPanel.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductFilterPanel.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductFilterPanel.mxml new file mode 100755 index 0000000..fc2f535 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductFilterPanel.mxml @@ -0,0 +1,215 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:VContainer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + xmlns:productsView="productsView.*" + xmlns:flexstore="samples.flexstore.*" + height="100%" + currentState="showingThumbnails" + initComplete="series.selectedIndex = 0"> + <js:style> + <js:SimpleCSSStyles paddingLeft="4" + paddingRight="12" + paddingTop="12" + paddingBottom="8" + /> + + </js:style> + + <fx:Metadata> + [Event(name="filter", type="samples.flexstore.ProductFilterEvent")] + [Event("compare")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + import org.apache.flex.html.Slider; + import org.apache.flex.html.SimpleAlert; + import samples.flexstore.ProductFilterEvent; + + private var thumbBeingPressed:Boolean; + + private function dispatchFilter():void + { + var event:ProductFilterEvent = + new ProductFilterEvent(filter, thumbBeingPressed); + dispatchEvent(event); + currentState = "showingThumbnails"; + } + + private function sliderValue(values:Array, index:int):Number + { + return values[index]; + } + + private function productRemoved():void + { + if (currentState == "showingComparison") + { + if (productList.items.length == 0) + { + dispatchFilter(); + } + else + { + attemptCompare(); + } + } + } + + private function attemptCompare():void + { + if (productList.items.length > 0) + { + dispatchEvent(new Event("compare")); + currentState = "showingComparison"; + } + else + { + SimpleAlert.show("There are no items to compare.", "Compare"); + } + } + + ]]> + </fx:Script> + <fx:Declarations> + <flexstore:ProductFilter id="filter"> + <flexstore:experience>{series.selectedItem}</flexstore:experience> + <flexstore:minPrice>{loPrice.value}</flexstore:minPrice> + <flexstore:maxPrice>{hiPrice.value}</flexstore:maxPrice> + <flexstore:blazeds>{cbBlazeDS.selected}</flexstore:blazeds> + <flexstore:mobile>{cbMobile.selected}</flexstore:mobile> + <flexstore:video>{cbVideo.selected}</flexstore:video> + </flexstore:ProductFilter> + + <js:CurrencyFormatter currencySymbol="$" id="cf"/> + + </fx:Declarations> + <js:beads> + <js:ContainerDataBinding /> + </js:beads> + + <js:Label text="Find" className="sectionHeader"/> + + <js:Container width="100%"> + <js:beads> + <js:FlexibleFirstChildHorizontalLayout /> + </js:beads> + <js:TextInput className="glass" width="100%"/> + <js:TextButton className="glass" text="Go" click="SimpleAlert.show('This feature is not implemented in this sample', 'Find')"/> + </js:Container> + + <js:Spacer height="18"/> + + <js:HRule width="100%"/> + + <js:Spacer height="8"/> + + <js:HContainer> + <js:style> + <js:SimpleCSSStyles paddingTop="0" paddingLeft="0" verticalAlign="bottom" /> + </js:style> + <js:Label text="Filter" className="sectionHeader"/> + <js:Label text="({filter.count} items selected)" > + <js:style> + <js:SimpleCSSStyles fontWeight="bold" /> + <!--<js:SimpleCSSStyles color="{getStyle('themeColor')}" fontWeight="bold" />--> + </js:style> + </js:Label> + </js:HContainer> + + <js:Spacer height="8"/> + + <js:Label text="Years of Experience"/> + + <js:DropDownList id="series" className="glass" width="140" change="dispatchFilter();"> + <js:dataProvider> + <fx:Array> + <fx:String>All</fx:String> + <fx:String>3</fx:String> + <fx:String>5</fx:String> + <fx:String>7</fx:String> + <fx:String>9</fx:String> + </fx:Array> + </js:dataProvider> + </js:DropDownList> + + <js:Spacer height="18"/> + + <js:Label text="Price"/> + + <!--<s:HSlider id="priceSlider" className="glassSlider" minimum="0" maximum="200" tickInterval="10" snapInterval="10" + width="100%" thumbCount="2" values="[0,200]" labels="[$0,$200]" liveDragging="true" dataTipFormatFunction="{cf.format}" + change="dispatchFilter()" + thumbPress="thumbBeingPressed=true" + thumbRelease="thumbBeingPressed=false;dispatchFilter()" + />--> + <js:HContainer id="nsholder" width="100%"> + <js:NumericStepper width="48%" id="loPrice" minimum="0" maximum="{hiPrice.value}" value="0" valueChange="dispatchFilter()" /> + <js:NumericStepper width="48%" id="hiPrice" minimum="{loPrice.value}" maximum="200" value="200" valueChange="dispatchFilter()" /> + </js:HContainer> + + <js:Spacer height="18"/> + + <js:Label text="Required Features"/> + + <js:Spacer height="4"/> + + <js:CheckBox id="cbBlazeDS" className="glass" text="BlazeDS" click="dispatchFilter();"/> + <js:Spacer height="4"/> + <js:CheckBox id="cbMobile" className="glass" text="Mobile" click="dispatchFilter()"/> + <js:Spacer height="4"/> + <js:CheckBox id="cbVideo" className="glass" text="Video" click="dispatchFilter();"/> + + <js:Spacer height="18"/> + + <js:HRule width="100%"/> + + <js:Spacer height="8"/> + + <js:HContainer> + <js:Label text="Compare" className="sectionHeader"/> + <js:Label text="(Drag items here to compare)" className="instructions"/> + </js:HContainer> + + + <js:Spacer height="4"/> + + <!-- height is maxItems * ProductListItem.HEIGHT + 2px border --> + <productsView:ProductList id="productList" height="{productList.maxItems * ProductListItem.HEIGHT + 2}" width="100%" + newItemStartX="300" newItemStartY="-100" maxItems="4" + removeProduct="productRemoved()"/> + + <js:Spacer height="8"/> + + <js:ImageAndTextButton id="compareButton" className="glass" + click.showingThumbnails="attemptCompare()" + click.showingComparison="dispatchFilter()" + text.showingComparison="Back to thumbnail view" + text.showingThumbnails="Compare Items" + image.showingThumbnails="assets/icon_compare.png" + image.showingComparison="assets/icon_tiles.png" /> + + <js:states> + <js:State name="showingThumbnails" /> + <js:State name="showingComparison" /> + </js:states> + +</js:VContainer> http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/e75059f7/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductList.mxml ---------------------------------------------------------------------- diff --git a/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductList.mxml b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductList.mxml new file mode 100755 index 0000000..7351e06 --- /dev/null +++ b/examples/flexjs/FlexJSStore/src/main/flex/productsView/ProductList.mxml @@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +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. + +--> +<js:Container xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:js="library://ns.apache.org/flexjs/basic" + > + <js:style> + <js:SimpleCSSStyles borderStyle="solid" borderWidth="1" backgroundColor="#BCB29F" /> + </js:style> + <!-- need a background color for drag and drop but can set alpha to 0 --> + + <fx:Metadata> + [Event(name="addProduct", type="samples.flexstore.ProductListEvent")] + [Event(name="duplicateProduct", type="samples.flexstore.ProductListEvent")] + [Event(name="productQtyChange", type="samples.flexstore.ProductListEvent")] + [Event(name="removeProduct", type="samples.flexstore.ProductListEvent")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + import org.apache.flex.effects.Effect; + import org.apache.flex.effects.Move; + import org.apache.flex.effects.Sequence; + import org.apache.flex.core.DropType; + import org.apache.flex.core.IUIBase; + import org.apache.flex.events.DragEvent; + + import samples.flexstore.Product; + import samples.flexstore.ProductListEvent; + + public var items:Array; + + public var newItemStartX:int; + public var newItemStartY:int; + [Bindable] + public var maxItems:int = 0; + public var showQuantity:Boolean; + + private var playingEffects:Object = new Object(); + + public function addProduct(product:Product):void + { + if (items == null) + items = []; + + var index:int = indexOf(product.productId); + var event:ProductListEvent; + var item:ProductListItem; + + if (index != -1) + { + item = items[index] as ProductListItem; + //if we don't keep track of what's playing a double-click can + //cause the list item to keep rising + if (playingEffects[item.uid] == null) + { + var jump:Sequence = new Sequence(); + var m1:Move = new Move(item) + m1.yBy = -5; + var m2:Move = new Move(item) + m2.yBy = 5; + jump.addChild(m1); + jump.addChild(m2); + jump.duration = 150; + playingEffects[item.uid] = jump; + jump.addEventListener(Effect.EFFECT_END, function(event:Event):void + { + delete playingEffects[item.uid]; + }); + jump.play(); + } + event = new ProductListEvent(ProductListEvent.DUPLICATE_PRODUCT); + event.product = item.product; + dispatchEvent(event); + } + else + { + index = items.length; + if (maxItems <= 0 || index < maxItems) + { + item = new ProductListItem(); + if (showQuantity) + { + item.currentState = 'showQuantity'; + } + item.product = product; + item.percentWidth = 100; + item.addEventListener(ProductListEvent.REMOVE_PRODUCT, removeItemHandler); + items[index] = item; + viewport.addElement(item); + layoutItems(index, true); + event = new ProductListEvent(ProductListEvent.ADD_PRODUCT); + event.product = product; + dispatchEvent(event); + } + } + } + + public function getProducts():Array + { + var ret:Array = []; + for (var i:int = 0; i < items.length; i++) + { + ret[i] = ProductListItem(items[i]).product; + } + return ret; + } + + private function removeItemHandler(event:Event):void + { + var item:ProductListItem = event.target as ProductListItem; + var index:int = indexOf(item.product.productId); + items.splice(index, 1); + viewport.removeElement(item); + layoutItems(index); + } + + private function layoutItems(startIndex:int, scrollToBottom:Boolean=false):void + { + var n:int = items.length; + var e:Move; + for (var i:int = startIndex; i < n ; i++) + { + var item:ProductListItem = items[i]; + var yTo:Number = i * (item.height); + //still need to prevent items that are already in motion from getting + //jumpy + if (playingEffects[item.uid] == null) + { + e = new Move(item); + if (item.x == 0 && item.y == 0) + { + e.xFrom = newItemStartX; + e.yFrom = newItemStartY; + } + + e.xTo = 0; + e.yTo = yTo; + playingEffects[item.uid] = e; + e.addEventListener(Effect.EFFECT_END, function(event:Event):void + { + delete playingEffects[item.uid]; + }); + e.play(); + } + else + { + playingEffects[item.uid].pause(); + playingEffects[item.uid].yTo = yTo; + playingEffects[item.uid].play(); + } + } + //get the last event and if we should scroll make sure we can validate + //and scroll to maxVPosition + if (scrollToBottom) + { + e.addEventListener(Effect.EFFECT_END, function(event:Event):void + { + //TODO scrollingView.model.verticalScrollPosition = scrollingView.maxVerticalScrollPosition; + }); + } + } + + private function indexOf(productId:int):int + { + var index:int = -1; + + var n:int = items.length; + for (var i:int = 0; i < items.length; i++) + { + if (ProductListItem(items[i]).product.productId == productId) + { + index = i; + break; + } + } + + return index; + } + + private function doDragEnter(event:DragEvent):void + { + trace("doDragEnter"); + dmc.acceptDragDrop(event.target as IUIBase, DropType.COPY); + } + + private function doDragDrop(event:DragEvent):void + { + trace("doDragDrop"); + var product:Product = DragEvent.dragSource as Product; + addProduct(product); + } + + ]]> + </fx:Script> + <js:beads> + <js:DropMouseController id="dmc" dragEnter="doDragEnter(event)" dragDrop="doDragDrop(event)" /> + <js:VerticalLayout /> + <js:ScrollingViewport id="scrollingView" /> + </js:beads> + <js:Container id="viewport" width="100%" height="100%" > + </js:Container> +</js:Container>