Create a button with an icon in actionscript - apache-flex

I want to create buttons with icons in Flex dynamically using Actionscript.
I tried this, with no success:
var closeButton = new Button();
closeButton.setStyle("icon", "#Embed(source='images/closeWindowUp.png");

I found an answer that works for me. In my .mxml file, I create Classes for the icons I will use:
// Classes for icons
[Embed(source='images/closeWindowUp.png')]
public static var CloseWindowUp:Class;
[Embed(source='/images/Down_Up.png')]
public static var Down_Up:Class;
[Embed(source='/images/Up_Up.png')]
public static var Up_Up:Class;
In the Actionscript portion of my application, I use these classes when dynamically creating buttons:
var buttonHBox:HBox = new HBox();
var closeButton:Button = new Button();
var upButton:Button = new Button();
var downButton:Button = new Button();
closeButton.setStyle("icon", SimpleWLM.CloseWindowUp);
buttonHBox.addChild(closeButton);
upButton.setStyle("icon", SimpleWLM.Up_Up);
buttonHBox.addChild(upButton);
downButton.setStyle("icon", SimpleWLM.Down_Up);
buttonHBox.addChild(downButton);

You can use this one option of dynamic change of button icon.
Embed your icons
[Embed(source='com/images/play.png')]
[Bindable]
public var imagePlay:Class;
[Embed(source='com/images/pause.png')]
[Bindable]
public var imagePause:Class;
Using one button to toggle play and pause of video
private function playpause():void
{
if (seesmicVideo.playing)
{
seesmicVideo.pause();
btn_play.setStyle("icon",imagePlay);
}
else
{
seesmicVideo.play();
btn_play.setStyle("icon",imagePause);
}
}

The error is in the quotes, there should be no quotes around the #Embed:
closeButton.setStyle("icon", #Embed(source="images/closeWindowUp.png"));

I was able to use an icon in my button with the following code:
<mx:Button id="buttonPlay" label="Play" click="playButtonClicked();" enabled="false" icon="#Embed('./play.png')"/>
the file play.png is in the same folder of the mxml file.
I am using Flash Builder version 4.6.
Edit: the question was about ActionScript and not MXML, but I leave this answer just for reference.

I'm assuming you're adding it to the stage?
Also, I think your Embed is missing a close quote / paren.
closeButton.setStyle("icon", "#Embed(source='images/closeWindowUp.png");
should be:
closeButton.setStyle("icon", "#Embed(source='images/closeWindowUp.png')");

Related

Flex 4.6 Need to know how to animate a .swf in actionscript

I've converted a PowerPoint into Flash so each slide is a .swf. I've used a number of different converters and the problem here is the same.
What I'd like to do is trigger the .swf's animation (contents of slide appearing) programatically. I can click on the .swf with a mouse and the animation advances. I can automate this when the .swf's embedded in a web page simply by doing:
document.getElementById('myMovie').play();
Each time I execute that code, the swf advances to the next animation. However, I can't find a way to do this in flex. I've used then MovieClipSWFLoader and tried:
private function animate():void {
var simulatedClick1:MouseEvent = new MouseEvent(MouseEvent.CLICK);
var simulatedClick2:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN);
var simulatedClick3:MouseEvent = new MouseEvent(MouseEvent.MOUSE_UP);
frameNo++;
myMovie.gotoAndStop(frameNo);
myMovie.nextFrame();
myMovie.nextScene();
myMovie.play();
myMovie.dispatchEvent(simulatedClick1); // with clicks 1, 2, and 3
}
<s:MovieClipSWFLoader id="myMovie" source=""/>
<s:Button id="btnAnimate" click="animate()"/>
I've also tried loading as an Image component and using the simulated click too... no good. Can anyone tell me how I can do this?
The problem was that the .swf was created with Flash 8 and wasn't compatible with my version of Flex. I found a great solution in ForcibleLoader at https://gist.github.com/nsdevaraj/409902. It converts old .swf's to new ones and then the code worked as it should.
private var libMC:MovieClip = new MovieClip();
ur = new URLRequest(guide_url);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfComplete);
var fLoader:ForcibleLoader = new ForcibleLoader(loader);
fLoader.load(ur);
swfMovie.addChild(loader);
private function swfComplete(event:Event):void{
libMC = event.currentTarget.content as MovieClip;
}
private function animate():void {
libMC.nextFrame();
<mx:UIComponent id="swfMovie"/>

How to create "Browse for folder" dialog in Adobe FLEX?

Know someone, how to create "Browse for folder" dialog in Adobe FLEX? And it is possible?
Thanx.
If it's an Air app you can do :
var f : File = new File;
f.addEventListener(Event.SELECT, onFolderSelected);
f.browseForDirectory("Choose a directory");
If it's a pure As3 app, you cannot Browse for folder, you can just browse for file via FileReference class.
in Web, for multiple file upload, (for single file upload, use FileRefernce)
private var _refAddFiles:FileReferenceList;
private function browse():void
{
_refAddFiles = new FileReferenceList();
var fileFilter:FileFilter=new FileFilter("*.jpg","*.jpg;*.jpeg;");
_refAddFiles.addEventListener(Event.SELECT, onSelectFile);
_refAddFiles.browse([fileFilter]);
}
<mx:Button click="browse"/>
This will work, and what you want to do after selection,
private function onSelectFile(event:Event):void
{
_arrUploadFiles = [ ];
if (_refAddFiles.fileList.length >= 1)
{
for (var k:Number = 0; k < _refAddFiles.fileList.length; k++)
{
_arrUploadFiles.push({ name: _refAddFiles.fileList[k].name,
file: _refAddFiles.fileList[k]});
}
}
}
This is a quick function set to create a nice folder browser in Flex:
private var file:File = new File();
private function pickFile(event:MouseEvent):void {
file.addEventListener(Event.SELECT, openFile);
file.browseForDirectory("Select folder...");
}
private function openFile(event:Event):void{
folderPath.text = file.nativePath;
}
The first function deals with the folder browser, the second one populates a text input with the full folder path.
Howto:
On the stage, create a simple mx:button and add a call to the pickFile() function for the click event:
<mx:Button click="{pickFile(event);}" />
Then, put also on the stage an mx:TextInput component, to show the folder path after selection:
<mx:TextInput id="folderPath" editable="false" />
This way you have a button to click in order to show the system folder browser, and a text input to show the full folder path after selection.
To improve the button look, you can embed a nice folder icon :-)
Just my 2c. :-)

Flex 4 Drag-n-Drop with custom DragProxy

I'm doing the drag an drop of an ItemRenderer manually (DataGrid) and want to know how to generate a custom DragProxy of a component that hasn't been added to the display list.
I tried something like this but didn't work:
private function doDrag(event:MouseEvent):void
{
var dragSource:DragSource = new DragSource();
dragSource.addData(data, 'dnd_format');
//var bm:Bitmap = new Bitmap(ImageSnapshot.captureBitmapData(this));
var btn:Button = new Button();
btn.label = 'New Button';
var bm:Bitmap = new Bitmap(ImageSnapshot.captureBitmapData(btn));
var dragProxy:Image = new Image();
dragProxy.source = bm;
DragManager.doDrag(this, dragSource, event, dragProxy,0,0, 0.6);
}
So, I want to be able to create the DragProxy using a component, the button is just an example.
Any ideas?
My guess is that this is not working because you are trying to get a bitmap from a component that was just created and has not been added to the stage. I would try testing this code with using an embedded image as the drag proxy first. If that works, then try getting a bitmap from a component that exists on the stage. My guess is that both cases will work.

How to get the reference to a newly created Button with Actionscript?

I have a MXML button:
<mx:Button id="myButton1"/>
How do I create N number of Buttons with Actionscript: myButton2, myButton3, myButton4... myButtonN ?
And how to get the reference to the newly created buttons right after they are created? Like
I should be able to do myButtonN.x = 100 right after it's created.
This is pretty basic stuff...you might want to start with some Flex tutorials, or read through one of the many excellent books.
Here's a blob of code for you to copy & paste and see how it works for you:
private var buttons:Array = [];
public function createButtons():void {
for(var i:int=0; i<100; i++) {
buttons[i] = new Button();
buttons[i].label = "Button "+i;
buttons[i].x = i * 50;
addChild(buttons[i]); // NOTE: use addElement instead of addChild in Flex 4
}
}
It's not tested, so might need some minor typos, but you should be able to get the idea.

How do I implement custom drag functionality in a Flex list control?

Flex has built in drag-n-drop for list controls, and allows you to override this. But they don't cover this in examples. The built-in functionality automatically drags the list-item, if you want to override this you find the handlers are being set up on the list itself.
What I specifically want to do, is my TileList shows small thumbnails of items I can drag onto a large Canvas. As I drag an item from the list, the drag proxy should be a different image.
So, I followed the technique suggested and it only works if I explicitly set the width/height on the proxy Image. Why?
It's not obvious until you've tried it =) I struggled with the same thing just a few weeks ago. This was my solution:
The list:
<List>
<mouseDown>onListMouseDown(event)</mouseDown>
</Tree>
The mouse down handler:
private function onMouseDown( event : MouseEvent ) : void {
var list : List = List(event.currentTarget);
// the data of the clicked row, change the name of the class to your own
var item : MyDataType = MyDataType(list.selectedItem);
var source : DragSource = new DragSource();
// MyAwsomeDragFormat is the key that you will retrieve the data by in the
// component that handles the drop
source.addData(item, "MyAwsomeDragFormat");
// this is the component that will be shown as the drag proxy image
var dragView : UIComponent = new Image();
// set the source of the image to a bigger version here
dragView.source = getABiggerImage(item);
// get hold of the renderer of the clicked row, to use as the drag initiator
var rowRenderer : UIComponent = UIComponent(list.indexToItemRenderer(list.selectedIndex));
DragManager.doDrag(
rowRenderer,
source,
event,
dragView
);
}
That will start the drag when the user clicks an item in the list. Notice that I don't set dragEnabled and the other drag-related properties on the list since I handle all that myself.
It can be useful to add this to the beginning of the event handler:
if ( event.target is ScrollThumb || event.target is Button ) {
return;
}
Just to short circuit if the user clicks somewhere in the scrollbar. It's not very elegant but it does the job.
I found a simpler answer here. That example extends a DataGrid control, but you can do the same with a List control. In my case, I use an image source instead of Class:
public class CustomDragList extends List {
[Bindable]
public var dragProxyImageSource:Object;
override protected function get dragImage():IUIComponent {
var image:Image = new Image();
image.width = 50;
image.height = 50;
image.source = dragProxyImageSource;
image.owner = this;
return image;
}
}
Then use that custom list like this:
<control:CustomDragList
allowMultipleSelection="true"
dragEnabled="true"
dragProxyImageSource="{someImageSource}"
dragStart="onDragStart(event)"/>
Where 'someImageSource' can be anything you'd normally use for an image source (embedded, linked, etc.)

Resources