forked from mia/Aegisub
Ruby: configuration dialogs
Originally committed to SVN as r922.
This commit is contained in:
parent
2f52b36910
commit
505e09257e
3 changed files with 244 additions and 256 deletions
|
@ -55,7 +55,7 @@ namespace Automation4 {
|
||||||
RubyObjects *RubyObjects::inst = NULL;
|
RubyObjects *RubyObjects::inst = NULL;
|
||||||
RubyScript * RubyScript::inst = NULL; // current Ruby Script
|
RubyScript * RubyScript::inst = NULL; // current Ruby Script
|
||||||
RubyProgressSink* RubyProgressSink::inst = NULL;
|
RubyProgressSink* RubyProgressSink::inst = NULL;
|
||||||
VALUE RubyScript::RubyAegisub;
|
VALUE RubyScript::RubyAegisub = Qfalse;
|
||||||
// RubyAssFile *RubyAssFile::raf = NULL;
|
// RubyAssFile *RubyAssFile::raf = NULL;
|
||||||
|
|
||||||
// RubyScriptReader
|
// RubyScriptReader
|
||||||
|
@ -115,6 +115,7 @@ namespace Automation4 {
|
||||||
ruby_init();
|
ruby_init();
|
||||||
ruby_init_loadpath();
|
ruby_init_loadpath();
|
||||||
RubyScript::inst = this;
|
RubyScript::inst = this;
|
||||||
|
if(!RubyAegisub) {
|
||||||
RubyAegisub = rb_define_module("Aegisub");
|
RubyAegisub = rb_define_module("Aegisub");
|
||||||
rb_define_module_function(RubyAegisub, "register_macro",reinterpret_cast<RB_HOOK>(&RubyFeatureMacro::RubyRegister), 4);
|
rb_define_module_function(RubyAegisub, "register_macro",reinterpret_cast<RB_HOOK>(&RubyFeatureMacro::RubyRegister), 4);
|
||||||
rb_define_module_function(RubyAegisub, "register_filter",reinterpret_cast<RB_HOOK>(&RubyFeatureFilter::RubyRegister), 5);
|
rb_define_module_function(RubyAegisub, "register_filter",reinterpret_cast<RB_HOOK>(&RubyFeatureFilter::RubyRegister), 5);
|
||||||
|
@ -124,6 +125,8 @@ namespace Automation4 {
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "progress_title",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTitle), 1);
|
rb_define_module_function(RubyScript::RubyAegisub, "progress_title",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTitle), 1);
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "debug_out",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDebugOut), -1);
|
rb_define_module_function(RubyScript::RubyAegisub, "debug_out",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDebugOut), -1);
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "get_cancelled",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyGetCancelled), 0);
|
rb_define_module_function(RubyScript::RubyAegisub, "get_cancelled",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyGetCancelled), 0);
|
||||||
|
rb_define_module_function(RubyScript::RubyAegisub, "display_dialog",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDisplayDialog), 2);
|
||||||
|
}
|
||||||
VALUE paths = rb_gv_get("$:");
|
VALUE paths = rb_gv_get("$:");
|
||||||
for(int i = 0; i < include_path.GetCount(); i++)
|
for(int i = 0; i < include_path.GetCount(); i++)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +141,9 @@ namespace Automation4 {
|
||||||
if(status > 0) // something bad happened (probably parsing error)
|
if(status > 0) // something bad happened (probably parsing error)
|
||||||
{
|
{
|
||||||
VALUE err = rb_errinfo();
|
VALUE err = rb_errinfo();
|
||||||
|
if(TYPE(err) == T_STRING)
|
||||||
throw StringValueCStr(err);
|
throw StringValueCStr(err);
|
||||||
|
else throw "Error loading script";
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE global_var = rb_gv_get("$script_name");
|
VALUE global_var = rb_gv_get("$script_name");
|
||||||
|
@ -166,11 +171,8 @@ namespace Automation4 {
|
||||||
void RubyScript::Destroy()
|
void RubyScript::Destroy()
|
||||||
{
|
{
|
||||||
if(loaded) {
|
if(loaded) {
|
||||||
ruby_finalize();
|
// ruby_finalize(); // broken in 1.9 ?_?
|
||||||
ruby_cleanup(0);
|
|
||||||
}
|
}
|
||||||
// TODO: would be nice to implement this
|
|
||||||
// RubyObjects::Get()->UnregisterAll();
|
|
||||||
|
|
||||||
// remove features
|
// remove features
|
||||||
for (int i = 0; i < (int)features.size(); i++) {
|
for (int i = 0; i < (int)features.size(); i++) {
|
||||||
|
@ -324,6 +326,7 @@ namespace Automation4 {
|
||||||
RubyThreadedCall call(&arg, &result);
|
RubyThreadedCall call(&arg, &result);
|
||||||
RubyProgressSink::inst->ShowModal();
|
RubyProgressSink::inst->ShowModal();
|
||||||
wxThread::ExitCode code = call.Wait();
|
wxThread::ExitCode code = call.Wait();
|
||||||
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = NULL;
|
RubyProgressSink::inst = NULL;
|
||||||
if(code)
|
if(code)
|
||||||
{
|
{
|
||||||
|
@ -331,7 +334,7 @@ namespace Automation4 {
|
||||||
throw StringValueCStr(result);
|
throw StringValueCStr(result);
|
||||||
else throw "Unknown Error";
|
else throw "Unknown Error";
|
||||||
}
|
}
|
||||||
else if(result != Qnil && result != Qfalse)
|
else if(TYPE(result) == T_ARRAY)
|
||||||
{
|
{
|
||||||
subsobj->RubyUpdateAssFile(result);
|
subsobj->RubyUpdateAssFile(result);
|
||||||
}
|
}
|
||||||
|
@ -404,27 +407,27 @@ namespace Automation4 {
|
||||||
void RubyFeatureFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog)
|
void RubyFeatureFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog)
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: configuration dialog
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
VALUE cfg;
|
||||||
if (has_config && config_dialog) {
|
if (has_config && config_dialog) {
|
||||||
assert(config_dialog->RubyReadBack() == 1);
|
cfg = config_dialog->RubyReadBack();
|
||||||
// TODO, write back stored options here
|
// TODO, write back stored options here
|
||||||
}
|
}
|
||||||
delete RubyProgressSink::inst;
|
// delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = new RubyProgressSink(export_dialog, false);
|
// RubyProgressSink::inst = new RubyProgressSink(export_dialog, false);
|
||||||
RubyProgressSink::inst->SetTitle(GetName());
|
// RubyProgressSink::inst->SetTitle(GetName());
|
||||||
|
|
||||||
RubyAssFile *subsobj = new RubyAssFile(subs, true/*modify*/, false/*undo*/);
|
RubyAssFile *subsobj = new RubyAssFile(subs, true/*modify*/, false/*undo*/);
|
||||||
VALUE *argv = ALLOCA_N(VALUE, 2);
|
VALUE *argv = ALLOCA_N(VALUE, 2);
|
||||||
argv[0] = subsobj->rbAssFile;
|
argv[0] = subsobj->rbAssFile;
|
||||||
argv[1] = Qnil; // config
|
argv[1] = cfg; // config
|
||||||
RubyCallArguments arg(rb_mKernel, rb_to_id(filter_fun), 2, argv);
|
RubyCallArguments arg(rb_mKernel, rb_to_id(filter_fun), 2, argv);
|
||||||
VALUE result;
|
VALUE result;
|
||||||
RubyThreadedCall call(&arg, &result);
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst->ShowModal();
|
|
||||||
wxThread::ExitCode code = call.Wait();
|
|
||||||
RubyProgressSink::inst = NULL;
|
RubyProgressSink::inst = NULL;
|
||||||
|
RubyThreadedCall call(&arg, &result);
|
||||||
|
// RubyProgressSink::inst->ShowModal();
|
||||||
|
wxThread::ExitCode code = call.Wait();
|
||||||
if(code)
|
if(code)
|
||||||
{
|
{
|
||||||
if(TYPE(result) == T_STRING)
|
if(TYPE(result) == T_STRING)
|
||||||
|
@ -447,25 +450,26 @@ namespace Automation4 {
|
||||||
if (!has_config)
|
if (!has_config)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//GetFeatureFunction(2); // 2 = config dialog function
|
|
||||||
|
|
||||||
// prepare function call
|
|
||||||
// subtitles (don't allow any modifications during dialog creation, ideally the subs aren't even accessed)
|
|
||||||
// RubyAssFile *subsobj = new RubyAssFile(AssFile::top, false/*allow modifications*/, false/*disallow undo*/);
|
|
||||||
// stored options
|
|
||||||
|
|
||||||
/* if(RubyProgressSink::inst)
|
|
||||||
{
|
|
||||||
delete RubyProgressSink::inst;
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = NULL;
|
|
||||||
}
|
|
||||||
RubyProgressSink::inst = new RubyProgressSink(parent, false);
|
RubyProgressSink::inst = new RubyProgressSink(parent, false);
|
||||||
RubyProgressSink::inst->SetTitle(GetName());
|
RubyProgressSink::inst->SetTitle(GetName());
|
||||||
|
|
||||||
// do call TODO
|
// prepare function call
|
||||||
RubyProgressSink::inst->ShowModal();
|
// subtitles (don't allow any modifications during dialog creation, ideally the subs aren't even accessed)
|
||||||
|
RubyAssFile *subsobj = new RubyAssFile(AssFile::top, false/*allow modifications*/, false/*disallow undo*/);
|
||||||
|
|
||||||
*/ return config_dialog = new RubyConfigDialog(false);
|
VALUE *argv = ALLOCA_N(VALUE, 2);
|
||||||
|
argv[0] = subsobj->rbAssFile;
|
||||||
|
argv[1] = Qnil; // TODO: stored options
|
||||||
|
RubyCallArguments arg(rb_mKernel, rb_to_id(dialog_fun), 2, argv);
|
||||||
|
VALUE dialog_data;
|
||||||
|
RubyThreadedCall call(&arg, &dialog_data);
|
||||||
|
RubyProgressSink::inst->ShowModal();
|
||||||
|
wxThread::ExitCode code = call.Wait();
|
||||||
|
delete RubyProgressSink::inst;
|
||||||
|
RubyProgressSink::inst = NULL;
|
||||||
|
|
||||||
|
return config_dialog = new RubyConfigDialog(dialog_data, Qnil, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -523,9 +527,19 @@ namespace Automation4 {
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RubyProgressSink::RubyDisplayDialog()
|
VALUE RubyProgressSink::RubyDisplayDialog(VALUE self, VALUE dialog_data, VALUE buttons)
|
||||||
{
|
{
|
||||||
return 0;
|
// Send the "show dialog" event
|
||||||
|
ShowConfigDialogEvent evt;
|
||||||
|
|
||||||
|
RubyConfigDialog dlg(dialog_data, buttons, true); // magically creates the config dialog structure etc
|
||||||
|
evt.config_dialog = &dlg;
|
||||||
|
|
||||||
|
wxSemaphore sema(0, 1);
|
||||||
|
evt.sync_sema = &sema;
|
||||||
|
RubyProgressSink::inst->AddPendingEvent(evt);
|
||||||
|
sema.Wait();
|
||||||
|
return dlg.RubyReadBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ namespace Automation4 {
|
||||||
// Provides progress UI and control functions for a Ruby script
|
// Provides progress UI and control functions for a Ruby script
|
||||||
class RubyProgressSink : public ProgressSink {
|
class RubyProgressSink : public ProgressSink {
|
||||||
private:
|
private:
|
||||||
static int RubyDisplayDialog();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RubyProgressSink(wxWindow *parent, bool allow_config_dialog = true);
|
RubyProgressSink(wxWindow *parent, bool allow_config_dialog = true);
|
||||||
|
@ -103,6 +102,7 @@ namespace Automation4 {
|
||||||
static VALUE RubySetTitle(VALUE self, VALUE title);
|
static VALUE RubySetTitle(VALUE self, VALUE title);
|
||||||
static VALUE RubyGetCancelled(VALUE self);
|
static VALUE RubyGetCancelled(VALUE self);
|
||||||
static VALUE RubyDebugOut(int argc, VALUE *args, VALUE self);
|
static VALUE RubyDebugOut(int argc, VALUE *args, VALUE self);
|
||||||
|
static VALUE RubyDisplayDialog(VALUE self, VALUE cfg, VALUE buttons);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,9 +115,10 @@ namespace Automation4 {
|
||||||
|
|
||||||
virtual wxControl *Create(wxWindow *parent) = 0;
|
virtual wxControl *Create(wxWindow *parent) = 0;
|
||||||
virtual void ControlReadBack() = 0;
|
virtual void ControlReadBack() = 0;
|
||||||
virtual void RubyReadBack() = 0;
|
virtual VALUE RubyReadBack() = 0;
|
||||||
|
|
||||||
RubyConfigDialogControl();
|
RubyConfigDialogControl();
|
||||||
|
RubyConfigDialogControl(VALUE opts);
|
||||||
virtual ~RubyConfigDialogControl() { }
|
virtual ~RubyConfigDialogControl() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,9 +141,9 @@ namespace Automation4 {
|
||||||
wxWindow* CreateWindow(wxWindow *parent);
|
wxWindow* CreateWindow(wxWindow *parent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RubyConfigDialog(bool include_buttons);
|
RubyConfigDialog(VALUE cfg, VALUE buttons, bool show_buttons);
|
||||||
virtual ~RubyConfigDialog();
|
virtual ~RubyConfigDialog();
|
||||||
int RubyReadBack(); // read back internal structure to lua structures
|
VALUE RubyReadBack(); // read back internal structure to Ruby hash
|
||||||
|
|
||||||
void ReadBack(); // from auto4 base
|
void ReadBack(); // from auto4 base
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,62 +47,46 @@ namespace Automation4 {
|
||||||
|
|
||||||
// RubyConfigDialogControl
|
// RubyConfigDialogControl
|
||||||
|
|
||||||
RubyConfigDialogControl::RubyConfigDialogControl()
|
RubyConfigDialogControl::RubyConfigDialogControl(VALUE opts)
|
||||||
{
|
{
|
||||||
// Assume top of stack is a control table (don't do checking)
|
VALUE val = rb_hash_aref(opts, rb_str_new2("name"));
|
||||||
|
if(TYPE(val) == T_STRING)
|
||||||
|
name = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
|
else name = _T("");
|
||||||
|
|
||||||
/* lua_getfield(L, -1, "name");
|
val = rb_hash_aref(opts, rb_str_new2("x"));
|
||||||
if (lua_isstring(L, -1)) {
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
name = wxString(lua_tostring(L, -1), wxConvUTF8);
|
x = FIX2INT(val);
|
||||||
} else {
|
|
||||||
name = _T("");
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
lua_getfield(L, -1, "x");
|
|
||||||
if (lua_isnumber(L, -1)) {
|
|
||||||
x = lua_tointeger(L, -1);
|
|
||||||
if (x < 0) x = 0;
|
if (x < 0) x = 0;
|
||||||
} else {
|
|
||||||
x = 0;
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
else x = 0;
|
||||||
|
|
||||||
lua_getfield(L, -1, "y");
|
val = rb_hash_aref(opts, rb_str_new2("y"));
|
||||||
if (lua_isnumber(L, -1)) {
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
y = lua_tointeger(L, -1);
|
y = FIX2INT(val);
|
||||||
if (y < 0) y = 0;
|
if (y < 0) y = 0;
|
||||||
} else {
|
|
||||||
y = 0;
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
else y = 0;
|
||||||
|
|
||||||
lua_getfield(L, -1, "width");
|
val = rb_hash_aref(opts, rb_str_new2("width"));
|
||||||
if (lua_isnumber(L, -1)) {
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
width = lua_tointeger(L, -1);
|
width = FIX2INT(val);
|
||||||
if (width < 1) width = 1;
|
if (width < 1) width = 1;
|
||||||
} else {
|
|
||||||
width = 1;
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
else width = 1;
|
||||||
|
|
||||||
lua_getfield(L, -1, "height");
|
val = rb_hash_aref(opts, rb_str_new2("height"));
|
||||||
if (lua_isnumber(L, -1)) {
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
height = lua_tointeger(L, -1);
|
height = FIX2INT(val);
|
||||||
if (height < 1) height = 1;
|
if (height < 1) width = 1;
|
||||||
} else {
|
|
||||||
height = 1;
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
else height = 1;
|
||||||
|
|
||||||
|
val = rb_hash_aref(opts, rb_str_new2("hint"));
|
||||||
|
if(TYPE(val) == T_STRING)
|
||||||
|
hint = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
|
else hint = _T("");
|
||||||
|
|
||||||
lua_getfield(L, -1, "hint");
|
|
||||||
if (lua_isstring(L, -1)) {
|
|
||||||
hint = wxString(lua_tostring(L, -1), wxConvUTF8);
|
|
||||||
} else {
|
|
||||||
hint = _T("");
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
*/
|
|
||||||
wxLogDebug(_T("created control: '%s', (%d,%d)(%d,%d), '%s'"), name.c_str(), x, y, width, height, hint.c_str());
|
wxLogDebug(_T("created control: '%s', (%d,%d)(%d,%d), '%s'"), name.c_str(), x, y, width, height, hint.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,13 +98,15 @@ namespace Automation4 {
|
||||||
public:
|
public:
|
||||||
wxString label;
|
wxString label;
|
||||||
|
|
||||||
Label()
|
Label(){};
|
||||||
: RubyConfigDialogControl()
|
Label(VALUE opts)
|
||||||
|
: RubyConfigDialogControl(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "label");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("label"));
|
||||||
label = wxString(lua_tostring(L, -1), wxConvUTF8);
|
if(TYPE(val) == T_STRING)
|
||||||
lua_pop(L, 1);
|
label = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
*/ }
|
else label = _T("");
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Label() { }
|
virtual ~Label() { }
|
||||||
|
|
||||||
|
@ -134,10 +120,9 @@ namespace Automation4 {
|
||||||
// Nothing here
|
// Nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// Label doesn't produce output, so let it be nil
|
return Qnil;
|
||||||
// lua_pushnil(L);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,13 +133,15 @@ namespace Automation4 {
|
||||||
public:
|
public:
|
||||||
wxString text;
|
wxString text;
|
||||||
|
|
||||||
Edit()
|
Edit(){};
|
||||||
: RubyConfigDialogControl()
|
Edit(VALUE opts)
|
||||||
|
: RubyConfigDialogControl(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "text");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("text"));
|
||||||
text = wxString(lua_tostring(L, -1), wxConvUTF8);
|
if(TYPE(val) == T_STRING)
|
||||||
lua_pop(L, 1);
|
text = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
*/ }
|
else text = _T("");
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Edit() { }
|
virtual ~Edit() { }
|
||||||
|
|
||||||
|
@ -168,9 +155,9 @@ namespace Automation4 {
|
||||||
text = ((wxTextCtrl*)cw)->GetValue();
|
text = ((wxTextCtrl*)cw)->GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// lua_pushstring(L, text.mb_str(wxConvUTF8));
|
return rb_str_new2(text.mb_str(wxConvUTF8));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -181,8 +168,9 @@ namespace Automation4 {
|
||||||
class Textbox : public Edit {
|
class Textbox : public Edit {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Textbox()
|
Textbox(){};
|
||||||
: Edit()
|
Textbox(VALUE opts)
|
||||||
|
: Edit(opts)
|
||||||
{
|
{
|
||||||
// Nothing more
|
// Nothing more
|
||||||
}
|
}
|
||||||
|
@ -207,33 +195,28 @@ namespace Automation4 {
|
||||||
bool hasspin;
|
bool hasspin;
|
||||||
int min, max;
|
int min, max;
|
||||||
|
|
||||||
IntEdit()
|
IntEdit(){};
|
||||||
: Edit()
|
IntEdit(VALUE opts)
|
||||||
|
: Edit(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "value");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("value"));
|
||||||
value = lua_tointeger(L, -1);
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
lua_pop(L, 1);
|
value = FIX2INT(val);
|
||||||
|
}
|
||||||
|
|
||||||
hasspin = false;
|
hasspin = false;
|
||||||
|
val = rb_hash_aref(opts, rb_str_new2("min"));
|
||||||
lua_getfield(L, -1, "min");
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
if (!lua_isnumber(L, -1))
|
min = FIX2INT(val);
|
||||||
goto nospin;
|
}
|
||||||
min = lua_tointeger(L, -1);
|
else return;
|
||||||
lua_pop(L, 1);
|
|
||||||
|
val = rb_hash_aref(opts, rb_str_new2("min"));
|
||||||
lua_getfield(L, -1, "max");
|
if(TYPE(val) == T_FIXNUM) {
|
||||||
if (!lua_isnumber(L, -1))
|
min = FIX2INT(val);
|
||||||
goto nospin;
|
hasspin = true;
|
||||||
max = lua_tointeger(L, -1);
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
hasspin = true;
|
|
||||||
nospin:
|
|
||||||
if (!hasspin) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
*/ }
|
|
||||||
|
|
||||||
virtual ~IntEdit() { }
|
virtual ~IntEdit() { }
|
||||||
|
|
||||||
|
@ -260,9 +243,9 @@ nospin:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// lua_pushinteger(L, value);
|
return INT2FIX(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -275,13 +258,16 @@ nospin:
|
||||||
float value;
|
float value;
|
||||||
// FIXME: Can't support spin button atm
|
// FIXME: Can't support spin button atm
|
||||||
|
|
||||||
FloatEdit()
|
FloatEdit(){};
|
||||||
: Edit()
|
FloatEdit(VALUE opts)
|
||||||
|
: Edit(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "value");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("value"));
|
||||||
value = lua_tointeger(L, -1);
|
if(TYPE(val) == T_FLOAT) {
|
||||||
lua_pop(L, 1);
|
value = NUM2DBL(val);
|
||||||
*/
|
} else if (TYPE(val) == T_FIXNUM) {
|
||||||
|
value = FIX2INT(val);
|
||||||
|
}
|
||||||
// TODO: spin button support
|
// TODO: spin button support
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,9 +288,9 @@ nospin:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// lua_pushnumber(L, value);
|
return rb_float_new(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -317,23 +303,26 @@ nospin:
|
||||||
wxArrayString items;
|
wxArrayString items;
|
||||||
wxString value;
|
wxString value;
|
||||||
|
|
||||||
Dropdown()
|
Dropdown(){};
|
||||||
: RubyConfigDialogControl()
|
Dropdown(VALUE opts)
|
||||||
|
: RubyConfigDialogControl(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "value");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("value"));
|
||||||
value = wxString(lua_tostring(L, -1), wxConvUTF8);
|
if(TYPE(val) == T_STRING)
|
||||||
lua_pop(L, 1);
|
value = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
|
|
||||||
lua_getfield(L, -1, "items");
|
val = rb_hash_aref(opts, rb_str_new2("items"));
|
||||||
lua_pushnil(L);
|
if(TYPE(val) == T_ARRAY)
|
||||||
while (lua_next(L, -2)) {
|
{
|
||||||
if (lua_isstring(L, -1)) {
|
long len = RARRAY(val)->len;
|
||||||
items.Add(wxString(lua_tostring(L, -1), wxConvUTF8));
|
VALUE *ptr = RARRAY(val)->ptr;
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if(TYPE(ptr[i]) == T_STRING)
|
||||||
|
items.Add(wxString(StringValueCStr(ptr[i]), wxConvUTF8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
*/ }
|
|
||||||
|
|
||||||
virtual ~Dropdown() { }
|
virtual ~Dropdown() { }
|
||||||
|
|
||||||
|
@ -347,11 +336,10 @@ nospin:
|
||||||
value = ((wxComboBox*)cw)->GetValue();
|
value = ((wxComboBox*)cw)->GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// lua_pushstring(L, value.mb_str(wxConvUTF8));
|
return rb_str_new2(value.mb_str(wxConvUTF8));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -362,17 +350,18 @@ nospin:
|
||||||
wxString label;
|
wxString label;
|
||||||
bool value;
|
bool value;
|
||||||
|
|
||||||
Checkbox()
|
Checkbox(){};
|
||||||
: RubyConfigDialogControl()
|
Checkbox(VALUE opts)
|
||||||
|
: RubyConfigDialogControl(opts)
|
||||||
{
|
{
|
||||||
/* lua_getfield(L, -1, "label");
|
VALUE val = rb_hash_aref(opts, rb_str_new2("label"));
|
||||||
label = wxString(lua_tostring(L, -1), wxConvUTF8);
|
if(TYPE(val) == T_STRING)
|
||||||
lua_pop(L, 1);
|
label = wxString(StringValueCStr(val), wxConvUTF8);
|
||||||
|
|
||||||
lua_getfield(L, -1, "value");
|
val = rb_hash_aref(opts, rb_str_new2("value"));
|
||||||
value = lua_toboolean(L, -1) != 0;
|
if(val == Qtrue) value = true;
|
||||||
lua_pop(L, 1);
|
else value = false;
|
||||||
*/ }
|
}
|
||||||
|
|
||||||
virtual ~Checkbox() { }
|
virtual ~Checkbox() { }
|
||||||
|
|
||||||
|
@ -386,9 +375,10 @@ nospin:
|
||||||
value = ((wxCheckBox*)cw)->GetValue();
|
value = ((wxCheckBox*)cw)->GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyReadBack()
|
VALUE RubyReadBack()
|
||||||
{
|
{
|
||||||
// lua_pushboolean(L, value);
|
if(value) return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -398,91 +388,77 @@ nospin:
|
||||||
|
|
||||||
// RubyConfigDialog
|
// RubyConfigDialog
|
||||||
|
|
||||||
RubyConfigDialog::RubyConfigDialog(bool include_buttons)
|
RubyConfigDialog::RubyConfigDialog(VALUE config, VALUE btn_data, bool include_buttons)
|
||||||
: use_buttons(include_buttons)
|
: use_buttons(include_buttons)
|
||||||
{
|
{
|
||||||
wxLogDebug(_T("creating RubyConfigDialog, this addr is %p"), this);
|
wxLogDebug(_T("creating RubyConfigDialog, this addr is %p"), this);
|
||||||
button_pushed = 0;
|
button_pushed = 0;
|
||||||
/* if (include_buttons) {
|
|
||||||
|
|
||||||
if (!lua_istable(L, -1))
|
if(include_buttons && TYPE(btn_data) == T_ARRAY)
|
||||||
// Just to avoid deeper indentation...
|
{
|
||||||
goto skipbuttons;
|
long len = RARRAY(config)->len;
|
||||||
// Iterate over items in table
|
VALUE *ptr = RARRAY(config)->ptr;
|
||||||
lua_pushnil(L); // initial key
|
for(int i = 0; i < len; i++)
|
||||||
while (lua_next(L, -2)) {
|
{
|
||||||
// Simply skip invalid items... FIXME, warn here?
|
if(TYPE(ptr[i]) == T_STRING)
|
||||||
if (lua_isstring(L, -1)) {
|
{
|
||||||
wxString s(lua_tostring(L, -1), wxConvUTF8);
|
wxString s(StringValueCStr(ptr[i]), wxConvUTF8);
|
||||||
buttons.push_back(s);
|
buttons.push_back(s);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
skipbuttons:
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume top of stack now contains a dialog table
|
if(TYPE(config) != T_ARRAY) {
|
||||||
if (!lua_istable(L, -1)) {
|
if(rb_respond_to(config, rb_intern("to_ary")))
|
||||||
lua_pushstring(L, "Cannot create config dialog from something non-table");
|
config = rb_funcall(config, rb_intern("to_ary"), 0);
|
||||||
lua_error(L);
|
else throw "Cannot create config dialog from something non-table";
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, so there is a table with controls
|
long len = RARRAY(config)->len;
|
||||||
lua_pushnil(L); // initial key
|
VALUE *ptr = RARRAY(config)->ptr;
|
||||||
while (lua_next(L, -2)) {
|
for(int i = 0; i < len; i++)
|
||||||
if (lua_istable(L, -1)) {
|
{
|
||||||
// Get control class
|
if(TYPE(ptr[i]) != T_HASH)
|
||||||
lua_getfield(L, -1, "class");
|
continue; // skip invalid entry
|
||||||
if (!lua_isstring(L, -1))
|
|
||||||
goto badcontrol;
|
VALUE ctrlclass = rb_hash_aref(ptr[i], rb_str_new2("class"));
|
||||||
wxString controlclass(lua_tostring(L, -1), wxConvUTF8);
|
|
||||||
|
if (TYPE(ctrlclass) != T_STRING)
|
||||||
|
continue; // skip
|
||||||
|
wxString controlclass(StringValueCStr(ctrlclass), wxConvUTF8);
|
||||||
controlclass.LowerCase();
|
controlclass.LowerCase();
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
RubyConfigDialogControl *ctl;
|
RubyConfigDialogControl *ctl;
|
||||||
|
|
||||||
// Check control class and create relevant control
|
// Check control class and create relevant control
|
||||||
if (controlclass == _T("label")) {
|
if (controlclass == _T("label")) {
|
||||||
ctl = new RubyControl::Label(L);
|
ctl = new RubyControl::Label(ptr[i]);
|
||||||
} else if (controlclass == _T("edit")) {
|
} else if (controlclass == _T("edit")) {
|
||||||
ctl = new RubyControl::Edit(L);
|
ctl = new RubyControl::Edit(ptr[i]);
|
||||||
} else if (controlclass == _T("intedit")) {
|
} else if (controlclass == _T("intedit")) {
|
||||||
ctl = new RubyControl::IntEdit(L);
|
ctl = new RubyControl::IntEdit(ptr[i]);
|
||||||
} else if (controlclass == _T("floatedit")) {
|
} else if (controlclass == _T("floatedit")) {
|
||||||
ctl = new RubyControl::FloatEdit(L);
|
ctl = new RubyControl::FloatEdit(ptr[i]);
|
||||||
} else if (controlclass == _T("textbox")) {
|
} else if (controlclass == _T("textbox")) {
|
||||||
ctl = new RubyControl::Textbox(L);
|
ctl = new RubyControl::Textbox(ptr[i]);
|
||||||
} else if (controlclass == _T("dropdown")) {
|
} else if (controlclass == _T("dropdown")) {
|
||||||
ctl = new RubyControl::Dropdown(L);
|
ctl = new RubyControl::Dropdown(ptr[i]);
|
||||||
} else if (controlclass == _T("checkbox")) {
|
} else if (controlclass == _T("checkbox")) {
|
||||||
ctl = new RubyControl::Checkbox(L);
|
ctl = new RubyControl::Checkbox(ptr[i]);
|
||||||
} else if (controlclass == _T("color")) {
|
} else if (controlclass == _T("color")) {
|
||||||
// FIXME
|
// FIXME
|
||||||
ctl = new RubyControl::Edit(L);
|
ctl = new RubyControl::Edit(ptr[i]);
|
||||||
} else if (controlclass == _T("coloralpha")) {
|
} else if (controlclass == _T("coloralpha")) {
|
||||||
// FIXME
|
// FIXME
|
||||||
ctl = new RubyControl::Edit(L);
|
ctl = new RubyControl::Edit(ptr[i]);
|
||||||
} else if (controlclass == _T("alpha")) {
|
} else if (controlclass == _T("alpha")) {
|
||||||
// FIXME
|
// FIXME
|
||||||
ctl = new RubyControl::Edit(L);
|
ctl = new RubyControl::Edit(ptr[i]);
|
||||||
} else {
|
} else continue; // skip
|
||||||
goto badcontrol;
|
|
||||||
}
|
|
||||||
|
|
||||||
controls.push_back(ctl);
|
controls.push_back(ctl);
|
||||||
|
|
||||||
} else {
|
|
||||||
badcontrol:
|
|
||||||
// not a control...
|
|
||||||
// FIXME, better error reporting?
|
|
||||||
lua_pushstring(L, "bad control table entry");
|
|
||||||
lua_error(L);
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
*/ }
|
|
||||||
|
|
||||||
RubyConfigDialog::~RubyConfigDialog()
|
RubyConfigDialog::~RubyConfigDialog()
|
||||||
{
|
{
|
||||||
|
@ -537,42 +513,39 @@ badcontrol:
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RubyConfigDialog::RubyReadBack()
|
VALUE RubyConfigDialog::RubyReadBack()
|
||||||
{
|
{
|
||||||
// First read back which button was pressed, if any
|
VALUE cfg = rb_hash_new();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < controls.size(); ++i) {
|
||||||
|
rb_hash_aset(cfg, rb_str_new2(controls[i]->name.mb_str(wxConvUTF8)), controls[i]->RubyReadBack());
|
||||||
|
}
|
||||||
if (use_buttons) {
|
if (use_buttons) {
|
||||||
|
VALUE res = rb_ary_new();
|
||||||
|
|
||||||
wxLogDebug(_T("reading back button_pushed"));
|
wxLogDebug(_T("reading back button_pushed"));
|
||||||
int btn = button_pushed;
|
int btn = button_pushed;
|
||||||
if (btn == 0) {
|
if (btn == 0) {
|
||||||
wxLogDebug(_T("was zero, cancelled"));
|
wxLogDebug(_T("was zero, cancelled"));
|
||||||
// Always cancel/closed
|
// Always cancel/closed
|
||||||
// lua_pushboolean(L, 0);
|
rb_ary_push(res, Qfalse);
|
||||||
} else {
|
} else {
|
||||||
wxLogDebug(_T("nonzero, something else: %d"), btn);
|
wxLogDebug(_T("nonzero, something else: %d"), btn);
|
||||||
if (buttons.size() > 0) {
|
if (buttons.size() > 0) {
|
||||||
wxLogDebug(_T("user button: %s"), buttons[btn-1].c_str());
|
wxLogDebug(_T("user button: %s"), buttons[btn-1].c_str());
|
||||||
// button_pushed is index+1 to reserve 0 for Cancel
|
// button_pushed is index+1 to reserve 0 for Cancel
|
||||||
// lua_pushstring(L, buttons[btn-1].mb_str(wxConvUTF8));
|
rb_ary_push(res, rb_str_new2(buttons[btn-1].mb_str(wxConvUTF8)));
|
||||||
} else {
|
} else {
|
||||||
wxLogDebug(_T("default button, must be Ok"));
|
wxLogDebug(_T("default button, must be Ok"));
|
||||||
// Cancel case already covered, must be Ok then
|
// Cancel case already covered, must be Ok then
|
||||||
// lua_pushboolean(L, 1);
|
rb_ary_push(res, Qtrue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rb_ary_push(res, cfg); // return array [button, hash with config]
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then read controls back
|
return cfg; // if no buttons return only hash with config
|
||||||
// lua_newtable(L);
|
|
||||||
for (size_t i = 0; i < controls.size(); ++i) {
|
|
||||||
controls[i]->RubyReadBack(); // TODO
|
|
||||||
// lua_setfield(L, -2, controls[i]->name.mb_str(wxConvUTF8));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_buttons) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RubyConfigDialog::ReadBack()
|
void RubyConfigDialog::ReadBack()
|
||||||
|
|
Loading…
Reference in a new issue