From cda3b493c282ecb993cb4dd2e1251311b0544115 Mon Sep 17 00:00:00 2001 From: toshinagata1964 Date: Thu, 19 Jun 2014 10:50:59 +0000 Subject: [PATCH] Show MO Surface dialog is updated (hopefully improved) git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@552 a2be9bc6-48de-4e38-9406-05402d4bc13c --- MolLib/Molecule.c | 1 + MolLib/Ruby_bind/ruby_bind.c | 40 ++++++++++++++++++++---------------- MolLib/Ruby_bind/ruby_dialog.c | 23 ++++++++++++++------- MolLib/Ruby_bind/ruby_dialog.h | 2 +- Scripts/commands.rb | 46 +++++++++++++++++++++++++++++++----------- wxSources/RubyDialogFrame.cpp | 32 ++++++++++++++++++++++++----- wxSources/RubyDialogFrame.h | 4 ++++ 7 files changed, 106 insertions(+), 42 deletions(-) diff --git a/MolLib/Molecule.c b/MolLib/Molecule.c index 74fc495..8330455 100755 --- a/MolLib/Molecule.c +++ b/MolLib/Molecule.c @@ -11238,6 +11238,7 @@ MoleculeClearMCube(Molecule *mol, Int nx, Int ny, Int nz, const Vector *origin, } if (nx > 0 && ny > 0 && nz > 0) { mc = (MCube *)calloc(sizeof(MCube), 1); + mc->idn = -1; /* round up to nearest 4N+1 integer */ dx *= nx; dy *= ny; diff --git a/MolLib/Ruby_bind/ruby_bind.c b/MolLib/Ruby_bind/ruby_bind.c index 5762a17..8a251f5 100644 --- a/MolLib/Ruby_bind/ruby_bind.c +++ b/MolLib/Ruby_bind/ruby_bind.c @@ -10188,29 +10188,35 @@ s_Molecule_CreateSurface(int argc, VALUE *argv, VALUE self) if (MoleculeClearMCube(mol, nx, ny, nz, &o, dx.x, dy.y, dz.z) == NULL) rb_raise(rb_eMolbyError, "Cannot allocate memory for MO surface calculation"); } - if (hval != Qnil && (((nx = 1), (aval = rb_hash_aref(hval, ID2SYM(rb_intern("color")))) != Qnil) || - ((nx = 0), (aval = rb_hash_aref(hval, ID2SYM(rb_intern("color0")))) != Qnil))) { - aval = rb_ary_to_ary(aval); - if (RARRAY_LEN(aval) < 3) { - raise: - rb_raise(rb_eMolbyError, "The color%s value must be an array with at least 3 float numbers", (nx == 0 ? "0" : "")); - } - for (i = 0; i < 4; i++) - d[i] = mol->mcube->c[nx].rgba[i]; - for (i = 0; i < 4 && i < RARRAY_LEN(aval); i++) { - d[i] = NUM2DBL(rb_Float(RARRAY_PTR(aval)[i])); - if (d[i] < 0.0 && d[i] > 1.0) - goto raise; + for (nx = 0; nx < 2; nx++) { + aval = ID2SYM(rb_intern(nx == 0 ? "color0" : "color")); + if (hval != Qnil && (aval = rb_hash_aref(hval, aval)) != Qnil) { + aval = rb_ary_to_ary(aval); + if (RARRAY_LEN(aval) < 3) { + raise: + rb_raise(rb_eMolbyError, "The color%s value must be an array with at least 3 float numbers", (nx == 0 ? "0" : "")); + } + for (i = 0; i < 4; i++) + d[i] = mol->mcube->c[nx].rgba[i]; + for (i = 0; i < 4 && i < RARRAY_LEN(aval); i++) { + d[i] = NUM2DBL(rb_Float(RARRAY_PTR(aval)[i])); + if (d[i] < 0.0 && d[i] > 1.0) + goto raise; + } + for (i = 0; i < 4; i++) + mol->mcube->c[nx].rgba[i] = d[i]; } - for (i = 0; i < 4; i++) - mol->mcube->c[nx].rgba[i] = d[i]; } if (mol->mcube->expand != expand) need_recalc = 1; mol->mcube->thres = thres; mol->mcube->expand = expand; - if (nmo < 0 && need_recalc) - nmo = mol->mcube->idn; /* Force recalculation */ + if (nmo < 0) { + if (mol->mcube->idn < 0) + return self; /* Only set attributes for now */ + if (need_recalc) + nmo = mol->mcube->idn; /* Force recalculation */ + } if (MoleculeUpdateMCube(mol, nmo) != 0) rb_raise(rb_eMolbyError, "Cannot complete MO surface calculation"); return self; diff --git a/MolLib/Ruby_bind/ruby_dialog.c b/MolLib/Ruby_bind/ruby_dialog.c index 7479b0d..72a4977 100644 --- a/MolLib/Ruby_bind/ruby_dialog.c +++ b/MolLib/Ruby_bind/ruby_dialog.c @@ -2000,7 +2000,8 @@ s_RubyDialog_doItemAction(VALUE val) VALUE flag; RDItem *ip = (RDItem *)vp[1]; RDItem *ip2; - VALUE ival, itval, actval; + Int options = (Int)vp[2]; + VALUE ival, itval, actval, tval, aval; RubyDialog *dref = s_RubyDialog_GetController(self); VALUE items = rb_iv_get(self, "_items"); int nitems = RARRAY_LEN(items); @@ -2016,7 +2017,9 @@ s_RubyDialog_doItemAction(VALUE val) rb_ivar_set(itval, SYM2ID(sIsProcessingActionSymbol), Qtrue); /* Handle radio group */ - if (s_RubyDialogItem_Attr(itval, sTypeSymbol) == sRadioSymbol) { + tval = s_RubyDialogItem_Attr(itval, sTypeSymbol); + aval = sActionSymbol; + if (tval == sRadioSymbol) { VALUE gval = s_RubyDialogItem_Attr(itval, sRadioGroupSymbol); if (gval == Qnil) { /* All other radio buttons with no radio group will be deselected */ @@ -2043,16 +2046,21 @@ s_RubyDialog_doItemAction(VALUE val) } } + if (tval == sTextFieldSymbol || tval == sTextViewSymbol) { + if (options == 1) + aval = ID2SYM(rb_intern("text_action")); /* Action for every text update */ + } + /* If the item has the "action" attribute, call it */ - actval = s_RubyDialogItem_Attr(itval, sActionSymbol); + actval = s_RubyDialogItem_Attr(itval, aval); if (actval != Qnil) { if (TYPE(actval) == T_SYMBOL) rb_funcall(self, SYM2ID(actval), 1, itval); else rb_funcall(actval, rb_intern("call"), 1, itval); - } else if (rb_respond_to(itval, SYM2ID(sActionSymbol))) { + } else if (rb_respond_to(itval, SYM2ID(aval))) { /* If "action" method is defined, then call it without arguments */ - rb_funcall(itval, SYM2ID(sActionSymbol), 0); + rb_funcall(itval, SYM2ID(aval), 0); } else { /* Default action (only for default buttons) */ if (idx == 0 || idx == 1) { @@ -2071,12 +2079,13 @@ s_RubyDialog_doItemAction(VALUE val) the item number (integer) as the argument. The default "action" method is defined as s_RubyDialog_action. */ void -RubyDialog_doItemAction(RubyValue self, RDItem *ip) +RubyDialog_doItemAction(RubyValue self, RDItem *ip, Int options) { int status; - void *vp[2]; + void *vp[3]; vp[0] = (void *)self; vp[1] = ip; + vp[2] = (void *)options; rb_protect(s_RubyDialog_doItemAction, (VALUE)vp, &status); if (status != 0) Molby_showError(status); diff --git a/MolLib/Ruby_bind/ruby_dialog.h b/MolLib/Ruby_bind/ruby_dialog.h index 3dfc8e1..2bf3e4c 100644 --- a/MolLib/Ruby_bind/ruby_dialog.h +++ b/MolLib/Ruby_bind/ruby_dialog.h @@ -53,7 +53,7 @@ extern const RDRect gZeroRect; /* Utility function */ extern int RubyDialog_validateItemContent(RubyValue self, RDItem *ip, const char *s); -extern void RubyDialog_doItemAction(RubyValue self, RDItem *ip); +extern void RubyDialog_doItemAction(RubyValue self, RDItem *ip, Int options); extern void RubyDialog_doTimerAction(RubyValue self); extern void RubyDialog_doKeyAction(RubyValue self, int keyCode); extern int RubyDialog_getFlexFlags(RubyValue self, RDItem *ip); diff --git a/Scripts/commands.rb b/Scripts/commands.rb index db841f5..882e863 100755 --- a/Scripts/commands.rb +++ b/Scripts/commands.rb @@ -233,7 +233,7 @@ class Molecule beta = nil end i = (beta ? 2 : 1) - mo_menu = [] # Create later + mo_menu = ["1000 (-00.00000000)"] # Dummy entry; create later tabvals = [] coeffs = nil a_idx_old = -1 @@ -265,15 +265,34 @@ class Molecule h = {"mo"=>nil, "color"=>nil, "opacity"=>nil, "threshold"=>nil, "expand"=>nil, "grid"=>nil} should_update = true on_action = lambda { |it| - should_update = false - h.each_key { |key| - val = value(key) - if val && h[key] != val - should_update = true - break - end - } - item_with_tag("update")[:enabled] = should_update + tag = it[:tag] + value = it[:value] + if tag == "color" || tag == "opacity" + opac = value("opacity").to_f + opac = 0.0 if opac < 0.0 + opac = 1.0 if opac > 1.0 + col = value("color") + color = coltable[col] + [opac] + color0 = [1,1,1,opac] + mol.set_surface_attr(:color=>color, :color0=>color0) + h[tag] = value + elsif tag == "threshold" + thres = it[:value].to_f + thres = 0.001 if thres >= 0.0 && thres < 0.001 + thres = -0.001 if thres <= 0.0 && thres > -0.001 + mol.set_surface_attr(:thres=>thres) + h[tag] = value + else + should_update = false + h.each_key { |key| + val = value(key) + if val && h[key] != val + should_update = true + break + end + } + item_with_tag("update")[:enabled] = should_update + end } on_mo_action = lambda { |it| mo = it[:value] @@ -304,7 +323,7 @@ class Molecule i1 = n i2 = 1 c1 = "" - c2 = (i1 >= alpha ? "*" : "") + c2 = (i1 > alpha ? "*" : "") end en = mol.get_mo_energy(i1 + (i2 == 0 ? ncomps : 0)) sprintf("%d%s%s (%.8f)", i1, c1, c2, en) @@ -326,7 +345,10 @@ class Molecule h[key] = value(key) } opac = h["opacity"].to_f + opac = 0.0 if opac < 0.0 + opac = 1.0 if opac > 1.0 color = coltable[h["color"]] + [opac] + color0 = [1, 1, 1, opac] thres = h["threshold"].to_f thres = 0.001 if thres >= 0.0 && thres < 0.001 thres = -0.001 if thres <= 0.0 && thres > -0.001 @@ -343,7 +365,7 @@ class Molecule idx = 0 mol.set_mo_coefficients(0, 0.0, coeffs) end - mol.create_surface(idx, :npoints=>grid, :color=>color, :thres=>thres, :expand=>expand) + mol.create_surface(idx, :npoints=>grid, :color=>color, :thres=>thres, :expand=>expand, :color0=>color0) on_action.call(it) } layout(1, diff --git a/wxSources/RubyDialogFrame.cpp b/wxSources/RubyDialogFrame.cpp index 6c272ff..b224efe 100644 --- a/wxSources/RubyDialogFrame.cpp +++ b/wxSources/RubyDialogFrame.cpp @@ -232,7 +232,25 @@ RubyDialogFrame::StopIntervalTimer(void) void RubyDialogFrame::OnDialogItemAction(wxCommandEvent &event) { - RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject())); + RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 0); +} + +void +RubyDialogFrame::OnTextUpdated(wxCommandEvent &event) +{ + RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 1); +} + +void +RubyDialogFrame::OnEnterProcessedOnText(wxCommandEvent &event) +{ + RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 2); +} + +void +RubyDialogFrame::OnKillFocusOnText(wxFocusEvent &event) +{ + RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 3); } void @@ -852,14 +870,18 @@ RubyDialogCallback_createItem(RubyDialog *dref, const char *type, const char *ti no_action = true; } else if (strcmp(type, "textfield") == 0) { /* Editable text */ - wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize()); + wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_PROCESS_ENTER); control = tc; - tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent); + tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnTextUpdated), NULL, parent); + tc->Connect(-1, wxEVT_TEXT_ENTER, wxCommandEventHandler(RubyDialogFrame::OnEnterProcessedOnText), NULL, parent); + tc->Connect(-1, wxEVT_KILL_FOCUS, wxFocusEventHandler(RubyDialogFrame::OnKillFocusOnText), NULL, parent); } else if (strcmp(type, "textview") == 0) { /* Text view */ - wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_MULTILINE | wxTE_RICH); + wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_MULTILINE | wxTE_RICH | wxTE_PROCESS_ENTER); control = tc; - tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent); + tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnTextUpdated), NULL, parent); + tc->Connect(-1, wxEVT_TEXT_ENTER, wxCommandEventHandler(RubyDialogFrame::OnEnterProcessedOnText), NULL, parent); + tc->Connect(-1, wxEVT_KILL_FOCUS, wxFocusEventHandler(RubyDialogFrame::OnKillFocusOnText), NULL, parent); } else if (strcmp(type, "view") == 0) { /* Panel */ MyDrawingPanel *pn = new MyDrawingPanel(parent, -1, rect.GetPosition(), rect.GetSize()); diff --git a/wxSources/RubyDialogFrame.h b/wxSources/RubyDialogFrame.h index 69fbfd8..d073274 100644 --- a/wxSources/RubyDialogFrame.h +++ b/wxSources/RubyDialogFrame.h @@ -94,6 +94,10 @@ public: int StartIntervalTimer(int millisec); void StopIntervalTimer(void); void OnDialogItemAction(wxCommandEvent &event); + void OnTextUpdated(wxCommandEvent &event); + void OnEnterProcessedOnText(wxCommandEvent &event); + void OnKillFocusOnText(wxFocusEvent &event); + void OnTimerEvent(wxTimerEvent &event); void OnDefaultButtonPressed(wxCommandEvent &event); void OnSize(wxSizeEvent &event); -- 2.11.0