/** \file * \brief plot binding for Lua 5. * * See Copyright Notice in "iup.h" */ #include #include #include #include #include "iup.h" #include "iup_plot.h" #include #include #include "iuplua.h" #include "iuplua_plot.h" #include "il.h" #include "iup_object.h" #include "iup_assert.h" #include "iup_predialogs.h" #include "iup_str.h" typedef int(*IFnL)(Ihandle*, lua_State *L); static void ShowFormulaError(Ihandle* ih, lua_State *L) { const char* str_message = IupGetLanguageString("IUP_ERRORINVALIDFORMULA"); const char* error = lua_tostring(L, -1); char msg[1024]; sprintf(msg, "%s\n Lua error: %s", str_message, error); IupMessageError(IupGetDialog(ih), msg); } int IupPlotSetFormula(Ihandle* ih, int sample_count, const char* formula, const char* init) { lua_State *L; int i, ds_index, ret_count = 1; double min, max, step, p, x, y; char formula_func[1024]; IFnL init_cb; iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return -1; /* must be an IupMatrix */ if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "plot")) return -1; L = luaL_newstate(); luaL_openlibs(L); { const char* register_global = "function openpackage(ns)\n" " for n, v in pairs(ns) do _G[n] = v end\n" "end\n" "openpackage(math)\n"; luaL_dostring(L, register_global); } if (init) luaL_dostring(L, init); init_cb = (IFnL)IupGetCallback(ih, "FORMULAINIT_CB"); if (init_cb) init_cb(ih, L); lua_pushlightuserdata(L, ih); lua_setglobal(L, "plot"); if (IupGetInt(ih, "FORMULA_PARAMETRIC")) ret_count = 2; sprintf(formula_func, "function plot_formula(sample_index, %s)\n" " return %s\n" "end\n", ret_count == 2 ? "t" : "x", formula); if (luaL_dostring(L, formula_func) != 0) { ShowFormulaError(ih, L); lua_close(L); return -1; } min = IupGetDouble(ih, "FORMULA_MIN"); max = IupGetDouble(ih, "FORMULA_MAX"); step = (max - min) / (double)(sample_count - 1); IupPlotBegin(ih, 0); for (i = 0, p = min; i < sample_count; i++, p += step) { lua_getglobal(L, "plot_formula"); lua_pushinteger(L, i); lua_pushnumber(L, p); if (lua_pcall(L, 2, ret_count, 0) != 0) { ShowFormulaError(ih, L); lua_close(L); return -1; } if (!lua_isnumber(L, -1)) { const char* str_message = IupGetLanguageString("IUP_ERRORINVALIDFORMULA"); IupMessageError(IupGetDialog(ih), str_message); lua_close(L); return -1; } if (ret_count == 2) { if (!lua_isnumber(L, -2)) { const char* str_message = IupGetLanguageString("IUP_ERRORINVALIDFORMULA"); IupMessageError(IupGetDialog(ih), str_message); lua_close(L); return -1; } x = lua_tonumber(L, -2); y = lua_tonumber(L, -1); lua_pop(L, 2); /* remove the result from the stack */ } else { x = p; y = lua_tonumber(L, -1); lua_pop(L, 1); /* remove the result from the stack */ } IupPlotAdd(ih, x, y); } ds_index = IupPlotEnd(ih); lua_close(L); return ds_index; } static int plot_postdraw_cb(Ihandle *self, cdCanvas* cnv) { lua_State *L = iuplua_call_start(self, "postdraw_cb"); cdlua_pushcanvas(L, cnv); return iuplua_call(L, 1); } static int plot_predraw_cb(Ihandle *self, cdCanvas* cnv) { lua_State *L = iuplua_call_start(self, "predraw_cb"); cdlua_pushcanvas(L, cnv); return iuplua_call(L, 1); } static int plot_ytickformatnumber_cb(Ihandle *self, char * p0, char * p1, double p2, char * p3) { int status; lua_State *L = iuplua_call_start(self, "ytickformatnumber_cb"); lua_pushstring(L, p1); lua_pushnumber(L, p2); lua_pushstring(L, p3); status = iuplua_call_raw(L, 3, 2); if (status != LUA_OK) return IUP_DEFAULT; else { char* tmp_s = lua_isnil(L, -2) ? NULL : (char*)lua_tostring(L, -2); int tmp_i = (int)lua_isnil(L, -1) ? IUP_DEFAULT : (int)lua_tointeger(L, -1); lua_pop(L, 2); /* remove the results */ if (tmp_i == IUP_DEFAULT && tmp_s) iupStrCopyN(p0, 128, tmp_s); return tmp_i; } } static int plot_xtickformatnumber_cb(Ihandle *self, char * p0, char * p1, double p2, char * p3) { int status; lua_State *L = iuplua_call_start(self, "xtickformatnumber_cb"); lua_pushstring(L, p1); lua_pushnumber(L, p2); lua_pushstring(L, p3); status = iuplua_call_raw(L, 3, 2); if (status != LUA_OK) return IUP_DEFAULT; else { char* tmp_s = lua_isnil(L, -2) ? NULL : (char*)lua_tostring(L, -2); int tmp_i = (int)lua_isnil(L, -1) ? IUP_DEFAULT : (int)lua_tointeger(L, -1); lua_pop(L, 2); /* remove the results */ if (tmp_i == IUP_DEFAULT && tmp_s) iupStrCopyN(p0, 128, tmp_s); return tmp_i; } } static int PlotBegin(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); IupPlotBegin(ih, luaL_checkinteger(L,2)); return 0; } static int PlotAdd(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); IupPlotAdd(ih, luaL_checknumber(L,2), luaL_checknumber(L,3)); return 0; } static int PlotAddStr(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); IupPlotAddStr(ih, luaL_checkstring(L,2), luaL_checknumber(L,3)); return 0; } static int PlotAddSegment(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotAddSegment(ih, luaL_checknumber(L, 2), luaL_checknumber(L, 3)); return 0; } static int PlotEnd(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); int ret = IupPlotEnd(ih); lua_pushinteger(L, ret); return 1; } static int PlotLoadData(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); int ret = IupPlotLoadData(ih, luaL_checkstring(L, 2), luaL_checkinteger(L, 3)); lua_pushinteger(L, ret); return 1; } static int PlotSetFormula(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); int ret = IupPlotSetFormula(ih, luaL_checkinteger(L, 2), luaL_checkstring(L, 3), luaL_optstring(L, 4, NULL)); lua_pushinteger(L, ret); return 1; } static int PlotFindSample(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); int ds_index, sample_index; int ret = IupPlotFindSample(ih, luaL_checknumber(L, 2), luaL_checknumber(L, 3), &ds_index, &sample_index); lua_pushinteger(L, ret); if (ret) { lua_pushinteger(L, ds_index); lua_pushinteger(L, sample_index); return 3; } else return 1; } static int PlotFindSegment(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); int ds_index, sample_index1, sample_index2; int ret = IupPlotFindSegment(ih, luaL_checknumber(L, 2), luaL_checknumber(L, 3), &ds_index, &sample_index1, &sample_index2); lua_pushinteger(L, ret); if (ret) { lua_pushinteger(L, ds_index); lua_pushinteger(L, sample_index1); lua_pushinteger(L, sample_index2); return 4; } else return 1; } static int PlotInsert(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotInsert(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checknumber(L, 4), luaL_checknumber(L, 5)); return 0; } static int PlotInsertStr(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); IupPlotInsertStr(ih, luaL_checkinteger(L,2), luaL_checkinteger(L,3), luaL_checkstring(L,4), luaL_checknumber(L,5)); return 0; } static int PlotInsertSegment(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotInsertSegment(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checknumber(L, 4), luaL_checknumber(L, 5)); return 0; } static int PlotInsertSamples(lua_State *L) { double *px, *py; int count = luaL_checkinteger(L, 6); px = iuplua_checkdouble_array(L, 4, count); py = iuplua_checkdouble_array(L, 5, count); IupPlotInsertSamples(iuplua_checkihandle(L,1), luaL_checkinteger(L,2), luaL_checkinteger(L,3), px, py, count); free(px); free(py); return 0; } static int PlotInsertStrSamples(lua_State *L) { double *py; char* *px; int count = luaL_checkinteger(L, 6); px = iuplua_checkstring_array(L, 4, count); py = iuplua_checkdouble_array(L, 5, count); IupPlotInsertStrSamples(iuplua_checkihandle(L,1), luaL_checkinteger(L,2), luaL_checkinteger(L,3), px, py, count); free(px); free(py); return 0; } static int PlotAddSamples(lua_State *L) { double *px, *py; int count = luaL_checkinteger(L, 5); px = iuplua_checkdouble_array(L, 3, count); py = iuplua_checkdouble_array(L, 4, count); IupPlotAddSamples(iuplua_checkihandle(L,1), luaL_checkinteger(L,2), px, py, count); free(px); free(py); return 0; } static int PlotAddStrSamples(lua_State *L) { double *py; char* *px; int count = luaL_checkinteger(L, 5); px = iuplua_checkstring_array(L, 3, count); py = iuplua_checkdouble_array(L, 4, count); IupPlotAddStrSamples(iuplua_checkihandle(L,1), luaL_checkinteger(L,2), px, py, count); free(px); free(py); return 0; } static int PlotGetSample(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); double x, y; IupPlotGetSample(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), &x, &y); lua_pushnumber(L, x); lua_pushnumber(L, y); return 2; } static int PlotGetSampleStr(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); double y; const char* x; IupPlotGetSampleStr(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), &x, &y); lua_pushstring(L, x); lua_pushnumber(L, y); return 2; } static int PlotGetSampleSelection(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); int selected = IupPlotGetSampleSelection(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3)); lua_pushboolean(L, selected); return 1; } static int PlotGetSampleExtra(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); double extra = IupPlotGetSampleExtra(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3)); lua_pushnumber(L, extra); return 1; } static int PlotSetSample(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotSetSample(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checknumber(L, 4), luaL_checknumber(L, 5)); return 0; } static int PlotSetSampleStr(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotSetSampleStr(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checkstring(L, 4), luaL_checknumber(L, 5)); return 0; } static int PlotSetSampleSelection(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotSetSampleSelection(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checkinteger(L, 4)); return 0; } static int PlotSetSampleExtra(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L, 1); IupPlotSetSampleExtra(ih, luaL_checkinteger(L, 2), luaL_checkinteger(L, 3), luaL_checknumber(L, 4)); return 0; } static int PlotTransform(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); double ix, iy; IupPlotTransform(ih, luaL_checknumber(L,2), luaL_checknumber(L,3), &ix, &iy); lua_pushnumber(L, ix); lua_pushnumber(L, iy); return 2; } static int PlotTransformTo(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); double rx, ry; IupPlotTransformTo(ih, (int)luaL_checkinteger(L, 2), (int)luaL_checkinteger(L, 3), &rx, &ry); lua_pushnumber(L, rx); lua_pushnumber(L, ry); return 2; } static int PlotPaintTo(lua_State *L) { Ihandle *ih = iuplua_checkihandle(L,1); IupPlotPaintTo(ih, cdlua_checkcanvas(L,2)); return 0; } void iuplua_plotfuncs_open (lua_State *L) { iuplua_register_cb(L, "PREDRAW_CB", (lua_CFunction)plot_predraw_cb, NULL); iuplua_register_cb(L, "POSTDRAW_CB", (lua_CFunction)plot_postdraw_cb, NULL); iuplua_register_cb(L, "XTICKFORMATNUMBER_CB", (lua_CFunction)plot_xtickformatnumber_cb, NULL); iuplua_register_cb(L, "YTICKFORMATNUMBER_CB", (lua_CFunction)plot_ytickformatnumber_cb, NULL); iuplua_register(L, PlotBegin ,"PlotBegin"); iuplua_register(L, PlotAdd ,"PlotAdd"); iuplua_register(L, PlotAddStr ,"PlotAddStr"); iuplua_register(L, PlotAddSegment ,"PlotAddSegment"); iuplua_register(L, PlotEnd ,"PlotEnd"); iuplua_register(L, PlotLoadData ,"PlotLoadData"); iuplua_register(L, PlotSetFormula ,"PlotSetFormula"); iuplua_register(L, PlotFindSample ,"PlotFindSample"); iuplua_register(L, PlotFindSegment, "PlotFindSegment"); iuplua_register(L, PlotInsert, "PlotInsert"); iuplua_register(L, PlotInsertStr ,"PlotInsertStr"); iuplua_register(L, PlotInsertSegment, "PlotInsertSegment"); iuplua_register(L, PlotInsertSamples ,"PlotInsertSamples"); iuplua_register(L, PlotInsertStrSamples ,"PlotInsertStrSamples"); iuplua_register(L, PlotAddSamples ,"PlotAddSamples"); iuplua_register(L, PlotAddStrSamples ,"PlotAddStrSamples"); iuplua_register(L, PlotGetSample, "PlotGetSample"); iuplua_register(L, PlotGetSampleStr, "PlotGetSampleStr"); iuplua_register(L, PlotGetSampleSelection, "PlotGetSampleSelection"); iuplua_register(L, PlotGetSampleExtra, "PlotGetSampleExtra"); iuplua_register(L, PlotSetSample, "PlotSetSample"); iuplua_register(L, PlotSetSampleStr, "PlotSetSampleStr"); iuplua_register(L, PlotSetSampleSelection, "PlotSetSampleSelection"); iuplua_register(L, PlotSetSampleExtra, "PlotSetSampleExtra"); iuplua_register(L, PlotTransform, "PlotTransform"); iuplua_register(L, PlotTransformTo, "PlotTransformTo"); iuplua_register(L, PlotPaintTo, "PlotPaintTo"); } int iupplotlua_open(lua_State * L); int iup_plotlua_open(lua_State * L) { if (iuplua_opencall_internal(L)) IupPlotOpen(); iuplua_get_env(L); iupplotlua_open(L); return 0; } /* obligatory to use require"iuplua_plot" */ int luaopen_iuplua_plot(lua_State* L) { return iup_plotlua_open(L); }