Note:
I’ve updated this post to work with Haxe 3 by changing:
import neko.FileSystem; and import cpp.FileSystem; to import sys.FileSystem;
and a change to support Waxe 3.0:
waxePanel.setSizer(sizer); to waxePanel.set_sizer(sizer);

To explore Waxe’s FileDialog class a little let’s add some functionality to the useless button from my NMEStage post. We’ll use the button to open a file dialog box and load in a .jpg or .png file and display it in on the NMEStage.
First let’s change the button’s text:
var button:Button = Button.create( waxePanel, null, 'Open a jpg or png');
And give it a function to perform when clicked:
button.onClick = showFileDialog;
Next up the showFileDialog method for our button it needs to take a single parameter of type Dynamic sent by the button when clicked:
private function showFileDialog( event:Dynamic )
{
}
Next we’ll make the file dialog inside the showFileDialog function:
var fileDialog:FileDialog = new FileDialog( frame , "Choose an image" , "" , "" , "PNG and JPG files|*.png;*.jpg|PNG files|*.png|JPG files|*.jpg");
In the FileDialog’s constructor we set it’s parent, the title text displayed in the FileDialog itself, default directory, default file, then a file filter string. Let’s take a closer look at the file filter string:
"PNG and JPG files|*.png;*.jpg|PNG files|*.png|JPG files|*.jpg"
The above string has 3 different filters, one that shows PNG and JPGs in the FileDialog, one that shows just PNGs and lastly one for just JPGs. Each filter takes the form:
|
multiple file filters are separated by a single | . Be careful of extra white spaces when listing file formats as this will stop filters working as expected.
With our FileDialog instanced we now need to show it. We do this with .showModal().
if( fileDialog.showModal() )
{
trace( "Selected" );
}
else
{
trace( "Cancelled" );
}
.showModal() returns a Bool when done. The Bool is true when a file has been selected, and false when the FileDialog has been cancelled without selecting a file. It also returns true if the user enters a file name with the keyboard and presses the open button, as it does not check whether the file exists when the user enters a file name we will have to check ourselves later.
Here’s what the showFileDialog method should look like so far:
private function showFileDialog( event:Dynamic )
{
var fileDialog:FileDialog = new FileDialog( frame , "Choose an image" , "" , "" , "PNG and JPG files|*.png;*.jpg|PNG files|*.png|JPG files|*.jpg");
//
if( fileDialog.showModal() )
{
trace( "Selected" );
}
else
{
trace( "Cancelled" );
}
}
To load the file we selected let’s replace “trace( “Selected” );” with some code to load our file:
// Build path
var path:String = fileDialog.directory + "/" + fileDialog.file ;
// File Exists?
if( !FileSystem.exists( path ) )
{
trace( "File does not exist." );
return;
}
loader = new nme.display.Loader( );
loader.contentLoaderInfo.addEventListener( nme.events.Event.COMPLETE , imageLoadComplete );
loader.load( new nme.net.URLRequest( path ) );
FileDialog has a number of useful properties for once the user has selected a file:
var path:String = fileDialog.directory + "/" + fileDialog.file ;
Here we build the path of our file from FileDialogs directory and file properties.
Next I check to see if the file exists using Neko or Cpp’s FileSystem.exists method:
if( !FileSystem.exists( path ) )
{
trace( "File does not exist." );
return;
}
Next the actual loading of the file using NME’s Loader class.
loader = new nme.display.Loader( );
loader.contentLoaderInfo.addEventListener( nme.events.Event.COMPLETE , imageLoadComplete );
loader.load( new nme.net.URLRequest( path ) );
Finally we need to add a handler for when loader completes it’s load operation:
private function imageLoadComplete( event:nme.events.Event ):Void
{
nmeStage.stage.addChild( loader );
}
We’ll need to change the nmeStage from a local variable to an instance variable so we can access it the handler, then we can add our image to it’s stage.
Here’s the full source:
package;
import wx.App;
import wx.Button;
import wx.Frame;
import wx.NMEStage;
import wx.Panel;
import wx.Sizer;
import wx.BoxSizer;
import wx.FileDialog;
import nme.display.StageAlign;
import nme.display.StageScaleMode;
import nme.events.Event;
import nme.net.URLRequest;
import nme.display.Loader;
#if neko
import sys.FileSystem;
#end
#if cpp
import sys.FileSystem;
#end
class Main
{
private var frame:Frame;
private var loader:Loader;
private var nmeStage:NMEStage;
function new()
{
// Make an app window
frame = Frame.create(null, "WaxeApp" , null , { width:400 , height:400 } );
// Make a panel
var waxePanel:Panel = Panel.create( frame );
var button:Button = Button.create( waxePanel, null, 'Open a jpg or png');
button.onClick = showFileDialog;
// Make an NME stage
nmeStage = NMEStage.create( waxePanel );
nmeStage.stage.align = StageAlign.TOP_LEFT;
nmeStage.stage.scaleMode = StageScaleMode.NO_SCALE;
// Draw something on the NMEStage
nmeStage.stage.graphics.beginFill( 0x000000 );
nmeStage.stage.graphics.drawCircle( 50 , 50 , 50 );
nmeStage.stage.graphics.endFill();
// Auto position the panel and NMEStage with a sizer
var sizer:Sizer = BoxSizer.create(true);
waxePanel.set_sizer(sizer);
sizer.add( button , 1 , Sizer.EXPAND | Sizer.BORDER_ALL , 5 );
sizer.add( nmeStage , 3 , Sizer.EXPAND | Sizer.BORDER_ALL , 5);
// Show your window
App.setTopWindow( frame );
frame.shown = true;
}
// Make and show the FileDialog
private function showFileDialog( event:Dynamic )
{
var fileDialog:FileDialog = new FileDialog( frame , "Choose an image" , "" , "" , "PNG and JPG files|*.png;*.jpg|PNG files|*.png|JPG files|*.jpg");
//
if( fileDialog.showModal() )
{
// Build path
var path:String = fileDialog.directory + "/" + fileDialog.file ;
// File Exists?
if( !FileSystem.exists( path ) )
{
trace( "File does not exist." );
return;
}
loader = new nme.display.Loader( );
loader.contentLoaderInfo.addEventListener( nme.events.Event.COMPLETE , imageLoadComplete );
loader.load( new nme.net.URLRequest( path ) );
}
else
{
trace( "Cancelled" );
}
}
// Loaded an Image
private function imageLoadComplete( event:nme.events.Event ):Void
{
nmeStage.stage.addChild( loader );
}
// Entry
public static function main()
{
App.boot( function(){ new Main(); } );
}
}