326 lines
8.5 KiB
Lua
Executable File
326 lines
8.5 KiB
Lua
Executable File
|
|
------------------------------------------------------------------------------
|
|
-- Callback handler
|
|
------------------------------------------------------------------------------
|
|
|
|
iup.callbacks = {} -- storage for the C callbacks
|
|
|
|
function iup.CallMethod(name, ...)
|
|
local ih = ... -- the first argument is always the iupHandle
|
|
local lua_func = ih[name] -- use "gettable" to retrieve the Lua callback
|
|
if (not lua_func) then
|
|
return
|
|
end
|
|
|
|
if type(lua_func) == "function" then
|
|
return lua_func(...)
|
|
elseif type(lua_func) == "string" then
|
|
local temp = self
|
|
self = ih
|
|
local result = iup.dostring(lua_func)
|
|
self = temp
|
|
return result
|
|
else
|
|
return iup.ERROR
|
|
end
|
|
end
|
|
|
|
function iup.RegisterCallback(name, c_func, type)
|
|
-- Store a C callback for future use
|
|
if not iup.callbacks[name] then iup.callbacks[name] = {} end
|
|
local cb = iup.callbacks[name]
|
|
if type then
|
|
cb[type] = c_func
|
|
else
|
|
cb[1] = c_func
|
|
end
|
|
end
|
|
|
|
function iup.CallGlobalMethod(name, ...)
|
|
local INDEX = string.upper(name)
|
|
local cb = iup.callbacks[INDEX]
|
|
if (not cb) then
|
|
return
|
|
end
|
|
|
|
local lua_func = cb[2]
|
|
if type(lua_func) == "function" then
|
|
return lua_func(...)
|
|
elseif type(lua_func) == "string" then
|
|
return iup.dostring(lua_func)
|
|
else
|
|
return iup.ERROR
|
|
end
|
|
end
|
|
|
|
function iup.SetGlobalCallback(name, lua_func)
|
|
local INDEX = string.upper(name)
|
|
local cb = iup.callbacks[INDEX]
|
|
if (cb) then -- if a callback name
|
|
if (lua_func) then
|
|
local c_func = cb[1]
|
|
iup.SetFunction(INDEX, c_func) -- set the pre-defined C callback
|
|
else
|
|
iup.SetFunction(INDEX, nil)
|
|
end
|
|
cb[2] = lua_func -- store also the Lua callback
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Meta Methods
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
-- this is a Lua table for control construction, see iup.WIDGET and iup.BOX
|
|
-- not used by applications
|
|
|
|
-- implements class inheritance for iupWidget
|
|
local widget_gettable = function(widget, index)
|
|
local p = widget
|
|
local v
|
|
while p do
|
|
v = rawget(p, index)
|
|
if v then
|
|
return v
|
|
end
|
|
|
|
p = rawget(p, "parent")
|
|
end
|
|
return nil
|
|
end
|
|
|
|
iup.NewClass("iupWidget")
|
|
iup.SetMethod("iupWidget", "__index", widget_gettable)
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- this is an Ihandle* with enhancements
|
|
|
|
local ihandle_gettable = function(ih, index)
|
|
local INDEX = string.upper(index)
|
|
if (iup.callbacks[INDEX]) then
|
|
local widget = iup.GetWidget(ih)
|
|
if (not widget or type(widget)~="table") then error("invalid IUP handle") end
|
|
return widget[index]
|
|
else
|
|
local value = iup.GetAttribute(ih, INDEX)
|
|
if (not value) then
|
|
local widget = iup.GetWidget(ih)
|
|
if (not widget or type(widget)~="table") then error("invalid IUP handle") end
|
|
return widget[index]
|
|
elseif type(value)== "number" or type(value) == "string" then
|
|
local ih = iup.GetHandle(value)
|
|
if ih then
|
|
return ih
|
|
else
|
|
return value
|
|
end
|
|
else
|
|
return value
|
|
end
|
|
end
|
|
end
|
|
|
|
local ihandle_settable = function(ih, index, value)
|
|
local ti = type(index)
|
|
local tv = type(value)
|
|
local widget = iup.GetWidget(ih)
|
|
if (not widget or type(widget)~="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 = iup.callbacks[INDEX]
|
|
if (cb) then -- if a callback name
|
|
local c_func = cb[1]
|
|
if (not c_func) then
|
|
c_func = cb[iup.GetClassName(ih)]
|
|
end
|
|
iup.SetCallback(ih, INDEX, c_func, value) -- set the pre-defined C callback
|
|
widget[index] = value -- store also in Lua
|
|
elseif iup.GetClass(value) == "iupHandle" then -- if an iupHandle
|
|
local name = iup.SetHandleName(value)
|
|
iup.SetAttribute(ih, INDEX, name)
|
|
widget[index] = nil -- if there was something in Lua remove it
|
|
elseif tv == "string" or tv == "number" or tv == "nil" then -- if a common value
|
|
iup.SetAttribute(ih, INDEX, value)
|
|
widget[index] = nil -- if there was something in Lua remove it
|
|
else
|
|
widget[index] = value -- store only in Lua
|
|
end
|
|
else
|
|
widget[index] = value -- store only in Lua
|
|
end
|
|
end
|
|
|
|
iup.NewClass("iupHandle")
|
|
iup.SetMethod("iupHandle", "__index", ihandle_gettable)
|
|
iup.SetMethod("iupHandle", "__newindex", ihandle_settable)
|
|
iup.SetMethod("iupHandle", "__tostring", iup.ihandle_tostring) -- implemented in C
|
|
iup.SetMethod("iupHandle", "__eq", iup.ihandle_compare) -- implemented in C
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Utilities
|
|
------------------------------------------------------------------------------
|
|
|
|
function iup.SetHandleName(v) -- used also by radio and zbox
|
|
local name = iup.GetName(v)
|
|
if not name then
|
|
local autoname = string.format("_IUPLUA_NAME(%s)", tostring(v))
|
|
iup.SetHandle(autoname, v)
|
|
return autoname
|
|
end
|
|
return name
|
|
end
|
|
|
|
function iup.RegisterWidget(ctrl) -- called by all the controls initialization functions
|
|
iup[ctrl.nick] = function(param)
|
|
if (not ctrl.constructor) then
|
|
error("IUP constructor missing for:" .. ctrl.nick)
|
|
end
|
|
return ctrl:constructor(param)
|
|
end
|
|
end
|
|
|
|
function iup.RegisterHandle(ih, typename)
|
|
|
|
iup.SetClass(ih, "iupHandle")
|
|
|
|
local widget = iup.GetWidget(ih)
|
|
if not widget then
|
|
local class = iup[string.upper(typename)]
|
|
if not class then
|
|
if (iup.IsContainer(ih)) then
|
|
class = iup.BOX
|
|
else
|
|
class = iup.WIDGET
|
|
end
|
|
end
|
|
|
|
local widget = {
|
|
parent = class,
|
|
ihandle = ih
|
|
}
|
|
iup.SetClass(widget, "iupWidget")
|
|
iup.SetWidget(ih, widget)
|
|
end
|
|
|
|
return ih
|
|
end
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Widget class (top class)
|
|
------------------------------------------------------------------------------
|
|
|
|
iup.WIDGET = {
|
|
callback = {}
|
|
}
|
|
|
|
function iup.WIDGET.constructor(class, param)
|
|
local ih = class:createElement(param) -- all classes must define createElement
|
|
local widget = {
|
|
parent = class,
|
|
ihandle = ih
|
|
}
|
|
iup.SetClass(ih, "iupHandle")
|
|
iup.SetClass(widget, "iupWidget")
|
|
iup.SetWidget(ih, widget)
|
|
widget:setAttributes(param)
|
|
return ih
|
|
end
|
|
|
|
function iup.WIDGET.setAttributes(widget, param)
|
|
local ih = widget.ihandle
|
|
for i,v in pairs(param) do
|
|
if type(i) == "number" and iup.GetClass(v) == "iupHandle" then
|
|
-- We should not set this or other elements (such as iuptext)
|
|
-- will erroneosly inherit it
|
|
rawset(widget, i, v)
|
|
else
|
|
-- this will call settable metamethod
|
|
ih[i] = v
|
|
end
|
|
end
|
|
end
|
|
|
|
function iup.WIDGET.show(ih)
|
|
iup.Show(ih)
|
|
end
|
|
|
|
function iup.WIDGET.hide(ih)
|
|
iup.Hide(ih)
|
|
end
|
|
|
|
function iup.WIDGET.map(ih)
|
|
iup.Map(ih)
|
|
end
|
|
|
|
function iup.WIDGET.unmap(ih)
|
|
iup.Unmap(ih)
|
|
end
|
|
|
|
function iup.WIDGET.detach(ih)
|
|
iup.Detach(ih)
|
|
end
|
|
|
|
function iup.WIDGET.destroy(ih)
|
|
iup.Destroy(ih)
|
|
end
|
|
|
|
-- all the objects in the hierarchy must be "iupWidget"
|
|
-- Must repeat this call for every new widget
|
|
iup.SetClass(iup.WIDGET, "iupWidget")
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Box class (inherits from WIDGET)
|
|
------------------------------------------------------------------------------
|
|
|
|
iup.BOX = {
|
|
parent = iup.WIDGET
|
|
}
|
|
|
|
function iup.BOX.setAttributes(widget, param)
|
|
-- iup.Append will be automatically called after createElement
|
|
-- no need to pass elements in the constructor of boxes
|
|
local ih = widget.ihandle
|
|
local n = #param
|
|
for i = 1, n do
|
|
if iup.GetClass(param[i]) == "iupHandle" then
|
|
iup.Append(ih, param[i])
|
|
end
|
|
end
|
|
iup.WIDGET.setAttributes(widget, param)
|
|
end
|
|
|
|
function iup.BOX.append(ih, child)
|
|
return iup.Append(ih, child)
|
|
end
|
|
|
|
function iup.BOX.insert(ih, ref_child, child)
|
|
return iup.Insert(ih, ref_child, child)
|
|
end
|
|
|
|
iup.SetClass(iup.BOX, "iupWidget")
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Compatibility functions.
|
|
------------------------------------------------------------------------------
|
|
|
|
function iup.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 for the main library (only)
|
|
if _G.package then
|
|
_G.package.loaded["iuplua"] = iup
|
|
iup._M = iup
|
|
iup._PACKAGE = "iuplua"
|
|
end
|
|
|
|
function iup.layoutdialog(obj)
|
|
return iup.LayoutDialog(obj[1])
|
|
end
|