iup-stack/iup/srclua5/ctrl/iuplua_plot.c

513 lines
13 KiB
C
Executable File

/** \file
* \brief plot binding for Lua 5.
*
* See Copyright Notice in "iup.h"
*/
#include <stdlib.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "iup.h"
#include "iup_plot.h"
#include <cd.h>
#include <cdlua.h>
#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);
}