/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * luawidget.cc * * Tue Aug 3 10:17:02 CEST 2010 * Copyright 2010 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Pracro. * * Pracro is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Pracro is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pracro; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "luawidget.h" #include "widgets.h" #include "debug.h" #define LUA_SRC "lua" /** ** Copied from lauxlib.c, but modified return NULL upon error instead of ** casting a lua error. **/ static void *luaL_isudata (lua_State *L, int ud, const char *tname) { void *p = lua_touserdata(L, ud); if (p != NULL) { /* value is a userdata? */ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ lua_pop(L, 2); /* remove both metatables */ return p; } } } // luaL_typerror(L, ud, tname); /* else error */ return NULL; /* to avoid warnings */ } #define luaL_checkbool(L, i) \ (lua_isboolean(L,i) ? lua_toboolean(L,i) : luaL_checkint(L,i)) typedef struct wdg_userdata { Widget *widget; } wdg_userdata; static int wdg_name(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushstring(L, wdgu->widget->name().toStdString().c_str()); return 1; } static int wdg_type(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); // return error code lua_pushstring(L, wdgu->widget->type().toStdString().c_str()); return 1; } static int wdg_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushstring(L, wdgu->widget->value().toStdString().c_str()); return 1; } static int wdg_set_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); const char *val = luaL_checkstring(L, 2); wdgu->widget->setValue(val, LUA_SRC); return 0; } static int wdg_enabled(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->enabled()); return 1; } static int wdg_set_enabled(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setEnabled(val); return 0; } static int wdg_visible(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->visible()); return 1; } static int wdg_set_visible(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setVisible(val); return 0; } static int wdg_valid(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->valid()); return 1; } static int wdg_set_valid(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setValid(val); return 0; } #define WDG_METHS \ {"name", wdg_name},\ {"type", wdg_type},\ {"value", wdg_value},\ {"setValue", wdg_set_value},\ {"enabled", wdg_enabled},\ {"setEnabled", wdg_set_enabled},\ {"visible", wdg_visible},\ {"setVisible", wdg_set_visible},\ {"valid", wdg_valid},\ {"setValid", wdg_set_valid} static int chk_checked(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); luaL_argcheck(L, wdgu, 1, "checkbox expected"); CheckBox *chk = (CheckBox*)wdgu->widget; lua_pushboolean(L, chk->checked()); return 1; } static int chk_set_checked(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); luaL_argcheck(L, wdgu, 1, "checkbox expected"); bool val = luaL_checkbool(L, 2); CheckBox *chk = (CheckBox*)wdgu->widget; chk->setChecked(val); return 0; } #define CHKBOX_METHS \ {"checked", chk_checked},\ {"setChecked", chk_set_checked} static int cmb_clear(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); luaL_argcheck(L, wdgu, 1, "combobox expected"); ComboBox *cmb = (ComboBox*)wdgu->widget; cmb->clear(); return 0; } static int cmb_add_item(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); luaL_argcheck(L, wdgu, 1, "combobox expected"); QString val = luaL_checkstring(L, 2); ComboBox *cmb = (ComboBox*)wdgu->widget; cmb->addItem(val); return 0; } static int cmb_le_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); luaL_argcheck(L, wdgu, 1, "combobox expected"); ComboBox *cmb = (ComboBox*)wdgu->widget; lua_pushstring(L, cmb->lineEditValue().toStdString().c_str()); return 1; } static int cmb_le_set_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); luaL_argcheck(L, wdgu, 1, "combobox expected"); const char *val = luaL_checkstring(L, 2); ComboBox *cmb = (ComboBox*)wdgu->widget; cmb->setLineEditValue(val); return 0; } #define CMBBOX_METHS \ {"clear", cmb_clear},\ {"addItem", cmb_add_item},\ {"lineEditValue", cmb_le_value},\ {"setLineEditValue", cmb_le_set_value} static int lin_clear_suggestions(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "lineedit expected"); LineEdit *led = (LineEdit*)wdgu->widget; led->clearSuggestions(); return 0; } static int lin_show_suggestions(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "lineedit expected"); LineEdit *led = (LineEdit*)wdgu->widget; led->showSuggestions(); return 0; } static int lin_is_suggested(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "lineedit expected"); const char *val = luaL_checkstring(L, 2); LineEdit *led = (LineEdit*)wdgu->widget; lua_pushboolean(L, led->isSuggested(val)); return 1; } static int lin_add_suggestion(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "lineedit expected"); const char *val = luaL_checkstring(L, 2); LineEdit *led = (LineEdit*)wdgu->widget; led->addSuggestion(val); return 0; } #define LINEDT_METHS \ {"clearSuggestions", lin_clear_suggestions},\ {"showSuggestions", lin_show_suggestions},\ {"isSuggested", lin_is_suggested},\ {"addSuggestion", lin_add_suggestion} static const struct luaL_Reg wdg_meths[] = { WDG_METHS, {NULL, NULL} }; static const struct luaL_Reg chkbox_meths[] = { WDG_METHS, CHKBOX_METHS, {NULL, NULL} }; static const struct luaL_Reg cmbbox_meths[] = { WDG_METHS, CMBBOX_METHS, {NULL, NULL} }; static const struct luaL_Reg linedt_meths[] = { WDG_METHS, LINEDT_METHS, {NULL, NULL} }; int wdg_make_widget(lua_State *L, Widget *widget) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)lua_newuserdata(L, sizeof(wdg_userdata)); if(widget->type() == "combobox") luaL_getmetatable(L, "ComboBox"); else if(widget->type() == "checkbox") luaL_getmetatable(L, "CheckBox"); else if(widget->type() == "lineedit") luaL_getmetatable(L, "LineEdit"); else luaL_getmetatable(L, "Widget"); lua_setmetatable(L, -2); wdgu->widget = widget; return 1; } void register_widget(lua_State *L) { luaL_newmetatable(L, "Widget"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_register(L, NULL, wdg_meths); // lua_pop(L, 2); luaL_newmetatable(L, "CheckBox"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_register(L, NULL, chkbox_meths); // lua_pop(L, 2); luaL_newmetatable(L, "ComboBox"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_register(L, NULL, cmbbox_meths); // lua_pop(L, 2); luaL_newmetatable(L, "LineEdit"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_register(L, NULL, linedt_meths); // lua_pop(L, 2); }