diff options
author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 |
commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/srclua5/il_tree_aux.c |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srclua5/il_tree_aux.c')
-rwxr-xr-x | iup/srclua5/il_tree_aux.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/iup/srclua5/il_tree_aux.c b/iup/srclua5/il_tree_aux.c new file mode 100755 index 0000000..99e721b --- /dev/null +++ b/iup/srclua5/il_tree_aux.c @@ -0,0 +1,184 @@ +/** \file + * \brief iuptree binding for Lua 5. + * + * See Copyright Notice in "iup.h" + */ + +#include <lua.h> +#include <lauxlib.h> + +#include "iup.h" +#include "iupcontrols.h" + +#include "iuplua.h" +#include "il.h" +#include "il_controls.h" + +/* + The REGISTRY is used to store references to the associated Lua objects. + Given an ID, to retreive a Lua object is quite simple. + + But given a user_id to obtain the ID is more complicated. + The IUPTREEREFTABLE is used to do this mapping. + We use the object as the index to this table. +*/ + +/* iup.IUPTREEREFTABLE[object at pos] = ref */ +static void tree_settableref(lua_State *L, int pos, int ref) +{ + lua_getglobal(L, "iup"); + lua_pushstring(L, "IUPTREEREFTABLE"); + lua_gettable(L, -2); + lua_remove(L, -2); + lua_pushvalue(L, pos); + if(ref == LUA_NOREF) + lua_pushnil(L); + else + lua_pushnumber(L, ref); + lua_settable(L, -3); + lua_pop(L, 1); +} + +/* ref = iup.IUPTREEREFTABLE[object at pos] */ +static int tree_gettableref(lua_State *L, int pos) +{ + lua_getglobal(L, "iup"); + lua_pushstring(L, "IUPTREEREFTABLE"); + lua_gettable(L, -2); + lua_remove(L, -2); + lua_pushvalue(L, pos); + lua_gettable(L, -2); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + return LUA_NOREF; + } + else + { + int ref = (int) lua_tonumber(L, -1); + lua_pop(L, 1); + return ref; + } +} + +static void tree_push_userid(lua_State *L, void* userid) +{ + int ref = (int)userid; + if (ref == 0) /* userid is actually NULL */ + lua_pushnil(L); + else + { + if (ref > 0) ref--; /* only positive references are shifted */ + lua_getref(L, ref); + } +} + +/***************************************************************************** + * Userdata/Table <-> id functions + ****************************************************************************/ + +static int TreeGetId(lua_State *L) +{ + Ihandle *ih = iuplua_checkihandle(L,1); + int ref = tree_gettableref(L, 2); + if (ref == LUA_NOREF) + lua_pushnil(L); + else + { + int id; + if (ref >= 0) ref++; /* only positive references are shifted */ + id = IupTreeGetId(ih, (void*)ref); + if (id == -1) + lua_pushnil(L); + else + lua_pushnumber(L, id); + } + return 1; +} + +static int TreeGetUserId(lua_State *L) +{ + Ihandle *ih = iuplua_checkihandle(L,1); + int id = (int)luaL_checknumber(L,2); + tree_push_userid(L, IupTreeGetUserId(ih, id)); + return 1; +} + +static int TreeSetUserId(lua_State *L) +{ + Ihandle *ih = iuplua_checkihandle(L,1); + int id = (int)luaL_checknumber(L,2); + int ref = (int)IupTreeGetUserId(ih, id); + if (ref != 0) /* userid is not NULL */ + { + if (ref > 0) ref--; /* only positive references are shifted */ + + /* release the previous object referenced there */ + lua_getref(L, ref); + tree_settableref(L, 4, LUA_NOREF); + lua_unref(L, ref); + lua_pop(L, 1); + } + + if (lua_isnil(L, 3)) + IupTreeSetUserId(ih, id, NULL); + else + { + /* add a new reference */ + lua_pushvalue(L, 3); + ref = lua_ref(L, 1); + tree_settableref(L, 3, ref); + + if (ref >= 0) ref++; /* only positive references are shifted */ + IupTreeSetUserId(ih, id, (char*)ref); + } + + return 0; +} + +static int tree_multiselection_cb(Ihandle *ih, int* ids, int p1) +{ + int i; + lua_State *L = iuplua_call_start(ih, "multiselection_cb"); + lua_newtable(L); + for (i = 0; i < p1; i++) + { + lua_pushnumber(L,i+1); + lua_pushnumber(L,ids[i]); + lua_settable(L,-3); + } + lua_pushnumber(L, p1); + return iuplua_call(L, 2); +} + +static int tree_noderemoved_cb(Ihandle *ih, int id, void* p1) +{ + lua_State *L = iuplua_call_start(ih, "noderemoved_cb"); + lua_pushnumber(L, id); + tree_push_userid(L, p1); + return iuplua_call(L, 2); +} + +void iuplua_treefuncs_open (lua_State *L) +{ + iuplua_dostring(L, "IUPTREEREFTABLE={}", ""); + + iuplua_register_cb(L, "MULTISELECTION_CB", (lua_CFunction)tree_multiselection_cb, NULL); + iuplua_register_cb(L, "NODEREMOVED_CB", (lua_CFunction)tree_noderemoved_cb, NULL); + +/* In Lua 5: + TreeSetTableId = TreeSetUserId + TreeGetTable = TreeGetUserId + TreeGetTableId = TreeGetId +*/ + + /* Userdata <-> id */ + iuplua_register(L, TreeGetId, "TreeGetId"); + iuplua_register(L, TreeGetUserId, "TreeGetUserId"); + iuplua_register(L, TreeSetUserId, "TreeSetUserId"); + + /* Table <-> id */ + iuplua_register(L, TreeGetId, "TreeGetTableId"); + iuplua_register(L, TreeGetUserId, "TreeGetTable"); + iuplua_register(L, TreeSetUserId, "TreeSetTableId"); +} |