Passing flashvars to Flex - html

As a PHP junior encountering Flex for the first time this scratches my brain for days. The flashvar contains the source of the video I wnat to play in the Flex video component. The HTML of the player looks like:
function createPlayer(videoSource){
document.writeln("<div id=\"player\">");
document.writeln("<object width=\"489\" height=\"414\" FlashVars=\""+videoSource+"\">");
document.writeln("<param name=\"player\" value=\"bin-debug/FlexPlayer.swf\">");
document.writeln("<embed src=\"bin-debug/FlexPlayer.swf\" name=\"player\" width=\"489\" height=\"414\" FlashVars=\""+videoSource+"\">");
document.writeln("</embed>");
document.writeln("</object>");
document.writeln("</div>");
}
I tried to call the FlashVars in the FlexPlayer.mxml but it's not working. Please tell me what I have to apply in the source in the mxml to access the FlashVars.
<s:VideoPlayer id="Player" left="0" top="0" width="497" height="414"
skinClass="MySkin" source="FlashVars"/>
</s:Group>

What does the variable videoSource contain? If it is an URL to a video and nothing more, it probably won't work, since flashvars is supposed to be a string that contains variable names and values (not just values).
So for example, flashvars="video.flv" won't work, but flashvars="sourceUrl=video.flv" can work, if the video player is made to use a variable named sourceUrl.
Also, for the object element you should add a separate param element for the flashvars, instead of having flashvars as an attribute of the object element. For the embed element, flashvars is an attribute, as you have it now (aint standards great ;)
More info:
http://kb2.adobe.com/cps/164/tn_16417.html

<mx:Script>
<![CDATA[
private function init():void {
// The FlashVars
var obj:Object = Application.application.parameters;
var videoSource:String = (obj.videoSource != null) ? obj.videoSource : "there was no flashVar by this name";
trace(videoSource);
}
]]>
</mx:Script>

Related

Defining hitArea on Spark ToggleButton

I've been able to skin a ToggleButton with custom images (loading Skin images dynamically) and it is working well.
The last functionality I would like to add is to limit interactivity (mouseEvents) to the opaque pixels. I've been searching around and came across InteractivePNG and Creating a hitarea for PNG Image with transparent (alpha) regions in Flex. I had erratic results with InteractivePNGin initial tests so I thought I would try to define the ToggleButton hitArea property using the code from the second link.
I haven't been able to get it working. My code for generating the Sprite to define the hit area is below. (I've also tried just a simple Sprite with a rect drawn within it.) When I set the togglebutton.hitArea I don't get any errors but it is no longer interactive.
Does the Sprite defining the hitArea need to be added to the DisplayList of the object it is being applied to? If so, how to I do that with a subclass of ToggleButton?
hitSprite = createHitArea(upImageData, 1);
hitSprite.mouseEnabled = false;
this.hitArea = hitSprite;
Of course calling `addChild() on a ToggleButton throws an error.
this.addChild(hitSprite);
I've tried:
wrapping my custom ToggleButton in a Spark Group, and then an MX UIComponent so that I could have a use a SpriteDisplayElement to add things to – but that didn't work.
adding a Sprite within my custom ToggleButton definition – and get an error doing that.
Am I out of luck here using the ToggleButton class for this type of functionality? What I don't understand is why ToggleButton has a hitArea property if there isn't a way to set it – but that can't be the case so I must be doing something wrong.
Update
I just tried this approach( Flex 4 Custom Component - How to notify skin of property changes?) binding to a SpriteVisualElement that gets created in to ToggleButton – but still no success in setting the hitArea – either of the ToggleButton or the Skin it is using.
public function createHitArea(bitmapData:BitmapData, grainSize:uint=1):SpriteVisualElement
{
var _hitarea:SpriteVisualElement = new SpriteVisualElement();
_hitarea.graphics.beginFill(0x000000, 1.0);
for(var x:uint=0;x<bitmapData.width;x+=grainSize) {
for(var y:uint=grainSize;y<bitmapData.height;y+=grainSize) {
if(x<=bitmapData.width && y<=bitmapData.height && bitmapData.getPixel(x,y)!=0) {
_hitarea.graphics.drawRect(x,y,grainSize,grainSize);
}
}
}
_hitarea.graphics.endFill();
_hitarea.cacheAsBitmap = true;
return _hitarea;
}
]]>
I don't know much about the hitArea property, but I have dealt with buttons that have transparencies. I solve that by adding something like this to my button skin:
<s:Group id="clickTarget" top="0" left="0" bottom="0" right="0">
<s:Rect top="0" left="0" bottom="0" right="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" alpha="0.01" />
</s:fill>
</s:Rect>
</s:Group>

How can I make Flex Busy Indicator load early?

I'm building a mobile app with Flash Builder 4.6 and AIR.
My Main.mxml class -- a ViewNavigatorApplication -- references a splash screen set to a minimum time of 6 seconds. After the splashscreen disappears, there's a period of a couple of seconds during which the content area of the screen is just blank white -- and that's when I need the Busy Indicator to appear.
EDIT: Additional Code, as requested:
In the Main.mxml class:
protected function viewnavigatorAppInitializeHandler(event:FlexEvent):void
{
//checks various criteria to determine which data to load, ie which service call
// to make. When that is determined, code calls setUpModel().
}
private function setUpModel():void {
Model.Instance.initialize(); //adds listeners in the model,
//makes service call. Data is returned and parsed in the event handler.
//APPLICATION_MODEL_LOADED event is then dispatched, and handled here
Model.Instance.addEventListener( Model.APPLICATION_MODEL_LOADED, modelReadyHandler );
}
private function modelReadyHandler(e:Event):void
{
//Busy Indicator only appears *after* the HomeListView is loaded.
//I need it to appear *while* these calls are being made.
navigator.pushView(HomeListView); //this is my First View
}
So I think the question is: what is it that is being displayed before HomeListView? If it's Main.mxml -- the ViewNavigatorApplication -- then how do I avoid the 'not assignable' error?
In HomeListView:
[Bindable] private var categoryList:ArrayCollection = new ArrayCollection();
private function viewActivateHandler():void
{
//the service call has been made, and data is ready to be loaded into the control
categories = Model.Instance.Categories;
I've tried this inside HomeListView:
<s:Group width="100%" height="100%">
<s:BusyIndicator
id="busy"
visible="true" symbolColor="blue"
horizontalCenter="0" verticalCenter="0"
rotationInterval="100" />
</s:Group>
It works. But the problem is it only appears once HomeListView has loaded. I thought that the blank white was HomeListView, just before the list appeared. But it isn't.
So then I tried putting the above code into the Main.mxml file. But I got the following error:
'spark.components.Group' is not assignable to the default property, 'navigationStack', of type 'spark.components.supportClasses.NavigationStack'.
So where can I put this BusyIndicator so that it covers the blank space before HomeListView appears?
I've figured out a way to do this.
From the documentation:
"Unlike Application, ViewNavigatorApplication is not meant to accept UIComponent objects as children. Instead, all visual components should be children of the views managed by the application."
That is why I was getting the error. So for my first View, I created a simple View called HolderView which contains the BusyIndicator:
<?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="HolderView">
<s:Group width="100%" height="100%">
<s:BusyIndicator
id="busy"
visible="true" symbolColor="blue"
horizontalCenter="0" verticalCenter="0"
rotationInterval="100" />
</s:Group>
Then, from my Main.mxml file, I first load that HolderView.
private function setUpModel():void {
Model.Instance.initialize();
navigator.pushView(HolderView);
Model.Instance.addEventListener(Model.APPLICATION_MODEL_LOADED, modelReadyHandler );
}
Once the data has come back -- on the Model.APPLICATION_MODEL_LOADED event listener -- that is when I will load HomeListView:
private function modelReadyHandler(e:Event):void
{
navigator.pushView(HomeListView);
}
This works. Hope it helps someone with same problem!

flex open url from HTML component in external browser

I am trying to open url links from within the HTML component into the system browser.
I am using this method to create several HTML component child and all of them are added in a Vgroup.
public function addHtmlText(htmlValue:String):void {
var htmlData:HTML = new HTML();
htmlData.percentWidth = 95;
htmlData.htmlText = htmlValue
htmlData.horizontalScrollPolicy="false"
htmlData.verticalScrollPolicy="false"
chatCanvas.addElement(htmlData);
}
this is how I render the strait text link into a real link ( )
public function emoUrl(emoValue:String):String {
var urlRegex:RegExp = /(((http|ftp|https):\/\/){1}([a-zA-Z0-9_-]+)(\.[a-zA-Z0-9_-]+)+([\S,:\/\.\?=a-zA-Z0-9_-]+))/igs
var emoValue1:Array = emoValue.match(urlRegex);
if (urlRegex.test(emoValue)) {
emoValue = emoValue.split(emoValue.match(urlRegex)).join(''+emoValue1.toString()+'')
}
return emoValue;
}
the problem is that since these are all individual HTML component elements and that a user can click on any one of them to open in the system browser.
currently, the link will open, but within the html component. I need it to be external.
I have found this on the internet that might help but I have no idea on hot to implement it for my needs.
htmlData.htmlLoader.navigateInSystemBrowser = true
thanks !
Create a URLRequest to the web page, and open it with navigateToURL :
var urlRequest:URLRequest = new URLRequest("http://www.adobe.com/");
navigateToURL(urlRequest);
Example loading a page upon click of a button with Flex MXML:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import flash.net.navigateToURL;
protected function clickHandler(event:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.adobe.com"), "_blank");
}
]]>
</fx:Script>
<s:Button label="Open page"
click="clickHandler(event)" />
</s:Application>
navigateToURL():
Opens or replaces a window in the application that contains the Flash Player container (usually a browser). In Adobe AIR, the function opens a URL in the default system web browser.
Parameters
request:URLRequest — A URLRequest object that specifies the URL to navigate to. For content running in Adobe AIR, when using the navigateToURL() function, the runtime treats a URLRequest that uses the POST method (one that has its method property set to URLRequestMethod.POST) as using the GET method.
window:String (default = null) — The browser window or HTML frame in which to display the document indicated by the request parameter. You can enter the name of a specific window or use one of the following values:
"_self" specifies the current frame in the current window.
"_blank" specifies a new window.
"_parent" specifies the parent of the current frame.
"_top" specifies the top-level frame in the current window.
urlRequest():
Creates a URLRequest object. If System.useCodePage is true, the request is encoded using the system code page, rather than Unicode. If System.useCodePage is false, the request is encoded using Unicode, rather than the system code page.
Parameters
url:String (default = null) — The URL to be requested. You can set the URL later by using the url property.

Flex getElementByName

I know that there is no such function as getElementByName in Flex but I also now that you can do this["object_id"] to get the element of the application u're in.
What about getting an element inside another element?
I've tried making element["id"] ? But in my try-catch it always runs the "catch" part =\
So: how do I get an element inside another element just having it's id in dynamically created string form?
Thank you in advance
It depends on what kind of element you are trying to access.
A child display object can be accessed by calling DisplayObjectContainer#getChildByName:
element.getChildByName("name");
A public variable (which could be set to also contain a child display object) can be accessed by using bracket syntax:
element["name"];
or simply using dot syntax:element.name
(where name is the name of the property you are trying to access).
Note that any instance you drag to the stage in the Flash IDE will automatically be assigned to a public variable, if you have the "automatically declare stage instances" option checked in your export settings. That is why using this[name]works.
If I understand correctly, you're asking for a way to get all the "elements" in a Flex application that have a certain name.
Here's an example (Flex 3):
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
<mx:Script>
<![CDATA[
private function testIt():void
{
var arr:Array = getDisplayObjectsByName(this, "foo");
for each (var e:* in arr)
trace(e);
}
private static function getDisplayObjectsByName(node:DisplayObjectContainer,
name:String, recurse:Boolean = true):Array
{
var n:int = node.numChildren;
var a:Array = [];
for (var i:int = 0; i < n; i++) {
var c:DisplayObject = node.getChildAt(i);
if (c.name == name)
a.push(c);
if (recurse) {
if (c is DisplayObjectContainer)
a = a.concat(getDisplayObjectsByName(DisplayObjectContainer(c),
name, true));
}
}
return a;
}
]]>
</mx:Script>
<mx:VBox name="foo">
<mx:HBox>
<mx:Button name="foo" label="Test" click="testIt()" />
</mx:HBox>
</mx:VBox>
<mx:Label text="Ignore Me" />
<mx:VBox name="bar">
</mx:VBox>
</mx:Application>
Here we're looking for all the elements called "foo" when the user clicks the "Test" button.
Output:
main0.foo
main0.foo.HBox5.foo
You'll notice that getDisplayObjectsByName() is static. All it does is traverse the display list (depth-first) and pick out all the objects with the specified name.
If you're looking for the element in a Group, you can use this function:
static function getElementByName(group:GroupBase, name:String):IVisualElement {
const child:DisplayObject = group.getChildByName(name);
const index:int = group.getChildIndex(child);
return group.getElementAt(index);
}

How to show list of components in Flex

I'm building a multiplayer game which when connecting to the server, the server sends back a list of available rooms (each room has MaxPlayers,MinRank,TableId,TableName,Password) so everytime I recieve these 5 strings, I create an instance of Mxml UI Component I have created and fill it with the relevant details.
In the main.MXML i've added an AS3 script variable to hold the GameInstances object i've created when rcvd data back from the server:
private var gameInstances:ArrayCollection = new ArrayCollection();
GameInstance.mxml is a component that has UI components in it and AS3 script to set some data.
When rcving data from the server in main.mxml :
var gameInstance:GameInstance = new GameInstance();
gameInstance.setTablePlayers(rcvdMsg[1]);
gameInstance.setTableMinRank(rcvdMsg[2]);
gameInstance.setTableId(rcvdMsg[3]);
gameInstance.setTableName(rcvdMsg[4]);
gameInstance.setTablePassword(rcvdMsg[5]);
gameInstances.addItem(gameInstance);
gameInstances holds objects of that mxml component.
How do I show this component visualy on the main.mxml?
I have a in main.mxml that I want visually show inside it the GameInstance objects.
This is how GameInstance.mxml looks like, I want the s:List to hold for each game a UI object like that(to show it ofcourse)
OK, if you using the gameInstances arraycollection as a data provider for tableList then you need to do a few things.
First, you need to make your gameInstances arraycollection [Bindable]
Then, you need to add data to the array collection as code you posted shows you are.
Next, you have to Create a custom item renderer for your tableList.
Finally, when you are done changing data/adding/removing objects from the gameInstances arraycollection you need to gameInstances.refresh();
[EDIT]
create a file named myListRenderer.mxml and put this code in it
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
override protected function commitProperties():void{
// this is where you assign your values
// this function gets called every-time the list scrolls
super.commitProperties();
players.text = this.data.setTablePlayers
minRank.text = this.data.setTableMinRank;
tableId.text = this.data.setTableId;
tableName.text = this.data.setTableName;
tablePassword.text = this.data.setTablePassword;
}
]]>
</mx:Script>
<mx:Label id="players" />
<mx:Label id="minRank" />
<mx:Label id="tableId" />
<mx:Label id="tableName" />
<mx:Label id="tablePassword" />
</mx:VBox>
If I understand the question, when you create components in ActionScript, you have to add them to a container before they'lls how up in the UI. If you have an array of components, you can just loop over that array and add each component as a child on a container. The main application file is a container, so you can do something like this:
for each(var myComp:UIComponent in myArrayList){
addChild(myComp);
}
It would be unusual to take this approach. Usually you just add the component to the parent container as you create them.