23 #include "wx/wxprec.h"
31 #include "ObjCryst/wxCryst/wxRefinableObj.h"
33 #include "ObjCryst/wxCryst/wxRefinableObj.h"
34 #include "ObjCryst/Quirks/VFNStreamFormat.h"
36 #include "ObjCryst/RefinableObj/GlobalOptimObj.h"
39 #include "ObjCryst/ObjCryst/Atom.h"
40 #include "ObjCryst/ObjCryst/Crystal.h"
41 #include "ObjCryst/ObjCryst/DiffractionDataSingleCrystal.h"
42 #include "ObjCryst/ObjCryst/PowderPattern.h"
43 #include "ObjCryst/ObjCryst/ScatteringPower.h"
44 #include "ObjCryst/ObjCryst/ZScatterer.h"
45 #include "ObjCryst/ObjCryst/ScatteringCorr.h"
46 #include "ObjCryst/ObjCryst/ReflectionProfile.h"
71 static const long ID_WXFIELD_REFPAR =WXCRYST_ID();
72 static const long ID_WXFIELD_REFPAR_FIXBUTTON =WXCRYST_ID();
73 static const long ID_WXFIELD_REFPAR_LIMITEDBUTTON=WXCRYST_ID();
74 static const long ID_REFPAR_POPUP_SET_LIMITS =WXCRYST_ID();
76 BEGIN_EVENT_TABLE(WXFieldRefPar,wxWindow)
77 EVT_TEXT_ENTER(ID_WXFIELD, WXFieldRefPar::OnEnter)
78 EVT_TEXT(ID_WXFIELD, WXFieldRefPar::OnText)
79 EVT_CHECKBOX(ID_WXFIELD_REFPAR_FIXBUTTON, WXFieldRefPar::OnToggleFix)
80 EVT_CHECKBOX(ID_WXFIELD_REFPAR_LIMITEDBUTTON,WXFieldRefPar::OnToggleLimited)
81 EVT_RIGHT_DOWN( WXFieldRefPar::OnPopupMenu)
82 EVT_MENU(ID_REFPAR_POPUP_SET_LIMITS, WXFieldRefPar::OnPopupMenuChoice)
85 WXFieldRefPar::WXFieldRefPar(wxWindow *parent,const
string& label,
86 RefinablePar *par, const
int hsize,
87 const
bool enableFixButton, const
bool enableLimitedButton):
88 WXField(parent,label,ID_WXFIELD_REFPAR),mValue(0.),mpRefPar(par),mIsSelfUpdating(false),mFormat(_T("%8f"))
90 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::WXFieldName():End",6)
93 this->SetLabel(label+
"R");
94 mpButtonFix=
new wxCheckBox(
this,ID_WXFIELD_REFPAR_FIXBUTTON,_T(
"L"),wxDefaultPosition, wxDefaultSize);
96 mpButtonFix->SetToolTip(_T(
"Check this box to enable optimizing this parameter.\n")
97 _T(
"(some parameters may be automatically fixed for global optimization)"));
98 mpSizer->Add(mpButtonFix,0,wxALIGN_CENTER);
100 if(enableLimitedButton)
102 mpButtonLimited=
new wxCheckBox(
this,ID_WXFIELD_REFPAR_LIMITEDBUTTON,_T(
""),
103 wxDefaultPosition, wxSize(16,20));
104 mpButtonLimited->SetToolTip(_T(
"Check this box to use limits for this parameter"));
105 mpSizer->Add(mpButtonLimited,0,wxALIGN_CENTER);
106 }
else mpButtonLimited=0;
108 mpField=
new wxTextCtrl(
this,ID_WXFIELD,_T(
""),
109 wxDefaultPosition,wxSize(hsize,-1),wxTE_PROCESS_ENTER,
110 wxTextValidator(wxFILTER_NUMERIC));
111 mpSizer->Add(mpField,0,wxALIGN_CENTER);
115 mpRefPar->WXNotifyDelete();
118 void WXFieldRefPar::OnEnter(wxCommandEvent & WXUNUSED(event))
120 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::OnEnter()",6)
125 if(
true==mIsSelfUpdating)
return;
126 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::OnEnter()",6)
127 if(spLastWXFieldInputNotValidated!=
this)
130 spLastWXFieldInputNotValidated=
this;
136 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::OnToggleFix()",6)
137 if(0!=mpButtonFix) mpRefPar->SetIsFixed(!(mpButtonFix->GetValue()));
143 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::OnToggleLimited()",6)
144 if(0!=mpButtonLimited) mpRefPar->SetIsLimited(mpButtonLimited->GetValue());
150 static wxMenu sWXFieldRefParPopupMenu;
151 static bool needInitMenu=
true;
155 sWXFieldRefParPopupMenu.Append(ID_REFPAR_POPUP_SET_LIMITS, _T(
"Change Limits"));
157 this->PopupMenu(&sWXFieldRefParPopupMenu,0,0);
162 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::OnPopupMenuChoice()",7)
163 if(event.GetId()== ID_REFPAR_POPUP_SET_LIMITS)
169 wxTextEntryDialog limitDialog(
this,_T(
"Enter the minimum value"),
170 _T(
"Minimum"),str,wxOK | wxCANCEL);
171 if(wxID_OK!=limitDialog.ShowModal())
173 VFN_DEBUG_EXIT(
"WXZScatterer::OnMenuSetLimits():Cancelled",6)
176 limitDialog.GetValue().ToDouble(&min);
181 wxTextEntryDialog limitDialog(
this,_T(
"Enter the maximum value"),
182 _T(
"Maximum"),str,wxOK | wxCANCEL);
183 if(wxID_OK!=limitDialog.ShowModal())
185 VFN_DEBUG_EXIT(
"WXZScatterer::OnMenuSetLimits():Cancelled",6)
188 limitDialog.GetValue().ToDouble(&max);
192 wxMessageDialog dumbUser(
this,_T(
"max <= min !!!"),
193 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
194 dumbUser.ShowModal();
199 mpRefPar->SetIsLimited(
true);
206 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::CrystUpdate()",6)
208 bool needUpdate=
false;
209 if(wxThread::IsMain())
211 if(mpRefPar->
IsUsed()!=this->IsShown()) needUpdate=
true;
212 if(0!=mpButtonFix)
if(mpButtonFix->GetValue()==mpRefPar->IsFixed()) needUpdate=
true;
213 if(0!=mpButtonLimited)
if(mpButtonLimited->GetValue()==mpRefPar->IsLimited()) needUpdate=
true;
230 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::UpdateUI("<<lock<<
")"<<
"MainThread="<<wxThread::IsMain(),3)
237 if(
false==mpRefPar->
IsUsed()) this->Show(
false);
238 else this->Show(
true);
250 mIsSelfUpdating=
true;
251 mpField->SetValue(tmp);
252 mIsSelfUpdating=
false;
253 if(0!=mpButtonFix) mpButtonFix->SetValue(!(mpRefPar->IsFixed()));
254 if(0!=mpButtonLimited) mpButtonLimited->SetValue(mpRefPar->IsLimited());
261 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::Revert()",6)
262 wxMutexLocker mlock(
mMutex);
268 VFN_DEBUG_MESSAGE(
"WXFieldRefPar::ValidateUserInput()",6)
269 wxMutexLocker mlock(
mMutex);
271 wxString s=mpField->GetValue();
296 WXField(parent,option->GetName(),field_id),
297 mChoice(-1),mChoiceOld(-1),mpOption(option),mpList(0)
299 wxString choices[20];
300 for(
int i=0;i<mpOption->GetNbChoice();i++)
301 choices[i]=wxString::FromAscii(mpOption->GetChoiceName(i).c_str());
303 mpList=
new wxChoice(
this,ID_WXFIELD,wxDefaultPosition,wxDefaultSize,
304 mpOption->GetNbChoice(),choices);
305 mpSizer->Add(mpList,0,wxALIGN_CENTER);
307 WXFieldOption::~WXFieldOption()
309 mpOption->WXNotifyDelete();
313 if(mChoice==mpList->GetSelection())
return;
315 mChoice=mpList->GetSelection();
316 mpOption->SetChoice(mChoice);
321 VFN_DEBUG_MESSAGE(
"WXFieldOption::CrystUpdate("<<uui<<lock<<
")",6)
323 if(mChoice==mpOption->GetChoice())
328 mChoice=mpOption->GetChoice();
335 VFN_DEBUG_MESSAGE(
"WXFieldOption::UpdateUI("<<lock<<
")"<<
"MainThread="<<wxThread::IsMain(),6)
342 mpList->SetSelection(mChoice);
349 wxMutexLocker mlock(
mMutex);
366 WXCrystObj(parent,wxHORIZONTAL,false),mpRegistry(reg)
368 VFN_DEBUG_ENTRY(
"WXCrystRegistry::WXCrystRegistry(wxWindow*)",6)
369 #ifdef VFN_CRYST_MUTEX
370 cout <<
"new CrystMutex("<<&
mMutex<<
")for WXCrystRegistry:"<<reg->GetName()<<endl;
372 wxStaticText*
mpLabel=
new wxStaticText(
this,-1,wxString::FromAscii(reg->GetName().c_str()));
373 mpSizer->Add(mpLabel,0,wxALIGN_LEFT);
374 mpLabel->SetForegroundColour(wxColour(0,0,255));
375 VFN_DEBUG_EXIT(
"WXCrystRegistry::WXCrystRegistry(wxWindow*):End",6)
377 template<
class T> WXRegistry<T>::~WXRegistry()
379 mpRegistry->WXNotifyDelete();
380 #ifdef VFN_CRYST_MUTEX
381 cout <<
"Deleting CrystMutex("<<&mMutex<<
")for WXCrystRegistry:"<<mpRegistry->GetName()<<endl;
384 template<
class T>
void WXRegistry<T>::Add(WXCrystObjBasic *obj)
386 VFN_DEBUG_ENTRY(
"WXCrystRegistry::AddWXCrystObj(WXCrystObj*)",6)
388 obj->Show(mIsExpanded);
390 VFN_DEBUG_EXIT("WXCrystRegistry::AddWXCrystObj(WXCrystObj*)",6)
392 template<class T>
void WXRegistry<T>::Remove(WXCrystObjBasic *obj)
395 VFN_DEBUG_ENTRY(
"WXCrystRegistry::RemoveWXCrystObj(WXCrystObj*)",6)
399 this->BottomLayout(0);
400 VFN_DEBUG_EXIT("WXCrystRegistry::RemoveWXCrystObj(WXCrystObj*):End",6)
403 template<class T>
bool WXRegistry<T>::OnChangeName(const
int id)
405 VFN_DEBUG_MESSAGE(
"WXRegistry<T>::OnChangeName()",6)
406 if(
id==ID_WXOBJ_NAME)
408 mpRegistry->SetName(mpWXTitle->GetValue());
438 const string &message,
int &choice)
440 wxString* choices=
new wxString[reg.
GetNb()];
441 for(
int i=0;i<reg.
GetNb();i++)
442 *(choices+i)=wxString::FromAscii((reg.
GetObj(i).GetClassName()+
":"+reg.
GetObj(i).GetName()).c_str());
443 #if wxCHECK_VERSION( 2, 9, 4 )
444 wxSingleChoiceDialog dialog
445 (parent,wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.
GetNb(),choices,(
void**)NULL,wxOK | wxCANCEL);
447 wxSingleChoiceDialog dialog
448 (parent,wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.
GetNb(),choices,NULL,wxOK | wxCANCEL);
450 dialog.SetSize(300,300);
451 if(wxID_OK!=dialog.ShowModal())
457 choice=dialog.GetSelection();
458 return &(reg.
GetObj(choice));
461 template RefinableObj*
467 template ScatteringPower*
469 template ScatteringPowerAtom*
471 const string &,
int &);
474 template PowderPattern*
476 template PowderPatternComponent*
478 const string&,
int &);
479 template DiffractionDataSingleCrystal*
481 const string &,
int &);
482 template OptimizationObj*
484 template XMLCrystTag*
489 wxWindow*parent,
const string &message
492 wxString* choices=
new wxString[reg.
GetNb()];
493 for(
int i=0;i<reg.
GetNb();i++)
494 *(choices+i)=wxString::FromAscii((reg.
GetObj(i).GetClassName()+
":"+reg.
GetObj(i).GetName()).c_str());
495 #if wxCHECK_VERSION( 2, 9, 4 )
496 wxSingleChoiceDialog dialog
497 (parent,wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.
GetNb(),choices,(
void**)NULL,wxOK | wxCANCEL);
499 wxSingleChoiceDialog dialog
500 (parent,wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.
GetNb(),choices,NULL,wxOK | wxCANCEL);
502 dialog.SetSize(300,300);
503 if(wxID_OK!=dialog.ShowModal())
509 choice=dialog.GetSelection();
510 return &(reg.
GetObj(choice));
513 template const RefinableObj*
516 template const Crystal*
519 template const Scatterer*
522 template const ScatteringPower*
524 const string &,
int &);
526 template const ScatteringPowerAtom*
528 const string &,
int &);
530 template const ZAtom*
533 template const PowderPattern*
535 const string &,
int &);
537 template const PowderPatternComponent*
539 const string&,
int &);
541 template const DiffractionDataSingleCrystal*
543 const string &,
int &);
545 template const OptimizationObj*
547 const string &,
int &);
549 template const XMLCrystTag*
551 const string &,
int &);
558 BEGIN_EVENT_TABLE(WXRefinableObj,wxWindow)
559 EVT_MENU(ID_REFOBJ_MENU_OBJ_SAVE, WXRefinableObj::OnMenuSave)
560 EVT_MENU(ID_REFOBJ_MENU_OBJ_LOAD, WXRefinableObj::OnMenuLoad)
561 EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
562 EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
563 EVT_MENU(ID_REFOBJ_MENU_PAR_RANDOMIZE, WXRefinableObj::OnMenuParRandomize)
564 EVT_UPDATE_UI(ID_CRYST_UPDATEUI, WXRefinableObj::OnUpdateUI)
567 WXRefinableObj::WXRefinableObj(wxWindow* parent, RefinableObj*obj):
568 WXCrystObj(parent,wxHORIZONTAL),mpRefinableObj(obj)
570 VFN_DEBUG_ENTRY(
"WXRefinableObj::WXRefinableObj():"<<obj->GetName(),6)
571 #ifdef VFN_CRYST_MUTEX
572 cout <<
"new CrystMutex("<<&mMutex<<
")for :"<<obj->GetClassName()<<
":"<<obj->GetName()<<endl;
574 mpWXTitle->SetLabel(mpRefinableObj->GetClassName());
577 mpMenuBar=
new WXCrystMenuBar(
this,
this);
579 mpSizer->Add(mpMenuBar);
580 mList.Add(mpMenuBar);
582 for(
unsigned int i=0;i<mpRefinableObj->GetNbOption();i++)
584 VFN_DEBUG_MESSAGE(
"WXRefinableObj::WXRefinableObj():Adding option "<<i,6)
585 WXCrystObjBasic *opt=mpRefinableObj->GetOption(i).WXCreate(this);
586 mpSizer->Add(opt,0,wxALIGN_LEFT);
591 VFN_DEBUG_EXIT("WXRefinableObj::WXRefinableObj()",6)
594 WXRefinableObj::~WXRefinableObj()
596 VFN_DEBUG_MESSAGE(
"WXRefinableObj::~WXRefinableObj():"<<mpRefinableObj->GetName(),6)
597 mpRefinableObj->WXNotifyDelete();
598 #ifdef VFN_CRYST_MUTEX
599 cout <<
"Deleting CrystMutex("<<&mMutex<<
")for :"<<mpRefinableObj->GetClassName()
600 <<
":"<<mpRefinableObj->GetName()<<endl;
606 VFN_DEBUG_ENTRY(
"WXRefinableObj::CrystUpdate("<<uui<<lock<<
"):"<<mpRefinableObj->
GetName(),6)
612 if(
true==wxThread::IsMain()) this->
UpdateUI(lock);
615 wxUpdateUIEvent event(ID_CRYST_UPDATEUI);
616 wxPostEvent(
this,event);
619 VFN_DEBUG_EXIT(
"WXRefinableObj::CrystUpdate():"<<mpRefinableObj->
GetName(),6)
624 VFN_DEBUG_MESSAGE(
"WXRefinableObj::OnChangeName()",6)
625 if(
id==ID_WXOBJ_NAME)
627 VFN_DEBUG_MESSAGE(
"WXRefinableObj::OnChangeName():Changing RefinableObj Name",6)
634 void WXRefinableObj::OnMenuSave(wxCommandEvent & WXUNUSED(event))
636 VFN_DEBUG_MESSAGE(
"WXRefinableObj::OnButtonSave()",6)
637 wxFileDialog save(this,_T("Choose a file"),_T(""),_T(""),_T("*.xml"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
638 if(save.ShowModal() != wxID_OK) return;
640 ofstream out(save.GetPath().ToAscii());
648 void WXRefinableObj::OnMenuLoad(wxCommandEvent & WXUNUSED(event))
650 VFN_DEBUG_MESSAGE(
"WXRefinableObj::OnButtonLoad()",6)
651 wxFileDialog *open= new wxFileDialog(this,_T("Choose a file"),_T(""),_T(""),_T("*.xml"),
652 wxFD_OPEN | wxFD_FILE_MUST_EXIST);
653 if(open->ShowModal() != wxID_OK) return;
655 ifstream fin(open->GetPath().ToAscii());
658 XMLCrystTag tag(fin);
665 void WXRefinableObj::OnMenuFixAllPar(wxCommandEvent & WXUNUSED(event))
671 void WXRefinableObj::OnMenuUnFixAllPar(wxCommandEvent & WXUNUSED(event))
677 void WXRefinableObj::OnMenuParRandomize(wxCommandEvent & WXUNUSED(event))
683 void WXRefinableObj::OnUpdateUI(wxUpdateUIEvent& event)
690 VFN_DEBUG_ENTRY(
"WXRefinableObj::UpdateUI("<<lock<<
")"<<
"MainThread="<<wxThread::IsMain()<<
":"<<mpRefinableObj->
GetName(),6)
702 VFN_DEBUG_EXIT(
"WXRefinableObj::UpdateUI()"<<mpRefinableObj->
GetName(),6)
T & GetObj(const unsigned int i)
Get object #i in the registry.
REAL GetHumanMin() const
Get the minimum value allowed (if limited)
T * WXDialogChooseFromRegistry(ObjRegistry< T > ®, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
void SetValue(const string &)
This actually posts an UpdateUI event, so that it is safe to call it from a non-graphic thread...
void OnToggleLimited(wxCommandEvent &WXUNUSED(event))
Toggle the 'limited' status of the parameter.
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
WX representation of a RefObj option. This displays the names of the different choices.
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
long GetNb() const
Get the index of an object in the registry, from its name Warning: it can change if an object is remo...
bool IsBeingRefined() const
Is the object being refined ? (Can be refined by one algorithm at a time only.)
void FixAllPar()
Fix All parameters.
A field for a RefinablePar.
void OnPopupMenuChoice(wxCommandEvent &event)
Opens the popu menu, to allow changing limits.
bool mNeedUpdateUI
Do we need to update the display ?
void OnToggleFix(wxCommandEvent &WXUNUSED(event))
Toggle the 'fixed' status of the parameter.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
WXFieldName * mpWXTitle
The title.
This displays all components of a ObjCryst++ Registry.
This is the abstract base class for all fields, wether they contain a floating-point parameter...
wxString mFormat
Format to be used, default = _T("%8f")
const REAL & GetHumanValue() const
Current value of parameter, scaled if necessary (for angles) to a human-understandable value...
void OnPopupMenu(wxMouseEvent &event)
Opens the popu menu, to allow changing limits.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
const string GetValue() const
Get the current name.
void OnText(wxCommandEvent &WXUNUSED(event))
Records when text is entered (either from self-updating or user input)
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
~WXFieldRefPar()
When a new value is entered (must type it and then hit the 'enter' key).
wxBoxSizer * mpSizer
The horizontal sizer in which the title, button, fields, are put.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects)...
virtual void RandomizeConfiguration()
Randomize Configuration (before a global optimization).
virtual void ValidateUserInput()
This function shall be called when a new value has been entered.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
void SetFormat(const wxString &format)
Set Format.
void SetHumanValue(const REAL &)
Current value of parameter, scaled if necessary (for angles) to a human-understandable value...
REAL GetHumanMax() const
Get the maximum value allowed (if limited)
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
void SetHumanMin(const REAL)
Set the minimum value allowed (if limited)
wxStaticText * mpLabel
The label.
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the choice field.
WXField * spLastWXFieldInputNotValidated
This pointer records the last wxField in which something was enetered, so that it can be validated wh...
virtual const string & GetName() const
Name of the object.
void OnChoice(wxCommandEvent &WXUNUSED(event))
When a new value is entered.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
void SetHumanMax(const REAL)
Get the maximum value allowed (if limited)
bool IsUsed() const
Is the parameter used (if not, it is simply irrelevant in the model) ?
virtual void ValidateUserInput()
Does nothing. Any user input is directly validated (OnChoice).
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the entry field.
void UnFixAllPar()
UnFix All parameters.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual void SetName(const string &name)
Name of the object.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.