Desktop applications with Haxe and Waxe – Part 5: Menus

Posted on May 22, 2012

4


Every classic desktop application has a top menu bar that at least lets us quit the program. So let’s create one! We start with an empty directory, and add the following MenuTest.hx…


import wx.Frame;
import wx.Menu;
import wx.Panel;
import wx.MenuBar;

class MenuTest {
public function new() {
    var frame = ApplicationMain.frame;
    var panel = Panel.create(frame);

    var menuBar = new MenuBar();
    frame.menuBar = menuBar;

    var menuFile = new Menu();
    menuBar.append(menuFile, 'File');
}

static public function main() {
    new MenuTest();
}
}

…and the following MenuTest.nmml:


<?xml version="1.0" encoding="utf-8"?>
<project>
<app
file="MenuTest"
title="MenuTest"
package="any.thing.test"
version="1.0"
company="waxe"
main="MenuTest"
/>

<window
width="600"
height="400"
orientation="landscape"
fps="24"
background="0xffffff"
resizeable="true"
hardware="true"
/>

<haxelib name="waxe" />

<ndll name="waxe" haxelib="waxe" />
<ndll name="std" />
<ndll name="zlib" />
<ndll name="regexp" />

</project>

Go ahead and compile with

> haxelib run nme test MenuTest.nmml neko

(For compiling to c++/windows target, check Part 1).

Now, you should see an application window with a top horizontal menubar, something like this:

So, what’s going on?

We start by creating the menubar object, and directly after that telling the frame (our active application window) to use this menubar:

        var menuBar = new MenuBar();
        frame.menuBar = menuBar;

After that we create our first menu object, wich will become the first “column” of menu alternatives. We stick to common practice and start with a file menu (for that we choose the intance name “menuFile”). Then we append our menuFile to the top menuBar, giving it the lable title “File”:

        var menuFile = new Menu();
        menuBar.append(menuFile, 'File');

Now we have a top menuBar and a first menuFile object displaying itself as “File”, but to create something useful, we have to append some menu alternatives to the menuFile. Add the following lines:

        menuFile.append(0, 'Test');
        menuFile.appendSeparator();
        menuFile.append(999, 'Quit');

After compiling, clicking the “File” label now gives us the following dropdown menu:

So, how to get some work done?

We might think that it’s the menu object itself that will take care of the action for us, or maybe thet menubar – but it’s actually the application window (here named “frame”). It has a .handle() method that lets us add callback functions corresponding to our menu alternatives. Try adding the following two lines:

        frame.handle(0, function(_) { trace('Menu test clicked'); } );
        frame.handle(999, function(_) { wx.App.quit(); } );

As you can see, the first parameter is an id that corresponds to the id used when creating the alternatives, and the second parameter is a callback function.

The Quit alternative was created with an id of 999, and the corresponding handle function will execute the wx.App.quit() method (wich is the wxWidgets way of pass away).

So, now go ahead and create another menu, for example a help menu, add it to the menubar and start populate it with alternatives and corresponding handlers!

Check and radio alternatives – unfinished!

When creating the menu alternatives, we also have the possibility to give them check- or radiobutton behaviours. Try adding the following lines between the test menu alternative and the quit menu alternative:

        menuFile.appendSeparator();
        menuFile.append(10, 'Check', null, Menu.CHECK);
        menuFile.appendSeparator();
        menuFile.append(20, 'Radio 1', null, Menu.RADIO);
        menuFile.append(21, 'Radio 2', null, Menu.RADIO);
        menuFile.appendSeparator();

After compiling, it should give something like this:

Those alternatives can be handled in the same manner as showed above. Unfortunately, this far I haven’t figured out

  1. if there’s a way to programmatically track the status wether the menualternative is set/unset
  2. if there’s a way to programmatically set the status by code

Any ideas how to do this?



About these ads
Posted in: Haxe, Waxe