summaryrefslogtreecommitdiff
path: root/iup/srclua5/iuplua.lua
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/srclua5/iuplua.lua
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srclua5/iuplua.lua')
-rwxr-xr-xiup/srclua5/iuplua.lua285
1 files changed, 285 insertions, 0 deletions
diff --git a/iup/srclua5/iuplua.lua b/iup/srclua5/iuplua.lua
new file mode 100755
index 0000000..b0f644a
--- /dev/null
+++ b/iup/srclua5/iuplua.lua
@@ -0,0 +1,285 @@
+-- This file is executed with the "iup" table already as the globalindex
+
+------------------------------------------------------------------------------
+-- Callback handler
+------------------------------------------------------------------------------
+
+callbacks = {}
+
+function iupCallMethod(name, ...)
+ local handle = arg[1] -- always the handle
+ local func = handle[name]
+ if (not func) then
+ return
+ end
+
+ if type(func) == "function" then
+ return func(unpack(arg))
+ elseif type(func) == "string" then
+ local temp = self
+ self = handle
+ local result = iup.dostring(func)
+ self = temp
+ return result
+ else
+ return iup.ERROR
+ end
+end
+
+function RegisterCallback(name, func, type)
+ if not callbacks[name] then callbacks[name] = {} end
+ local cb = callbacks[name]
+ if type then
+ cb[type] = func
+ else
+ cb[1] = func
+ end
+end
+
+------------------------------------------------------------------------------
+-- Meta Methods
+------------------------------------------------------------------------------
+
+
+local widget_gettable = function(object, index)
+ local p = object
+ local v
+ while 1 do
+ v = rawget(p, index)
+ if v then return v end
+ p = rawget(p, "parent")
+ if not p then return nil end
+ end
+end
+
+iupNewClass("iup widget")
+iupSetMethod("iup widget", "__index", widget_gettable)
+
+
+local ihandle_gettable = function(handle, index)
+ local INDEX = string.upper(index)
+ if (callbacks[INDEX]) then
+ local object = iupGetWidget(handle)
+ if (not object or type(object)~="table") then error("invalid iup handle") end
+ return object[index]
+ else
+ local value = GetAttribute(handle, INDEX)
+ if (not value) then
+ local object = iupGetWidget(handle)
+ if (not object or type(object)~="table") then error("invalid iup handle") end
+ return object[index]
+ elseif type(value)== "number" or type(value) == "string" then
+ local ih = GetHandle(value)
+ if ih then return ih
+ else return value end
+ else
+ return value
+ end
+ end
+end
+
+local ihandle_settable = function(handle, index, value)
+ local ti = type(index)
+ local tv = type(value)
+ local object = iupGetWidget(handle)
+ if (not object or type(object)~="table") then error("invalid iup handle") end
+ if ti == "number" or ti == "string" then -- check if a valid C name
+ local INDEX = string.upper(index)
+ local cb = callbacks[INDEX]
+ if (cb) then -- if a callback name
+ local func = cb[1]
+ if (not func) then
+ func = cb[GetClassName(handle)]
+ end
+ iupSetCallback(handle, INDEX, func, value) -- register the pre-defined C callback
+ object[index] = value -- store also in Lua
+ elseif iupGetClass(value) == "iup handle" then -- if a iup handle
+ local name = ihandle_setname(value)
+ SetAttribute(handle, INDEX, name)
+ object[index] = nil -- if there was something in Lua remove it
+ elseif tv == "string" or tv == "number" or tv == "nil" then -- if a common value
+ SetAttribute(handle, INDEX, value)
+ object[index] = nil -- if there was something in Lua remove it
+ else
+ object[index] = value -- store also in Lua
+ end
+ else
+ object[index] = value -- store also in Lua
+ end
+end
+
+iupNewClass("iup handle")
+iupSetMethod("iup handle", "__index", ihandle_gettable)
+iupSetMethod("iup handle", "__newindex", ihandle_settable)
+iupSetMethod("iup handle", "__tostring", ihandle_tostring)
+iupSetMethod("iup handle", "__eq", ihandle_compare) -- implemented in C
+
+
+------------------------------------------------------------------------------
+-- Utilities
+------------------------------------------------------------------------------
+
+function ihandle_setname(v) -- used also by radio and zbox
+ local name = GetName(v)
+ if not name then
+ local autoname = string.format("_IUPLUA_NAME(%s)", tostring(v))
+ SetHandle(autoname, v)
+ return autoname
+ end
+ return name
+end
+
+function iupRegisterWidget(ctrl) -- called by all the controls initialization functions
+ iup[ctrl.nick] = function(arg)
+ return ctrl:constructor(arg)
+ end
+end
+
+function RegisterHandle(handle, typename)
+
+ iupSetClass(handle, "iup handle")
+
+ local object = iupGetWidget(handle)
+ if not object then
+
+ local class = iup[string.upper(typename)]
+ if not class then
+ class = WIDGET
+ end
+
+ local object = { parent=class, handle=handle }
+ iupSetClass(object, "iup widget")
+ iupSetWidget(handle, object)
+ end
+
+ return handle
+end
+
+------------------------------------------------------------------------------
+-- Widget class (top class)
+------------------------------------------------------------------------------
+
+WIDGET = {
+ callback = {}
+}
+
+function WIDGET.show(object)
+ Show(object.handle)
+end
+
+function WIDGET.hide(object)
+ Hide(object.handle)
+end
+
+function WIDGET.map(object)
+ Map(object.handle)
+end
+
+function WIDGET.constructor(class, arg)
+ local handle = class:createElement(arg)
+ local object = {
+ parent = class,
+ handle = handle
+ }
+ iupSetClass(handle, "iup handle")
+ iupSetClass(object, "iup widget")
+ iupSetWidget(handle, object)
+ object:setAttributes(arg)
+ return handle
+end
+
+function WIDGET.setAttributes(object, arg)
+ local handle = object.handle
+ for i,v in pairs(arg) do
+ if type(i) == "number" and iupGetClass(v) == "iup handle" then
+ -- We should not set this or other elements (such as iuptext)
+ -- will erroneosly inherit it
+ rawset(object, i, v)
+ else
+ -- this will call settable metamethod
+ handle[i] = v
+ end
+ end
+end
+
+-- all the objects in the hierarchy must be "iup widget"
+-- Must repeat this call for every new widget
+iupSetClass(WIDGET, "iup widget")
+
+
+------------------------------------------------------------------------------
+-- Box class (inherits from WIDGET)
+------------------------------------------------------------------------------
+
+BOX = {
+ parent = WIDGET
+}
+
+function BOX.setAttributes(object, arg)
+ local handle = rawget(object, "handle")
+ local n = #arg
+ for i = 1, n do
+ if iupGetClass(arg[i]) == "iup handle" then
+ Append(handle, arg[i])
+ end
+ end
+ WIDGET.setAttributes(object, arg)
+end
+
+iupSetClass(BOX, "iup widget")
+
+
+------------------------------------------------------------------------------
+-- Compatibility functions.
+------------------------------------------------------------------------------
+
+error_message_popup = nil
+
+function _ERRORMESSAGE(err,traceback)
+ err = err..(traceback or "")
+ if (error_message_popup) then
+ error_message_popup.value = err
+ else
+ local bt = button{title="Ok", size="60", action="error_message_popup = nil; return iup.CLOSE"}
+ local ml = multiline{expand="YES", readonly="YES", value=err, size="300x150"}
+ local vb = vbox{ml, bt; alignment="ACENTER", margin="10x10", gap="10"}
+ local dg = dialog{vb; title="Error Message",defaultesc=bt,defaultenter=bt,startfocus=bt}
+ error_message_popup = ml
+ dg:popup(CENTER, CENTER)
+ dg:destroy()
+ error_message_popup = nil
+ end
+end
+
+pack = function (...) return arg end
+
+function protectedcall_(f, err)
+ if not f then
+ _ERRORMESSAGE(err)
+ return
+ end
+ local ret = pack(pcall(f))
+ if not ret[1] then
+ _ERRORMESSAGE(ret[2])
+ return
+ else
+ table.remove(ret, 1)
+ return unpack(ret)
+ end
+end
+
+function dostring(s) return protectedcall_(loadstring(s)) end
+function dofile(f) return protectedcall_(loadfile(f)) end
+
+function RGB(r, g, b)
+ return string.format("%d %d %d", 255*r, 255*g, 255*b)
+end
+
+-- This will allow both names to be used in the same application
+-- also will allow static linking to work with require
+if _G.package then
+ _G.package.loaded["iuplua"] = iup
+ _G.package.loaded["iuplua51"] = iup
+ iup._M = iup
+ iup._PACKAGE = "iuplua"
+end