RiscLua comes with a simple library sytem. The libraries are held
in the directory
!lua.lib and are accessed using the
word
require . We will look at the example wimp
application
!Snerp which does not do very much but
shows how use of libraries can simplify coding. Its
!RunImage file starts with
-- load definitions -----------------------
require "wimp.events"
require "wimp.messages"
require "wimp.task"
require "wimp.ibaricon"
require "wimp.templates"
require "wimp.window"
The
wimp.events library simply names the event codes
used by the Wimp_Poll SWI. Similarly the
wimp.messages library names wimp message numbers. The
wimp.task library returns a single function
task which expects
three arguments: the task name, 100 times the version number of
RISC OS (310 is the default value if the argument is omitted) and
a list of all the messages, apart from
Quit which
the task is to receive. It returns a table with entries
b message block
title title
titleb block holding title
mesgb block holding message list
errb error block
pollw block holding pollword
taskhandle a number
handler table of handler functions
indexed by reason codes. A
handler function is a method
(only argument is 'self')
which returns nil to cause
the task to exit.
mask poll event mask - this needs
explicit setting
and methods
init register the task with the
window manager
closedown deregister the task with the
window manager
run enter the polling loop
try protect a method so that
errors cause task to exit
preclosedown run before closing task down
report put up a report dialog box
messagehandler handle all messgaes except Quit
ack acknowledge a Dataload
message and jumps to a
continuation method, which takes
the filename and filetype of
the dataload as arguments.
The rest of the program inside
!Snerp.!RunImage is
in a
do . . . until loop. The first line creates the
task and names it.
local snerp = task("Snerp",310,{ --[[
messages we want to receive]]
DataLoad;
})
The remainder of the program describes snerp's properties,
for example
snerp.mask = 0x3933
(see PRM 3-116/7) and ends with
-- register snerp ---------
snerp:init()
-- create iconbar icon ----------------------
assert(ibaricon(snerp,"!snerp",
"<Snerp$dir>.Templates"),
"Cannot create iconbar icon") --[[
defines snerp.ibaricon]]
local windata =
templates("<Snerp$dir>.Templates",{"main"})
snerp.main = createwindow(windata.main.def)
-- run it ---------------
snerp:run()
The
wimp.ibaricon library returns a single function
ibaricon . It expects three arguments, the task, the name
of the sprite to put on the iconbar, and the name of the template file
containing the
info dialog box for the iconbar menu.
The
wimp.templates library defines the function
templates which expects two arguments, the name of the templates
file, and a list of some of the window names defined there. It returns
a table, indexed by those names, of window data. Each datum is a table
with keys
def , a pointer to a window definition block
and
work , a pointer to a block for indirected data.
The
wimp.window library defines the function
createwindow which expects as argument a pointer to a
window definition block and which returns the window's handle.
The use of these two libraries means that you do not need to
know the details of how windows are defined.
The only parts of the program we have not described are snerp's
handler functions, which describe its responses to wimp events and
to messages.
-- snerp's actions
snerp.dragtoiconbar = \ (self,x,y,fname,ftype)
self:report(fname.." dragged to Snerp icon")
=> true
end -- function
snerp.dragtomain = \ (self,x,y,fname,ftype)
self:report(fname.." dragged to Snerp main window")
=> true
end -- function
snerp.ibarSelect = \ (self)
local b,main,mainopen in self
local r,! in swi
if not mainopen then
b[0] = main
b[1],b[2],b[3],b[4] = 200,200,800,600
b[5],b[6] = 0,0
b[7] = -1
r[1] = b
!(0x400c5) -- Wimp_OpenWindow
self.mainopen = true
end -- if
-- self:report "Select clicked on !Snerp icon"
=> true
end -- function
snerp.ibarAdjust = \ (self)
self:report "Adjust clicked on !Snerp icon"
=> true
end -- function
snerp.mainclick = \ (self)
self:report "Main window clicked"
=> true
end -- function
-- define snerp's event handlers ---------------
snerp.handler[Open_Window_Request] = \ (self)
local b in self
local r,! in swi
r[1] = b
=> !(0x400c5) -- Wimp_OpenWindow
end
snerp.handler[Close_Window_Request] = \ (self)
local b,main in self
local r,! in swi
r[1] = b
!(0x400c6) -- Wimp_CloseWindow
if b[0] == main then
self.mainopen = false
end -- if
=> true
end
snerp.handler[Mouse_Click] = \ (self)
local b,ibaricon,main,ibarAdjust,ibarSelect in self
if b[3] == -2 and b[4] == ibaricon.handle then
local click = {
[1] = ibarAdjust;
[2] = ibaricon.menuopen; -- sets snerp.lastmenu
[4] = ibarSelect;
}
local clickval = b[2]
local action = click[clickval]
if action then => action(self) end -- if
end -- if
if b[3] == main then
=> self:mainclick()
end -- if
=> true
end -- function
snerp.handler[Menu_Selection] = \ (self)
local lastmenu, ibaricon in self
local item = self.b[0]
if lastmenu == ibaricon.menu then
if item == 1 then
os.execute("filer_run <Snerp$Dir>.!Help")
=> true
end -- if
if item == 2 then
=> nil -- exit
end -- if
end -- if
=> true
end -- function
-- define snerp's message handler -------
snerp.messagehandler = \ (self)
local b,ibaricon,main,dragtoiconbar,dragtomain in self
local mesg = b[4]
if mesg == DataLoad then
if b[5] == -2 and b[6] == ibaricon.handle then
=> self:ack(dragtoiconbar,true)
end -- if
if b[5] == main then
=> self:ack(dragtomain,true)
end -- if
end -- if
end -- function
The message handler responds to drags to the iconbar, calling
dragtoiconbar and drags into the main window, calling
dragtomain . The event handler responds to requests to
open a window, to close a window, to mouse-clicks and to menu-selections.
Note that each handler is a function of one argument,
self , and returns a non-nil value unless it causes the task to quit.