diff --git a/pd.lua b/pd.lua index 28b5dd1..ab8e080 100644 --- a/pd.lua +++ b/pd.lua @@ -91,6 +91,29 @@ pd._perform_dsp = function (object, ...) end end +-- draw properties +pd._properties = function (object) + local obj = pd._objects[object] + if nil ~= obj and type(obj.properties) == "function" then + obj:properties() + return true + else + pd.post("not found") + return false + end +end + +-- set properties +pd._set_properties = function (object, method, args) + local obj = pd._objects[object] + if obj ~= nil and type(obj[method]) == "function" then + local propertiesmethod = obj[method] + propertiesmethod(obj, args) -- Passa `obj` explicitamente como `self` + else + pd._error(obj._object, "method ".. method .. " does not exist") + end +end + -- repaint method dispatcher pd._repaint = function (object) local obj = pd._objects[object] @@ -457,6 +480,26 @@ function pd.Class:set_args(args) pd._set_args(self._object, args) end +function pd.Class:addproperties() + pd._properties_add(self._object) +end + +function pd.Class:newframe(title, max_col) + pd._properties_newframe(self._object, title, max_col) +end + +function pd.Class:addcheckbox(text, method, init_value) + pd._properties_addcheckbox(self._object, text, method, init_value) +end + +function pd.Class:addtextinput(text, method, init_value, width) + pd._properties_addtextinput(self._object, text, method, init_value, width) +end + +function pd.Class:addcolorpicker(text, method) + pd._properties_addcolorpicker(self._object, text, method) +end + function pd.Class:canvas_realizedollar(s) return pd._canvas_realizedollar(self._object, s) end diff --git a/pdlua.c b/pdlua.c index 562340d..ca14f1b 100644 --- a/pdlua.c +++ b/pdlua.c @@ -1403,6 +1403,11 @@ static int pdlua_class_new(lua_State *L) pdlua_widgetbehavior.w_visfn = pdlua_vis; pdlua_widgetbehavior.w_activatefn = pdlua_activate; class_setwidget(c_gfx, &pdlua_widgetbehavior); + + // NOTE: It is possible to do this just for the object, not all gui objects + class_setpropertiesfn(c_gfx, pdlua_properties); + class_addmethod(c_gfx, (t_method)pdlua_properties_receiver, gensym("_properties"), A_GIMME, 0); + } lua_pushlightuserdata(L, c); @@ -2802,6 +2807,25 @@ static void pdlua_init(lua_State *L) lua_pushstring(L, "_error"); lua_pushcfunction(L, pdlua_error); lua_settable(L, -3); + + // properties + lua_pushstring(L, "_properties_add"); + lua_pushcfunction(L, pdlua_properties_add); + lua_settable(L, -3); + + lua_pushstring(L, "_properties_newframe"); + lua_pushcfunction(L, pdlua_properties_newframe); + lua_settable(L, -3); + lua_pushstring(L, "_properties_addcheckbox"); + lua_pushcfunction(L, pdlua_properties_addcheckbox); + lua_settable(L, -3); + lua_pushstring(L, "_properties_addtextinput"); + lua_pushcfunction(L, pdlua_properties_addtextinput); + lua_settable(L, -3); + lua_pushstring(L, "_properties_addcolorpicker"); + lua_pushcfunction(L, pdlua_properties_addcolorpicker); + lua_settable(L, -3); + /* 20240906 ag: Added TIMEUNITPERMSEC, systime and timesince, to make clock_set useable. NOTE: TIMEUNITPERMSEC is the time unit for systime, timesince, and clock_set and is from m_sched.c. It isn't in the Pd diff --git a/pdlua.h b/pdlua.h index 0b2f24a..a4263a5 100644 --- a/pdlua.h +++ b/pdlua.h @@ -45,6 +45,17 @@ typedef struct _pdlua_gfx // Variables to keep track of mouse button state and drag position int mouse_drag_x, mouse_drag_y, mouse_down; int first_draw; + + // variables to set properties + t_symbol *current_frame; + t_symbol *properties_receiver; + int frame_count; + int max_col, max_row; + int current_col, current_row; + + int checkbox_count; + int numberbox_count; + int colorpicker_count; #else int current_layer; diff --git a/pdlua/tutorial/examples/properties-help.pd b/pdlua/tutorial/examples/properties-help.pd new file mode 100644 index 0000000..13fa5c7 --- /dev/null +++ b/pdlua/tutorial/examples/properties-help.pd @@ -0,0 +1,5 @@ +#N canvas 963 23 951 1016 10; +#X declare -lib pdlua; +#X obj 5 7 declare -lib pdlua; +#X obj 254 59 tgl 18 0 empty empty empty 0 -9 0 10 #fcfcfc #000000 #000000 0 1; +#X obj 66 69 properties; diff --git a/pdlua/tutorial/examples/properties.pd_lua b/pdlua/tutorial/examples/properties.pd_lua new file mode 100644 index 0000000..4860ad5 --- /dev/null +++ b/pdlua/tutorial/examples/properties.pd_lua @@ -0,0 +1,64 @@ +local properties = pd.Class:new():register("properties") + +function properties:initialize(sel, atoms) + self.inlets = 1 + self.outlets = 1 + self.phase = 0 + self:addproperties() + self:set_size(127, 127) + + self.checkbox1 = 1 + self.checkbox2 = 1 + self.color = {155,155,155} + + self.textinput1 = "Hello" + self.textinput2 = 40 + self.bigstring = "Uidsja hasd asdhj asdy asdhjasd" + + return true +end + +function properties:properties() + self:newframe("First CheckBox", 2) + self:addcheckbox("Check Box 1", "updatecheckbox1", self.checkbox1) + self:addcheckbox("Check Box 2", "updatecheckbox2", self.checkbox2) + + self:newframe("First textinput", 2) + self:addtextinput("Check textinput 1", "updatetext1", self.textinput1, 5) + self:addtextinput("Check textinput 2", "updatetext2", self.textinput2, 5) + + self:newframe("My Color Picker", 1) + self:addcolorpicker("Background", "updatecolorbg"); +end + +function properties:updatecolorbg(args) + self.color[1] = args[1][1] + self.color[2] = args[1][2] + self.color[3] = args[1][3] + self:repaint(1) +end + +function properties:updatetext1(args) + self.textinput1 = args[1] + pd.post("textinput1 is now " .. self.textinput1); +end + +function properties:updatetext2(args) + self.textinput2 = args[1] + pd.post("textinput2 is now " .. self.textinput2); +end + +function properties:updatecheckbox1(args) + self.checkbox1 = args[1] + pd.post("checkbox1 is now " .. self.checkbox1); +end + +function properties:updatecheckbox2(args) + self.checkbox2 = args[1] + pd.post("checkbox2 is now " .. self.checkbox2); +end + +function properties:paint(g) + g:set_color(table.unpack(self.color)) + g:fill_all() +end diff --git a/pdlua_gfx.h b/pdlua_gfx.h index a3f32ab..a7b64a1 100644 --- a/pdlua_gfx.h +++ b/pdlua_gfx.h @@ -1582,3 +1582,467 @@ static int free_path(lua_State* L) freebytes(path->path_segments, path->num_path_segments_allocated * sizeof(int)); return 0; } + +// ╭─────────────────────────────────────╮ +// │ PROPERTIES │ +// ╰─────────────────────────────────────╯ +#ifndef PURR_DATA + +static void pdlua_properties_createdialog(t_pdlua_gfx *o) +{ + pdgui_vmess(0, "ssss", "toplevel", o->properties_receiver->s_name, "-class", "DialogWindow"); + pdgui_vmess(0, "ssss", "wm", "title", o->properties_receiver->s_name, "{[mydialog] Properties}"); + pdgui_vmess(0, "sss", "wm", "group", o->properties_receiver->s_name, "."); + pdgui_vmess(0, "sssii", "wm", "resizable", o->properties_receiver->s_name, 0, 0); + + pdgui_vmess(0, "sss", "wm", "transient", o->properties_receiver->s_name, "$::focused_window"); + pdgui_vmess(0, "ssss", o->properties_receiver->s_name, "configure", "-menu", "$::dialog_menubar"); + pdgui_vmess(0, "sssfsf", o->properties_receiver->s_name, "configure", "-padx", 0.0f, "-pady", 0.0f); +} + +static void pdlua_properties_updaterow(t_pdlua_gfx *o) +{ + o->current_col++; + if (o->current_col == o->max_col) { + o->current_row++; + o->current_col = 0; // not used for now + } +} + +static void pdlua_properties_setupbuttons(t_pdlua_gfx *o) { + char buttonsId[MAXPDSTRING]; + snprintf(buttonsId, MAXPDSTRING, ".%p.buttons", (void *)o); + + char buttonCancelId[MAXPDSTRING]; + char buttonApplyId[MAXPDSTRING]; + char buttonOkId[MAXPDSTRING]; + snprintf(buttonCancelId, MAXPDSTRING, ".%p.buttons.cancel", (void *)o); + snprintf(buttonApplyId, MAXPDSTRING, ".%p.buttons.apply", (void *)o); + snprintf(buttonOkId, MAXPDSTRING, ".%p.buttons.ok", (void *)o); + + char destroyCommand[MAXPDSTRING]; + snprintf(destroyCommand, MAXPDSTRING, "destroy .%p", (void *)o); + + // Criando o frame dos botões + pdgui_vmess(0, "sssf", "frame", buttonsId, "-pady", 5.0f); + pdgui_vmess(0, "ssss", "pack", buttonsId, "-fill", "x"); + + + // Cancel (Close window) + pdgui_vmess(0, "ssssss", "button", buttonCancelId, "-text", "Cancel", "-command", + destroyCommand); + pdgui_vmess(0, "sssssisisi", "pack", buttonCancelId, "-side", "left", "-expand", 1, "-padx", 10, + "-ipadx", 10); + + // Apply (send all data to pd and lua obj) for this must be necessary to save all the variables used in the object in a char [128][MAXPDSTRING], + // I don't think that this is good, or there is better solution? + // TODO: Need to dev the apply command + pdgui_vmess(0, "ssss", "button", buttonApplyId, "-text", "Apply"); + // pdgui_vmess(0, "ssssss", "button", buttonApplyId, "-text", "Apply", "-command", command); + pdgui_vmess(0, "sssssisisi", "pack", buttonApplyId, "-side", "left", "-expand", 1, "-padx", 10, + "-ipadx", 10); + + // Ok + pdgui_vmess(0, "ssssss", "button", buttonOkId, "-text", "OK", "-command", destroyCommand); + pdgui_vmess(0, "sssssisisi", "pack", buttonOkId, "-side", "left", "-expand", 1, "-padx", 10, + "-ipadx", 10); +} + +static int pdlua_properties_newframe(lua_State *L) +{ + + t_pdlua *pdlua; + const char *s; + + if (lua_islightuserdata(L, 1) && lua_isstring(L, 2) && lua_isnumber(L, 3)) + { + pdlua = lua_touserdata(L, 1); + const char *title = lua_tostring(L, 2); + int col = lua_tonumber(L, 3); + t_pdlua_gfx *o = &pdlua->gfx; + if (o) + { + o->frame_count++; + char current_frameid[MAXPDSTRING]; + snprintf(current_frameid, MAXPDSTRING, ".%p.main.frame%d", (void *)o, o->frame_count); + o->current_frame = gensym(current_frameid); + + // raised, sunken, flat, ridge, solid, and groove. + // Create main frame for set of configurations + pdgui_vmess(0, "sssssi", "frame", current_frameid, "-relief", "groove", "-borderwidth", 1); + pdgui_vmess(0, "sssssssisi", "pack", current_frameid, "-side", "top", "-fill", "x", "-padx", 10, + "-pady", 10); + + // Title of the Frame + char labelid[MAXPDSTRING]; + snprintf(labelid, MAXPDSTRING, "%s.title", current_frameid); + pdgui_vmess(0, "ssss", "label", labelid, "-text", title); + pdgui_vmess(0, "sssssf", "pack", labelid, "-side", "top", "-pady", 5.f); + + // Create content frame with grid layout + char content_frameid[MAXPDSTRING]; + snprintf(content_frameid, MAXPDSTRING, "%s.content", current_frameid); + pdgui_vmess(0, "ss", "frame", content_frameid); + pdgui_vmess(0, "ssss", "pack", content_frameid, "-side", "top", "-fill", "x"); + + // Configure grid with 2 equal columns + for (int i = 0; i < col; i++) { + pdgui_vmess(0, "sssisi", "grid", "columnconfigure", content_frameid, i, "-weight", 1); + } + o->current_frame = gensym(content_frameid); + o->max_col = col; + o->current_col = 0; + o->current_row = 0; + } else{ + mylua_error(__L(), pdlua, "properties"); + } + } else{ + mylua_error(__L(), pdlua, "properties"); + + } + return 0; +} + +static int pdlua_properties_addcheckbox(lua_State *L) +{ + t_pdlua *pdlua; + const char *s; + + if (lua_islightuserdata(L, 1) && lua_isstring(L, 2) && lua_isstring(L, 3) && lua_isnumber(L, 4)) + { + pdlua = lua_touserdata(L, 1); + const char *text = lua_tostring(L, 2); + const char *method = lua_tostring(L, 3); + int init_value = lua_tonumber(L, 4); + if (pdlua == NULL){ + return 0 ; + } + + t_pdlua_gfx *o = &pdlua->gfx; + if (o) + { + char pdsend[MAXPDSTRING]; + char checkid[MAXPDSTRING]; + char checkvariable[MAXPDSTRING]; + char sanitized_frame[MAXPDSTRING]; + o->checkbox_count++; + + // Sanitize frame name (replace '.' with '_') + snprintf(sanitized_frame, MAXPDSTRING, "%s", o->current_frame->s_name); + for (char *p = sanitized_frame; *p != '\0'; p++) { + if (*p == '.') { + *p = '_'; + } + } + + // Generate unique variable name + snprintf(checkvariable, MAXPDSTRING, "::checkbox%d_%s_state", o->checkbox_count, + sanitized_frame); + + // Initialize the Tcl variable to 0 (unchecked) + pdgui_vmess(0, "ssi", "set", checkvariable, init_value); + + // Build the pdsend command + snprintf(pdsend, MAXPDSTRING, "eval pdsend [concat %s _properties checkbox %s $%s]", + o->properties_receiver->s_name, method, checkvariable); + + // Create the checkbox + snprintf(checkid, MAXPDSTRING, "%s.check%d", o->current_frame->s_name, o->checkbox_count); + pdgui_vmess(0, "ssssssss", "checkbutton", checkid, "-text", text, "-variable", checkvariable, + "-command", pdsend); + + pdgui_vmess(0, "sssisi", "grid", checkid, "-row", o->current_row, "-column", o->current_col, + "-sticky", "we"); + pdlua_properties_updaterow(o); + } else { + mylua_error(__L(), pdlua, "addcheckbox"); + } + } else { + mylua_error(__L(), pdlua, "addcheckbox"); + } + return 0; +} + + +static int pdlua_properties_addtextinput(lua_State *L) +{ + t_pdlua *pdlua; + const char *s; + + if (lua_islightuserdata(L, 1) && lua_isstring(L, 2) && lua_isstring(L, 3) && lua_isstring(L, 4) && lua_isnumber(L, 5)) + { + pdlua = lua_touserdata(L, 1); + const char *text = lua_tostring(L, 2); + const char *method = lua_tostring(L, 3); + const char *init_value = lua_tostring(L, 4); + int width = lua_tonumber(L, 5); + if (pdlua == NULL){ + mylua_error(__L(), pdlua, "pdlua is NULL"); + return 0 ; + } + + t_pdlua_gfx *o = &pdlua->gfx; + if (o) + { + char pdsend[MAXPDSTRING]; + char textid[MAXPDSTRING]; + char buttonid[MAXPDSTRING]; + char entryid[MAXPDSTRING]; + + char numvariable[MAXPDSTRING]; + + char sanitized_frame[MAXPDSTRING]; + o->numberbox_count++; + + // Sanitize frame name (replace '.' with '_') + snprintf(sanitized_frame, MAXPDSTRING, "%s", o->current_frame->s_name); + for (char *p = sanitized_frame; *p != '\0'; p++) { + if (*p == '.') { + *p = '_'; + } + } + + // Variable save the value of gui obj + snprintf(numvariable, MAXPDSTRING, "::numberbox%d_%s_value", o->numberbox_count, + sanitized_frame); + pdgui_vmess(0, "sss", "set", numvariable, init_value); + + // Command to send it to pd + snprintf(pdsend, MAXPDSTRING, "eval pdsend [concat %s _properties numberbox %s $%s]", + o->properties_receiver->s_name, method, numvariable); + + // container for button to set and text input + char text_button_frame[MAXPDSTRING]; + snprintf(text_button_frame, MAXPDSTRING, "%s.text_button_frame_%d", o->current_frame->s_name, + o->numberbox_count); + pdgui_vmess(0, "sssssisisi", "frame", text_button_frame, "-relief", "solid", "-borderwidth", 1, + "-padx", 5, "-pady", 5); + + // create text for identification + snprintf(textid, MAXPDSTRING, "%s.text%d", text_button_frame, o->numberbox_count); + pdgui_vmess(0, "ssss", "label", textid, "-text", text); + + // Create the number entry box + snprintf(entryid, MAXPDSTRING, "%s.numberbox%d", text_button_frame, o->numberbox_count); + pdgui_vmess(0, "sssssi", "entry", entryid, "-textvariable", numvariable, "-width", width); + + // Create the set button + snprintf(buttonid, MAXPDSTRING, "%s.setbutton%d", text_button_frame, o->numberbox_count); + pdgui_vmess(0, "sssssssisi", "button", buttonid, "-text", "Set", "-command", pdsend, "-padx", + 10, "-pady", 0); + + // Pack the entry and button side by side + pdgui_vmess(0, "ssss", "pack", textid, "-side", "top"); + pdgui_vmess(0, "ssss", "pack", entryid, "-side", "left"); + pdgui_vmess(0, "ssss", "pack", buttonid, "-side", "right"); + pdgui_vmess(0, "sssisisssi", "grid", text_button_frame, "-row", o->current_row, "-column", + o->current_col, "-sticky", "we", "-padx", 20, "-pady", 20); + pdlua_properties_updaterow(o); + } else{ + mylua_error(__L(), pdlua, "pdlua_gfx is NULL"); + } + } else { + mylua_error(__L(), pdlua, "Types checks failed"); + } + return 0; +} + +// static int pdlua_dialog_createcolorpicker(t_pdlua *x, const char *text, const char *method) { +static int pdlua_properties_addcolorpicker(lua_State *L) { + t_pdlua *pdlua; + const char *s; + + if (lua_islightuserdata(L, 1) && lua_isstring(L, 2) && lua_isstring(L, 3)) + { + pdlua = lua_touserdata(L, 1); + const char *text = lua_tostring(L, 2); + const char *method = lua_tostring(L, 3); + // const char *init_value = lua_tostring(L, 4); // TODO: set color here with table maybe? + if (pdlua == NULL){ + return 0 ; + } + + t_pdlua_gfx *o = &pdlua->gfx; + if (o) + { + + char pdsend[MAXPDSTRING]; + char buttonid[MAXPDSTRING]; + char colorvariable[MAXPDSTRING]; + char sanitized_frame[MAXPDSTRING]; + o->colorpicker_count++; + + // Sanitize frame name (replace '.' with '_') + snprintf(sanitized_frame, MAXPDSTRING, "%s", o->current_frame->s_name); + for (char *p = sanitized_frame; *p != '\0'; p++) { + if (*p == '.') { + *p = '_'; + } + } + + // Generate unique variable name + snprintf(colorvariable, MAXPDSTRING, "::colorpicker%d_%s_value", o->colorpicker_count, + sanitized_frame); + + // Initialize the Tcl variable to a default color + pdgui_vmess(0, "sss", "set", colorvariable, "#ffffff"); + + // Build the pdsend command to trigger color picker and send result + snprintf(pdsend, MAXPDSTRING, + "eval pdsend [concat %s _properties colorpicker %s [tk_chooseColor -initialcolor {#ffffff} -title {Choose color}]]", + o->properties_receiver->s_name, method); + + // Create the color picker button with the constructed command + snprintf(buttonid, MAXPDSTRING, "%s.colorpicker%d", o->current_frame->s_name, + o->colorpicker_count); + pdgui_vmess(0, "ssssss", "button", buttonid, "-text", text, "-command", pdsend); + + pdgui_vmess(0, "sssisi", "grid", buttonid, "-row", o->current_row, "-column", o->current_col, + "-sticky", "we"); + pdlua_properties_updaterow(o); + + } else { + mylua_error(__L(), pdlua, "addcolorpicker"); + } + } else { + mylua_error(__L(), pdlua, "addcolorpicker"); + } +} + + +static void pdlua_properties(t_gobj *z, t_glist *owner) { + t_pdlua *pdlua = (t_pdlua *)z; + t_pdlua_gfx *o = &pdlua->gfx; + + char receiver[MAXPDSTRING]; + snprintf(receiver, MAXPDSTRING, ".%p", o); + o->properties_receiver = gensym(receiver); + o->current_frame = NULL; + pd_bind(&pdlua->pd.ob_pd, o->properties_receiver); // new to unbind + + pdlua_properties_createdialog(o); // <-- create hidden window + + // main window + char frameId[MAXPDSTRING]; + snprintf(frameId, MAXPDSTRING, ".%p.main", (void *)o); + pdgui_vmess(0, "sss", "wm", "deiconify", o->properties_receiver->s_name); // <- on sucess show the window + pdgui_vmess(0, "sssf", "frame", frameId, "-padx", 15.0f, "-pady", 15.0f); + pdgui_vmess(0, "sssssf", "pack", frameId, "-fill", "both", "-expand", 4.0f); + pdgui_vmess(0, "sssfsf", "pack", frameId, "-pady", 10.f, "-padx", 10.f); + + // call _properties + lua_getglobal(__L(), "pd"); + lua_getfield (__L(), -1, "_properties"); + lua_pushlightuserdata(__L(), pdlua); + if (lua_pcall(__L(), 1, 1, 0)) + { + mylua_error(__L(), pdlua, "properties"); + pdgui_vmess(0, "ss", "destroy", o->properties_receiver->s_name); + return; + } + + // Get the return value (Lua pushes it onto the stack) + int result = lua_toboolean(__L(), -1); // Converts Lua boolean to C int (1 = true, 0 = false) + lua_pop(__L(), 1); // Remove the result from the stack + if (!result) + { + pdgui_vmess(0, "ss", "destroy", o->properties_receiver->s_name); + return; + } + pdlua_properties_setupbuttons(o); // <- this is independed of all previous containers + +} + +#include + +static void pdlua_properties_receiver(t_pdlua *o, t_symbol *s, int argc, t_atom *argv) +{ + if (argc < 2) + return; + + lua_getglobal(__L(), "pd"); + lua_getfield(__L(), -1, "_set_properties"); + lua_remove(__L(), -2); + + lua_pushlightuserdata(__L(), o); + lua_pushstring(__L(), atom_getsymbol(argv + 1)->s_name); + lua_newtable(__L()); // Criando a tabela + + const char *guitype = atom_getsymbol(argv)->s_name; + if (strcmp(guitype, "colorpicker") == 0) + { + const char *hexcolor = atom_getsymbol(argv + 2)->s_name; + int isvalid = 1; + + if (hexcolor == NULL || hexcolor[0] != '#' || strlen(hexcolor) != 7) { + isvalid = 0; + } else { + for (int i = 1; i < 7; i++) { + if (!isxdigit(hexcolor[i])) isvalid = 0; + } + } + + if (!isvalid) { + pd_error(o, "Invalid color string"); + return; + } + + int r, g, b; + if (sscanf(hexcolor + 1, "%2x%2x%2x", &r, &g, &b) == 3) { + lua_newtable(__L()); + lua_pushinteger(__L(), r); + lua_rawseti(__L(), -2, 1); + lua_pushinteger(__L(), g); + lua_rawseti(__L(), -2, 2); + lua_pushinteger(__L(), b); + lua_rawseti(__L(), -2, 3); + lua_rawseti(__L(), -2, 1); + } else { + pd_error(o, "Invalid color format in sscanf"); + return; + } + } else{ + for (int i = 2; i < argc; i++) + { + if (argv[i].a_type == A_FLOAT) + { + lua_pushnumber(__L(), atom_getfloat(argv + i)); + lua_rawseti(__L(), -2, i - 1); // Store at index (1-based in Lua) + } + else if (argv[i].a_type == A_SYMBOL) + { + lua_pushstring(__L(), atom_getsymbol(argv + i)->s_name); + lua_rawseti(__L(), -2, i - 1); + } + } + } + + if (lua_pcall(__L(), 3, 0, 0)) + { + mylua_error(__L(), o, "_set_properties"); // Handle error + lua_pop(__L(), 1); // Pop error message + return; + } +} + +static int pdlua_properties_add(lua_State *L) +{ + t_pdlua *lua_class; + const char *s; + if (lua_islightuserdata(L, 1)) + { + lua_class = lua_touserdata(L, 1); + if (lua_class) + { + // NOTE: Something like this would be nice + // class_setpropertiesfn((t_class *)lua_class->pd.te_g.g_pd, pdlua_properties); + // return 1; + } + } + return 0; +} + + +#endif + +