How do I respond to a NavigatorContent being selected in a View Stack - actionscript-3

I have view stack in a app like so:
<mx:ViewStack id="viewStack" left="0" right="0" top="0" bottom="0">
<views:LoginView top="0" bottom="0" right="0" left="0" id="loginView"/>
<views:MainHomeView top="0" bottom="0" right="0" left="0" id="childSelectionView"/>
<views:MainHomeView top="0" bottom="0" right="0" left="0" id="mainEvalView"/>
</mx:ViewStack>
When an event is fired, I call viewStack.selectedChild = childSelectionView
My question is how do I code a listener for the NavigatorConent being selected?
Here is what I try to do:
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:local="*" xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()">
<fx:Script>
<![CDATA[
private function init():void
{
// Do something here
advanceButton.visablitiy = false;
}
]]>
</fx:Script>
<s:VGroup>
<s:HGroup>
<s:Button label="Advance" id="advanceButton" />
</s:HGroup>
</s:VGroup>
I know that all the NavigatorConent's dispatch a creationComplete event on the application start, but their childrent aren't created yet. How did I respond to the on selectedChild change to self?

Sometimes it pays to poke around a bit, literally the question right before yours is exactly in the same problem domain. Use the FlexEvent.CONTENT_CREATION_COMPLETE event.
See Flex Error #1009: Cannot access a property or method of a null object reference

<fx:Script><![CDATA[
import mx.controls.Alert;
import mx.events.IndexChangedEvent;
protected function viewStack_childIndexChangeHandler(event:IndexChangedEvent):void {
Alert.show('Selected Child: ' + viewStack.selectedChild.label);
}
]]></fx:Script>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:ButtonBar dataProvider="{viewStack}"/>
<mx:ViewStack id="viewStack" change="viewStack_childIndexChangeHandler(event)">
<s:NavigatorContent id="navigator1" label="Navigator 1">
<s:Group>
<s:Button label="N1"/>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent id="navigator2" label="Navigator 2">
<s:Group>
<s:Button label="N2"/>
</s:Group>
</s:NavigatorContent>
</mx:ViewStack>

Related

Flex 4.6 : Make action for button in list

I'm beginner in Flex . my issue when to add button to list , i put the button in the itemrender but the action of navigator.pushView(views.Listde,ProblemsList.selectedItem);
make an error "Acess of undefined property navigator .
Code :
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import views.ButList;
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
navigator.pushView(views.Listde,ProblemsList.selectedItem);
}
]]>
</fx:Script>
<s:Group width="100%" height="100%" styleName="PCS.css">
<s:HGroup width="100%" height="100%" gap="2" verticalAlign="middle" horizontalAlign="center" paddingBottom="5" paddingLeft="5"
paddingRight="5" paddingTop="5">
<s:HGroup width="30%" height="100%" verticalAlign="middle" horizontalAlign="center">
<s:Label text="{data._AddedDate}" textAlign="left" verticalAlign="bottom" width="100%" height="100%"/>
</s:HGroup>
<s:VGroup width="50%" height="100%" verticalAlign="middle" horizontalAlign="right">
<s:BitmapImage source="images/{data.image}"/>
<s:TextArea editable="false" text="{data.description}"/>
<s:Label text="{data.price}"/>
<s:Button label="s" click="button1_clickHandler(event)"/>
</s:VGroup>
</s:HGroup>
</s:Group>
if any solution to resolve it by list or any component instead of list then i want button to navigate to view with the selected item and the change of the list to navigate to another view with the selected item also , then the change of list work success but the button action cannot defined with the navigator.
Thanks in advance for any help .
Create a custom event with data property and dispatch the event from item renderer or dispatch the list change event from the item renderer when clicking the button.
package myEvents
{
import flash.events.Event;
public class CustomEvent extends Event
{
public function CustomEvent(type:String,
data:Object=null) {
// Call the constructor of the superclass.
super(type);
// Set the new property.
this.data = data;
}
// Define static constant.
public static const MY_BUTTON_CLICKED:String = "myButtonClicked";
// Define a public variable to hold the state of the enable property.
public var data:Object;
// Override the inherited clone() method.
override public function clone():Event {
return new CustomEvent(type, data);
}
}
}
MyItemRenderer.mxml
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import views.ButList;
protected function button1_clickHandler(event:MouseEvent):void
{
// dispatch a custom
(this.owner as List).dispatchEvent(new CustomEvent(CustomEvent.MY_BUTTON_CLICKED, data));
//navigator.pushView(views.Listde,ProblemsList.selectedItem);
}
]]>
</fx:Script>
<s:Group width="100%" height="100%" styleName="PCS.css">
<s:HGroup width="100%" height="100%" gap="2" verticalAlign="middle" horizontalAlign="center" paddingBottom="5" paddingLeft="5"
paddingRight="5" paddingTop="5">
<s:HGroup width="30%" height="100%" verticalAlign="middle" horizontalAlign="center">
<s:Label text="{data._AddedDate}" textAlign="left" verticalAlign="bottom" width="100%" height="100%"/>
</s:HGroup>
<s:VGroup width="50%" height="100%" verticalAlign="middle" horizontalAlign="right">
<s:BitmapImage source="images/{data.image}"/>
<s:TextArea editable="false" text="{data.description}"/>
<s:Label text="{data.price}"/>
<s:Button label="s" click="button1_clickHandler(event)"/>
</s:VGroup>
</s:HGroup>
</s:Group>
Your view class
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="MY View">
<s:layout>
<s:VerticalLayout paddingTop="10"/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
private function onListCreationComplete_Handler():void
{
myList.addEventListener(CustomEvent.MY_BUTTON_CLICKED, onItemRendererButtonClicked);
}
protected function onItemRendererButtonClicked(event:CustomEvent):void {
var data:Object = event.data;
navigator.pushView(views.Listde,data);//myList.selectedItem
}
]]>
</fx:Script>
<s:Label text="Select an view"/>
<s:List id="myList"
width="100%" height="100%"
labelField="firstName" itemRenderer="MyItemRenderer"
change="myList_changeHandler(event)" creationComplete="onListCreationComplete_Handler()">
<s:ArrayCollection>
<fx:Object description="Fruits" image="assets/icons/1.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="New Item" image="assets/icons/2.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="Doll" image="assets/icons/3.png" _AddedDate="15/05/14" price="154"/>
</s:ArrayCollection>
</s:List>
</s:View>
I hope this might help u. There are tons of examples out there for list and item renderer for mobile.
Based on your ItemRenderer, you can simply listen to the IndexChangeEvent in your View. In this case, you don't need a separate button at all - the whole ItemRenderer can act as the button.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="MY View">
<s:layout>
<s:VerticalLayout paddingTop="10"/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
import views.ButList;
protected function myList_changeHandler(event:IndexChangeEvent):void {
navigator.pushView(views.Listde,myList.selectedItem);
}
]]>
</fx:Script>
<s:Label text="Select an view"/>
<s:List id="myList"
width="100%" height="100%"
labelField="firstName" itemRenderer="MyItemRenderer"
change="myList_changeHandler(event)">
<s:ArrayCollection>
<fx:Object description="Fruits" image="assets/icons/1.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="New Item" image="assets/icons/2.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="Doll" image="assets/icons/3.png" _AddedDate="15/05/14" price="154"/>
</s:ArrayCollection>
</s:List>
</s:View>

Flex: Spark image resize does not work

When I use resize component on image, it just disappears. Even if I give widthTo and heightTo values more than image size.
Code
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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:net="flash.net.*">
<fx:Script>
<![CDATA[
import mx.effects.Resize;
import mx.utils.ObjectUtil;
private function btn_click(evt:MouseEvent):void {
var arr:Array = [];
arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));
fileReference.browse(arr);
}
private function fileReference_select(evt:Event):void {
fileReference.load();
}
private function fileReference_complete(evt:Event):void {
img.source = fileReference.data;
}
]]>
</fx:Script>
<fx:Declarations>
<net:FileReference id="fileReference"
select="fileReference_select(event);"
complete="fileReference_complete(event);" />
<s:Resize id="resizeBig"
target="{img}"
widthFrom="{img.width}" widthTo="{newWidth.text as Number}"
heightFrom="{img.height}" heightTo="{newHeight.text as Number}"/>
<s:Resize id="myResizeEffect"
target="{img}"
widthBy="10" heightBy="10"/>
</fx:Declarations>
<s:Image id="img"
verticalCenter="0"
horizontalCenter="0"
maxWidth="200"
maxHeight="200"
/>
<mx:ControlBar>
<mx:Button id="btn"
label="Upload"
click="btn_click(event);" />
<s:HGroup verticalAlign="middle">
<s:Label>Width:</s:Label>
<!-- <s:NumericStepper id="newWidth" minimum="1" maximum="100" value="10" /> -->
<s:TextInput id="newWidth" restrict="0-9.\\-" />
</s:HGroup>
<s:HGroup verticalAlign="middle">
<s:Label>Height:</s:Label>
<s:TextInput id="newHeight" restrict="0-9.\\-"/>
</s:HGroup>
<s:HGroup verticalAlign="middle">
<s:Button id="resize"
label="Resize"
click="resizeBig.end();resizeBig.play();"
/>
<s:Button label="Resize Me"
click="myResizeEffect.end();myResizeEffect.play();"/>
</s:HGroup>
</mx:ControlBar>
</s:WindowedApplication>
I think the binding expression doesn't like the "as Number" thing. I would try with a function that does the conversion:
widthTo="{getNumber(newWidth.text)}"

Create a Panel skin (Spark) with a background fill color I can pass as a parameter

I'm trying to create a Panel skin (Spark) with a background fill color I can pass as a parameter.
(See in bold:)
<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin name="CustomPanelSkin"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
blendMode="normal">
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" stateGroups="withControls" />
<s:State name="disabledWithControlBar" stateGroups="withControls" />
</s:states>
<fx:Metadata>
[HostComponent("spark.components.Panel")]
</fx:Metadata>
<s:Group left="0" right="0" top="0" bottom="0">
<s:Rect left="0" right="0" top="0" bottom="0" radiusX="12" radiusY="12">
<s:fill>
<s:SolidColor color="#184c81" />
</s:fill>
</s:Rect>
<s:Group id="contents" left="1" right="1" top="1" bottom="1">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0">
</s:Group>
</s:Group>
</s:Group>
</s:SparkSkin>
From what I read I should create a subclass, but there is not much material on the subject.
I would later on want to use this skin in many Panel controls I have in my application.
Base Panel skin has background color implementation using css styles. You can set it using action script:
panel.setStyle("backgroundColor", 0x184c81);
Also you can control skin components when you have a reference to it in the host component.
Read Implementing the partAdded() and partRemoved() methods for skinnable components for Spark components
This is simple.Create a panel skin and name it something as "panelSkin.mxml".In the .as file use the following statement
newPanelBlock.setStyle("skinClass",com.foldername.panelSkin);
newPanelBlock.setStyle("backgroundColor", 0x184c81);

How to mirror camera display in VideoDisplay in Flex

I am trying to mirror the camera display in my mx:VideoDisplay object in Flex 3.6. That is, I want the camera image to be flipped horizontally.
This is my MXML file:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" applicationComplete="init()"
xmlns:ns1="components.*"
xmlns:ns2="*"
xmlns:fl="flash.media.*"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:gauge="components.gauge.*"
>
<mx:Script source="script.as" />
<mx:Style source="style.css" />
<mx:Canvas label="recorder" width="100%" height="100%" verticalScrollPolicy="off"
horizontalScrollPolicy="off" id="canvas2">
<mx:VideoDisplay id="myWebcam" scaleX="1" left="0" top="0" bottom="36" right="0"/>
<mx:Image id="mask2" source="#Embed(source='assets/mask.png')"
left="190" top="120" width="270"/>
<ns1:VideoContainer right="0" bottom="0" />
</mx:Application>
I have tried to use myWebcam.scaleX="-1" and adding myWebcam.x = myWebcam.width among many further combinations without success.
So, how am I supposed to flip the image?
Thanks
You can change:
<mx:VideoDisplay id="myWebcam" scaleX="1" left="0" top="0" bottom="36" right="0"/>
to:
<mx:VideoDisplay id="myWebcam" scaleX="-1" left="0" top="0" bottom="36" right="0" x="{myWebcam.width + myWebcam.x}"/>
I also found that myWebcam.scaleX = -1 is not ok, maybe it is a bug.

window skin according OS

I try to have a specific window skin according operating system.
See below my skin.
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
xmlns:Layout="skin.Layout.*"
alpha.disabledGroup="0.5"
creationComplete="sparkskin1_creationCompleteHandler(event)">
<fx:Metadata>
[HostComponent("fr.inter.ui.windowSkin.wCustomWindow")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function btResize_mouseDownHandler(event:MouseEvent):void
{
btResize.addEventListener( MouseEvent.MOUSE_UP, btResize_mouseUpHandler );
stage.nativeWindow.startResize();
}
protected function btResize_mouseOutHandler(event:MouseEvent):void
{
btResize.removeEventListener( MouseEvent.MOUSE_OUT, btResize_mouseOutHandler );
}
protected function btResize_mouseUpHandler(event:MouseEvent):void
{
btResize.removeEventListener( MouseEvent.MOUSE_UP, btResize_mouseUpHandler );
}
protected function sparkskin1_creationCompleteHandler(event:FlexEvent):void
{
if (NativeApplication.supportsDockIcon)
{
this.currentState = "supportsDockIcon";//mac
}
else
{
this.currentState = "supportsSystemTray";
}
}
]]>
</fx:Script>
<s:states>
<s:State name="disabledAndInactive" stateGroups="disabledGroup, inactiveGroup" />
<s:State name="maximizedGroup"/>
<s:State name="normal" />
<s:State name="disabled" stateGroups="disabledGroup" />
<s:State name="normalAndInactive" stateGroups="inactiveGroup" />
<s:State name="supportsDockIcon" />
<s:State name="supportsSystemTray"/>
</s:states>
<s:Rect id="backgroundRect"
left="0"
right="0"
top="0"
bottom="0"
alpha="0"
>
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
<s:Group bottom="0" left="0" right="0"
top="0"
>
<!--Fond de la fenetre-->
<s:Rect bottom="0" left="0" right="0"
top="0"
radiusX="8" radiusY="8" >
<s:fill>
<s:SolidColor color="#656565" alpha=".7" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="#666666" />
</s:stroke>
</s:Rect>
<s:Group height="38" id="moveArea"
left="0" right="0" >
<!--Barre bleu avec filet-->
<s:Rect height="25" left="10" right="10" top="10">
<s:fill>
<s:SolidColor color="#055a90" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="#666666" />
</s:stroke>
</s:Rect>
<s:BitmapImage id="icon"
left.supportsSystemTray="5" right.supportsDockIcon="5"
verticalCenter="0" />
<s:Label id="titleDisplay"
styleName="swindowTitle"
left.supportsSystemTray="60" left.supportsDockIcon="{this.width/2}"
top="18" verticalAlign="middle" horizontalCenter="0"
/>
<!--Zone de bouton-->
<s:HGroup right.supportsSystemTray="12" left.supportsDockIcon="12" verticalCenter="0">
<s:Button id="btMinimize" buttonMode="true"
skinClass.supportsSystemTray="skin.components.MinimizeButtonSkin"
skinClass.supportsDockIcon="skin.components.MinimizeButtonSkinM"
verticalCenter="0"/>
<s:Button id="btMaximize" buttonMode="true"
skinClass.supportsSystemTray="skin.components.MaximizeButtonSkin"
skinClass.supportsDockIcon="skin.components.MaximizeButtonSkinM"
verticalCenter="0"/>
<s:Button id="closeButton" buttonMode="true"
skinClass.supportsSystemTray="skin.components.CloseButtonSkin"
skinClass.supportsDockIcon="skin.components.CloseButtonSkinM"
verticalCenter="0"/>
</s:HGroup>
</s:Group>
<!--Fond de la zone principale-->
<s:Rect id="background" left="10" top="35" right="10" bottom="10">
<s:fill>
<s:LinearGradient rotation="-90">
<s:GradientEntry color="#edf0f7"/>
<s:GradientEntry color="#fcfbfb" />
</s:LinearGradient>
</s:fill>
<s:stroke>
<s:SolidColorStroke color="#666666" />
</s:stroke>
</s:Rect>
<!--Zone dans laquelle les elements vont se positionner-->
<s:Group id="contentGroup" left="15" right="15" top="43" bottom="15" minWidth="0"
minHeight="0" width="100%" height="100%">
</s:Group>
</s:Group>
<s:Button height="15" id="btResize" width="15"
bottom="0" right="0"
skinClass="spark.skins.spark.windowChrome.GripperSkin"
mouseDown="btResize_mouseDownHandler(event)"
buttonMode="true"/>
When windows is loading firt, buttons appear well.
But if window is desactivate and after activate, MacOs and Windows buttons appear.
I don't know how to solve that, could you help me?
Thanks
You're not supposed to set the Skin's currentState directly from within the Skin because the hostComponent should take care of that. When you deactivate and re-activate the Window, the hostComponent will set the Skin state back to one of its original states (e.g. normal) and hence disregards your two custom states.
If you want to set the Skin's state based on certain conditions you should override the getCurrentSkinState() method of the hostComponent. But in this particular case I don't think that would be the right approach, because it would be too complicated.
The easiest solution here I think would be to override the Skin's updateDisplayList() method to position your elements. This is the method that takes care of correctly displaying all the elements in your Skin.
<fx:Script>
<![CDATA[
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (NativeApplication.supportsDockIcon) {
titleDisplay.left = width / 2;
//position other elements for mac
}
else {
titleDisplay.left = 60;
//position other elements for win
}
}
]]>
</fx:Script>
Another - perhaps even better - approach would be to create two separate Skin's (one for Mac, one for Windows) and apply the correct Skin to your Windows. This would rid us of the continous if/else checking for capabilities.