Tuesday, September 23, 2008

mx:TextInput bug from Flexosaurus

Nearly five months ago I noticed mx:TextInput's bug. The following steps will reproduce the bug.

In the Application 1

- Enter some long string in the mx:TextInput e.g. "asd asdsa sadsadsa sadsad asdsa"

- Click on the "Button" button(it is setting text in the mx:TextInput to "yes")

- You will not be able to see the text in the mx:TextInput, you will be able to see the text if you e.g. click on the mx:TextInput

Application 1




<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
width="300" height="50" layout="absolute">

<mx:Script>

<![CDATA[

private function clickBtn(event:MouseEvent):void
{
txtInput.text = "yes";

}
]]>

</mx:Script>

<mx:Button id="btnSubmit" x="178" y="10" label="Button"
click="clickBtn(event)"/>
<mx:TextInput id="txtInput" x="10" y="10"/>

</mx:Application>



There is a few ways for fixing this problem. Here is one of them. We will create custom text input component and override public function set text(value:String):void function. In the text setter we will call initialize mx:TextInput text property (super.text = value;) and then we'll just bring the cursor to the begging.

Reproduce the bug for the Application 2 and you will be able to see the text.

Application 2




<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:ns1="*"
width="300" height="50" layout="absolute">

<mx:Script>

<![CDATA[

private function clickBtn(event:MouseEvent):void
{
txtInput.text = "yes";

}
]]>

</mx:Script>

<mx:Button id="btnSubmit" x="178" y="10" label="Button"
click="clickBtn(event)"/>
<ns1:CustomTextInput id="txtInput" x="10" y="10"/>

</mx:Application>


CustomTextInput.as

package
{
import mx.controls.Alert;
import mx.controls.TextInput;

public class CustomTextInput extends TextInput
{
public function CustomTextInput()
{
super();
}

override public function set text(value:String):void
{
super.text = value;

// Bringing cursor to the beginning
setSelection(1,1);
}
}
}

Wednesday, August 6, 2008

Little hint concerning Flickr API from Flexosaurus

If you are trying to use ActionScript 3.0 API for Flickr and while creating FlickrService you are getting following error:

1017: The definition of base class URLLoaderBase was not found.



Or following exception run-time:

Error #1014: Class com.adobe.webapis::URLLoaderBase could not be found.



Do not panic. You just need to download as3corelib . There are number of classes in as3corelib that are getting used by ActionScript 3.0 API for Flickr.

Sunday, August 3, 2008

3D Ferris Wheel from Flexosaurus

I just tried to implement something "3D" and here it is:) Actually it's just number of planes which you can rotate in the way the Ferris Wheel get rotated. You can also change the X,Y,Z angles of scene. E.g. you can change the angles, place the planes horizontally and you'll get whirling photo album. It is also very easy to make this planes clickable. The sample is powered by Away3D and Caurina Tweener.

SOURCE | SAMPLE

Friday, July 25, 2008

Cool ToolTips from Flexosaurus

Conventional Flex tooltips are just displaying text that provides info. In the following sample I created few custom tooltips.

•Animated tooltip
•Image tooltip

The first one is a tooltip with transparent background with some animation added. The second tooltip is more decorative. Because of the image size the text should be short. It is possible to take bigger image and resize it depending on text length, but I don't think that the big tooltips of this style will look good enough.

Also here is provided the way for applying some effects for tooltip's appearance and disappearance.

It is often useful to have tooltip which is supporting HTML. It is quite easy to implement. If you need it, just let me know in the comments and I'll give you the code.


Source

Thursday, July 17, 2008

Flexosaurus about Blogger API for ActionScript

Yesterday I was trying to get authenticating to the Blogger service, but I was getting following error. Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false
eventPhase=2 text="Error #2032: Stream Error. URL:
https://www.google.com/accounts/ClientLogin"]. URL:
https://www.google.com/accounts/ClientLogin.

I found out that Google currently do not support cross-domain requests to Google Accounts from Flash. There is currently an issue filed against this here: http://code.google.com/p/gdata-issues/issues/detail?id=406 .

Anyhow I was able to get authorization token(it worked for Mozilla FireFox, but not for IE6), but not more than that. But it may be able to work around this by proxying requests through own domain, however. So maybe I will try.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
applicationComplete="authotize()">

<mx:Script><![CDATA[

import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;

//Authorization Token
private var _auth:String;

public function authotize():void
{
var urlLoader:URLLoader = new URLLoader();
var urlRequest:URLRequest = new URLRequest();
var urlVariables:URLVariables = new URLVariables();

urlVariables.Email = {you_e-mail_here}
urlVariables.Passwd = {your_password_here}
urlVariables.service = "blogger";
urlVariables.source = "exampleCo-exampleApp-1";

urlRequest.url = "https://www.google.com/accounts/ClientLogin";
urlRequest.data = urlVariables;
urlRequest.method = URLRequestMethod.POST;

urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
urlLoader.addEventListener(Event.COMPLETE, onComplete);

urlLoader.load(urlRequest);
}

private function onComplete(event:Event):void
{
var str:String = event.currentTarget.data;
var index:int = str.indexOf("Auth=");
_auth = str.substring(index + 5, str.length - 1);
}

private function onHTTPStatus(event:HTTPStatusEvent):void
{
trace(event);
}

private function onError(event:Event):void
{
trace(event);
}

]]></mx:Script>

</mx:Application>

Tuesday, July 15, 2008

Editable chart with custom axis from Flexosaurus

Nearly one month ago I was needed to create a custom axis which contains controls. We have little time and we decided to round this problem and chose another approach. On previous weekend I decided to find out how it is possible to insert controls into axis and found it very easy. Following example is adding one image and one button with every label, it is also providing a way of editing chart run-time.




<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="{init()}"
width="460" height="450">


<mx:ColumnChart id="championsChart" dataProvider="{champions}">
<mx:horizontalAxis>
<mx:CategoryAxis id="horAxis" dataProvider="{champions}"
categoryField="Team"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="Team" yField="Count"
displayName="Team">
<mx:fill>
<mx:SolidColor color="0xc02314"/>
</mx:fill>
</mx:ColumnSeries>
</mx:series>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer axis="{horAxis}">
<mx:labelRenderer>
<mx:Component>
<mx:VBox horizontalAlign="center">
<mx:HBox>
<mx:Image source="@Embed('../assets/f1logo.png')"/>
<mx:Label id="newLabel"/>
</mx:HBox>
<mx:Button label="EDIT" click="{outerDocument.onClick(event)}"/>
<mx:Script><![CDATA[
override public function set data(value:Object):void
{
if(value == null)
{
return;
}

newLabel.text = value.text;
}
]]></mx:Script>
</mx:VBox>
</mx:Component>
</mx:labelRenderer>
</mx:AxisRenderer>
</mx:horizontalAxisRenderers>
</mx:ColumnChart>

<mx:Script><![CDATA[

import mx.containers.*;
import mx.controls.Button;
import mx.controls.TextInput;
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;

private var titleWindow:TitleWindow;
private var countTextInput:TextInput;
private var saveButton:Button;
private var cancelButton:Button;
private var index:int;

[Bindable]

public var champions:ArrayCollection = new ArrayCollection
([
{Team:"Ferrari", Count:15},
{Team:"Williams", Count:9},
{Team:"McLaren", Count:8}
]);

public function onClick(e:Event):void
{
index = searchName(e.target.parent.newLabel.text);
titleWindow.title = e.target.parent.newLabel.text + " championships number";
PopUpManager.addPopUp(titleWindow,this,true);
PopUpManager.centerPopUp(titleWindow);
}

private function init():void
{
var vbox:VBox = new VBox();
var hbox:HBox = new HBox();

titleWindow = new TitleWindow();
countTextInput = new TextInput();
saveButton = new Button();
cancelButton = new Button()

cancelButton.addEventListener(MouseEvent.CLICK, onCancel);
saveButton.addEventListener(MouseEvent.CLICK, onSave);

saveButton.label = "SAVE";
cancelButton.label = "CANCEL";

hbox.addChild(saveButton);
hbox.addChild(cancelButton);

vbox.addChild(countTextInput);
vbox.addChild(hbox);

titleWindow.addChild(vbox);
}

private function onCancel(e:Event):void
{
PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";
}

private function onSave(e:Event):void
{
champions.getItemAt(index).Count = (countTextInput.text == "") ? 10 : int(countTextInput.text);

PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";

championsChart.dataProvider = champions;
}

private function searchName(name:String):int
{
for(var i:int = 0; i < champions.length; i++)
{
if(champions.getItemAt(i).Team == name)
{
return i;
}
}
return -1;
}

]]></mx:Script>
</mx:Application>