Lua bindings for dialogs and menus

The ipeui module provides dialogs and popup menus for Lua. It does not depend on any other Ipe component, and can be reused in other Lua projects.

Global methods

There are a few global methods in the ipeui module:

ipeui.mainLoop()          -- start event loop
ipeui.closeAllWindows()   -- sends all windows a close event
ipeui.startBrowser(url)   -- on Windows platform only
ipeui.setClipboard(text)  -- store text on system clipboard
text = ipeui.clipboard()  -- get text property from system clipboard

Predefined dialogs

The following are predefined dialogs. In all cases, parent can either be nil or an Appui object.

-- request a string input from user
-- returns string or nil if cancelled
response = ipeui.getString(parent, prompt)

-- get a filename from user
-- type is "open" or "save"
-- filter e.g. "XML (*.xml);;PDF (*.pdf)"
-- dir is nil or a starting directory
-- selected is nil or the filter originally selected
-- returns nil if the dialog is canceled
-- or filename and selected filter
ipeui.fileDialog(parent, type, caption, filter, dir, selected)

-- show a message box
-- type is one of "none" "warning" "information" "question" "critical"
-- details may be nil
-- buttons may be nil (for "ok") or one of 
-- "ok" "okcancel" "yesnocancel", "discardcancel", "savediscardcancel", 
-- return 1 for ok/yes/save, 0 for no/discard, -1 for cancel
ipeui.messageBox(parent, type, text, details, buttons)

-- this dialog only returns when the external editor has finished
ipeui.WaitDialog(parent, command)

Dialogs

Other dialogs can be constructed programmatically:

d = ipeui.Dialog(parent, window_title)

d:setStretch("row", row_number, stretch_factor)
d:setStretch("column", row_number, stretch_factor)
d:add(name, what, options, row, column, row_span, column_span)
d:set(name, value)
value = d:get(name)

-- returns true if dialog was accepted
d:execute()
d:execute(size)   -- where size == { width, height }

name can be an arbitrary string. what must be one of

button, text, list, label, combo, checkbox, input

options is a table. Most fields are optional:

-- button:
label="string"  (Required!)
action="accept" or "reject" or a Lua method

-- label:
label="string"  (Required!)

-- text:
read_only=bool
syntax="logfile" or "xml" or "latex"

-- list and combo:
array of list items (strings)

-- checkbox:
label="string"  (Required!)
action= Lua method  (called when state changed)

-- input:

The argument of set is:

The result value of get is:

Popup menus

Popup menus are constructed and shown as follows:

m = ipeui.Menu()	
item, no, subitem = m:execute(global_position)

When the menu is cancelled, execute returns nil.

You can then add items to the menu one by one. A simple item is added like this:

m:add("name", "Label")

When this item is selected, execute returns name, 0, and an empty string.

The following line adds an entire submenu:

m:add("name", "Submenu", { "alpha", "beta", "gamma" } )

When an item from this submenu is selected, execute returns name, the index into the submenu, and the name of the submenu item.

When the strings in the table are not directly the visible labels for the submenu, a Lua function can be used to convert them:

m:add("name", "Submenu", { "alpha", "beta", "gamma" },
      function (i, item) return "select " .. item end )

The final argument can either be a string or a function. If it is a string, then all items are checkable, and the item whose name is identical to the final argument is checked. Otherwise, the function maps item number and name to a color (three numbers in the range 0.0 to 1.0). This is then used to display a color icon.

Timers

Timers are constructed as follows:

t = ipeui.Timer(parent, table, "method")

When the timer times out, it will call the method named method in the Lua table table. The timer stores only a weak reference to the table, so the timer will not stop the table from being garbage collected.

The timer is controlled using the methods:

timer:setInterval(interval)     -- an integer in milliseconds
timer:setSingleShot(bool)
timer:start()	
timer:stop()
a = timer:active()              -- true if the timer is running