Menus and Form Classes

Object-oriented style is particularly appropriate for GUI applications. Although Lua does not have a formal concept of 'class', it is not difficult to add a class mechanism. Then our forms can be self-contained objects, as is obligatory in C#. The classes described here are not proper derived classes of the .NET Form class, rather they use delegation; if our form object cannot find a method or property within itself, it calls the delegate object, which is a Form object.

-- menuform.lua
require "CLRForm"
 
MenuForm = class()
 
function MenuForm:_init ()
    self.form = Form()
    self.name = "Dolly"
    -- this method can only be called once we've set up our own fields!
    self:delegate(self.form)
    self.Text = "A Simple Form Class"
    self.FormBorderStyle = FormBorderStyle.FixedDialog
    self.MaximizeBox = false
    self.MinimizeBox = false
    self.ContextMenu = popup_menu {
        "First",method(self,self.first),
        "Second",method(self,self.second),
    }
end
 
function MenuForm:first()
    local name = PromptForString(arg[0],"Give the dog a name",self. name)
    if name then self.name = name end
end
 
function MenuForm:second()
    ShowMessageBox (self.name)
end
 
form = MenuForm()
form:ShowDialog()

Notice the useful popup_menu function, which takes some of the tedium out of defining menus. (A more complete example can be found in the source forlconsole.lua, where shortcuts are defined, etc.) The little function method has a simple definition; it creates a callback function which actually does the function call, passing the object as the first parameter (the self object):

function method (obj,fun)
    return function()
        fun(obj)
    end
end

Main menus are also easy to construct; here is how lconsole.wlua does its menu:

local menu = main_menu {
    "File",{
        "Load Lua(CtrlO)",load_lua,
        "Save Session(CtrlS)",save_session,
        "Save As Text",save_text,
        "E&xit(CtrlX)",function() os.exit(0) end,
    },
    "Run",{
        "Save and Go(F5)",save_and_go,
        "Create Function",function() fun() end,
        "Delete Item",delete_list_item,
        "Clear Code Pane",clear_code,
    },
    "History", {
        "Last(AltUpArrow)", function() get_history(true) end,
        "Previous(AltDownArrow)", function() get_history(false) end
    }
}

If an item string contains '(...)', then it's interpreted as a name from the System.Windows.Forms.Shortcut enumeration; see the .NET documentation for all available constants.