iup-stack/iup/srclua5/iuplua_tree_aux.c

186 lines
4.5 KiB
C
Raw Normal View History

2023-02-20 16:44:45 +00:00
/** \file
* \brief iuptree binding for Lua 5.
*
* See Copyright Notice in "iup.h"
*/
#include <lua.h>
#include <lauxlib.h>
#include "iup.h"
#include "iuplua.h"
#include "il.h"
/*
The REGISTRY is used to store references to the associated Lua objects.
Given an ID, to retrieve a Lua object is quite simple.
But given a user_id to obtain the ID is more complicated.
The iup.TREEREFTABLE is used to do this mapping.
We use the object as the index to this table.
*/
/* iup.TREEREFTABLE[object at pos] = ref */
static void tree_settableref(lua_State *L, int pos, int ref)
{
iuplua_push_name(L, "TREEREFTABLE");
lua_pushvalue(L, pos);
if(ref == LUA_NOREF)
lua_pushnil(L);
else
lua_pushinteger(L, ref);
lua_settable(L, -3);
lua_pop(L, 1);
}
/* ref = iup.TREEREFTABLE[object at pos] */
static int tree_gettableref(lua_State *L, int pos)
{
iuplua_push_name(L, "TREEREFTABLE");
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_tointeger(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_rawgeti(L, LUA_REGISTRYINDEX, 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_pushinteger(L, id);
}
return 1;
}
static int TreeGetUserId(lua_State *L)
{
Ihandle *ih = iuplua_checkihandle(L,1);
int id = (int)luaL_checkinteger(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_checkinteger(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_rawgeti(L, LUA_REGISTRYINDEX, ref);
tree_settableref(L, 4, LUA_NOREF);
luaL_unref(L, LUA_REGISTRYINDEX, ref);
lua_pop(L, 1);
}
if (lua_isnil(L, 3))
IupTreeSetUserId(ih, id, NULL);
else
{
/* add a new reference */
lua_pushvalue(L, 3);
ref = luaL_ref(L, LUA_REGISTRYINDEX);
tree_settableref(L, 3, ref);
if (ref >= 0) ref++; /* only positive references are shifted */
IupTreeSetUserId(ih, id, (void*)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_createtable(L, p1, 0);
for (i = 0; i < p1; i++)
{
lua_pushinteger(L,i+1);
lua_pushinteger(L,ids[i]);
lua_settable(L,-3);
}
lua_pushinteger(L, p1);
return iuplua_call(L, 2);
}
static int tree_multiunselection_cb(Ihandle *ih, int* ids, int p1)
{
int i;
lua_State *L = iuplua_call_start(ih, "multiunselection_cb");
lua_createtable(L, p1, 0);
for (i = 0; i < p1; i++)
{
lua_pushinteger(L,i+1);
lua_pushinteger(L,ids[i]);
lua_settable(L,-3);
}
lua_pushinteger(L, p1);
return iuplua_call(L, 2);
}
static int tree_noderemoved_cb(Ihandle *ih, void* p1)
{
lua_State *L = iuplua_call_start(ih, "noderemoved_cb");
tree_push_userid(L, p1);
return iuplua_call(L, 1);
}
void iuplua_treefuncs_open (lua_State *L)
{
iuplua_register_cb(L, "MULTISELECTION_CB", (lua_CFunction)tree_multiselection_cb, NULL);
iuplua_register_cb(L, "MULTIUNSELECTION_CB", (lua_CFunction)tree_multiunselection_cb, NULL);
iuplua_register_cb(L, "NODEREMOVED_CB", (lua_CFunction)tree_noderemoved_cb, NULL);
/* Table/Userdata <-> id */
iuplua_register(L, TreeGetId, "TreeGetId");
iuplua_register(L, TreeGetUserId, "TreeGetUserId");
iuplua_register(L, TreeSetUserId, "TreeSetUserId");
/* OLD names for backward compatibility */
iuplua_register(L, TreeGetId, "TreeGetTableId");
iuplua_register(L, TreeGetUserId, "TreeGetTable");
iuplua_register(L, TreeSetUserId, "TreeSetTableId");
}