FOX/ObjCryst++  1.10.X (development)
wxCryst.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 //#include <sstream> //for stringstream
20 #include <fstream>
21 
22 // wx headers, with or without precompilation
23 #include "wx/wxprec.h"
24 #ifdef __BORLANDC__
25  #pragma hdrstop
26 #endif
27 #ifndef WX_PRECOMP
28  #include "wx/wx.h"
29 #endif
30 
31 #include "ObjCryst/wxCryst/wxCryst.h"
32 
33 //#include "ObjCryst/Quirks/VFNStreamFormat.h"
34 #include "ObjCryst/Quirks/VFNDebug.h"
35 
36 //#include "ObjCryst/RefinableObj/GlobalOptimObj.h"
37 
38 //Fixes for Cygwin; where do those stupid macros come from ? Somewhere in wxMSW headers
39 #ifdef max
40 #undef max
41 #endif
42 #ifdef min
43 #undef min
44 #endif
45 #ifdef DrawText
46 #undef DrawText
47 #endif
48 
49 namespace ObjCryst
50 {
51 std::map<wxWindowID,std::pair<wxPoint,wxSize> > gvWindowPosition;
52 
53 wxMultiChoiceDialog_ListBox::wxMultiChoiceDialog_ListBox(wxWindow* parent, const wxString& message, const wxString& caption,
54  int n, const wxString* choices):
55 wxDialog(parent,-1,_T("Choose the molecule's atoms"),wxDefaultPosition,wxSize(300,400),wxCAPTION|wxSTAY_ON_TOP),
56 mListBox(this,-1,wxDefaultPosition,wxSize(250,350),n,choices,wxLB_MULTIPLE)
57 {
58  wxBoxSizer *sizer=new wxBoxSizer(wxVERTICAL);
59  sizer->Add(&mListBox);
60  sizer->Add(this->CreateSeparatedButtonSizer(wxOK | wxCANCEL));
61  this->SetSizer(sizer);
62  sizer->SetSizeHints(this);
63  sizer->Fit(this);
64 }
65 
66 wxArrayInt wxMultiChoiceDialog_ListBox::GetSelections() const
67 {
68  wxArrayInt choice;
69  mListBox.GetSelections(choice);
70  return choice;
71 }
72 
74 //
75 // Unique ID for menus incrementer
76 //
78 WXCRYST_ID::WXCRYST_ID(){mIndex=mCounter++;}
79 WXCRYST_ID::operator long(){return mIndex;}
80 long WXCRYST_ID::mCounter=wxID_HIGHEST+100;
81 
82 #ifdef VFN_CRYST_MUTEX
83 //
85 // Mutex
86 //
88 CrystMutex::CrystMutex():mNbLock(0){}
89 CrystMutex::~CrystMutex()
90 {
91  cout <<"~CrystMutex("<<this<<"), Total number of Locks="<<mNbLock<<endl;
92 }
93 wxMutexError CrystMutex::Lock()
94 {
95  #if 1
96  return this->wxMutex::Lock();
97  #else
98  cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<")::Lock() ?"<<endl;
99  wxMutexError res=this->wxMutex::TryLock();
100  if(res==wxMUTEX_NO_ERROR)
101  cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<")::Lock()-OK"<<endl;
102  if(res==wxMUTEX_DEAD_LOCK)
103  {
104  cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<")::Lock()-DEADLOCK!"<<endl;
105  exit(0);
106  }
107  if(res==wxMUTEX_BUSY)
108  {
109  cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<")::Lock()-Busy?"<<endl;
110  res=this->wxMutex::Lock();
111  cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<")::Lock()-OK2"<<endl;
112  }
113  return res;
114  #endif
115 }
116 wxMutexError CrystMutex::Unlock()
117 {
118  //cout <<"Thread:"<<wxThread::IsMain()<<":CrystMutex("<<this<<"::Unlock()"<<endl;
119  mNbLock++;
120  return this->wxMutex::Unlock();
121 }
122 #endif
123 
125 //
126 // WXCrystObjBasic
127 //
129 WXCrystObjBasic::WXCrystObjBasic(wxWindow* parent):
130 wxWindow(parent,-1),mWXCrystParent(0),mIsShown(true),mNeedUpdateUI(true)
131 {
132  VFN_DEBUG_MESSAGE("WXCrystObjBasic::WXCrystObjBasic() at "<<this,6)
133  if(parent !=0) mWXCrystParent=dynamic_cast<WXCrystObjBasic*>(parent);
134 #ifdef __WXGTK__
135 #ifndef __WXGTK20__
136  // Why is this necessary for GTK 1.2 ? wxWidgets 2.6.3
137  this->SetBackgroundColour(wxColour(240,240,240));// wxLIGHT_GREY
138 #endif
139 #endif
140  VFN_DEBUG_MESSAGE("WXCrystObjBasic::WXCrystObjBasic():End",6)
141 }
142 
144 {
145  // Every time we destroy a widget, validate all input to make sure the destroyed
146  // widget does not have some unread info.
148  set<WXCrystObjBasicList*> vpList=mvpList;//use a copy
149  for(set<WXCrystObjBasicList*>::iterator pos=vpList.begin();pos!=vpList.end();++pos)
150  (*pos)->Remove(this);
151 }
152 
153 void WXCrystObjBasic::BottomLayout(WXCrystObjBasic *pChild)
154 {
155  VFN_DEBUG_ENTRY("WXCrystObjBasic::BottomLayout(...)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
156  wxTheApp->GetTopWindow()->SendSizeEvent();
157  VFN_DEBUG_EXIT("WXCrystObjBasic::BottomLayout(...)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
158 }
159 void WXCrystObjBasic::AddChild(WXCrystObjBasic *pChild, bool doBottomLayout)
160 {
161  VFN_DEBUG_ENTRY("WXCrystObjBasic::AddChild(...)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
162  wxSizer *pSizer=this->GetSizer();
163  if(pSizer!=0)
164  {
165  pSizer->Add(pChild);
166  }
167  if(doBottomLayout) wxTheApp->GetTopWindow()->SendSizeEvent();
168  VFN_DEBUG_EXIT("WXCrystObjBasic::AddChild(...)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
169 }
170 
173 bool WXCrystObjBasic::Layout()
174 {
175  //static unsigned long ct=0;
176  //cout<<"WXCrystObjBasic::Layout() #"<<++ct<<endl;
177  return wxWindow::Layout();
178 }
179 void WXCrystObjBasic::SetToolTip(const wxString& tip){this->wxWindow::SetToolTip(tip);}
180 
182 //
183 // WXCrystObjBasicList
184 //
187 {}
188 
190 {
191  set<WXCrystObjBasic*> vpWXCrystObj=mvpWXCrystObj;
192  for(set<WXCrystObjBasic*>::iterator pos=vpWXCrystObj.begin();pos!=vpWXCrystObj.end();pos++)
193  (*pos)->RemovedFromList(this);
194  mvpWXCrystObj.clear();
195 }
196 
197 unsigned int WXCrystObjBasicList::GetNb()const {return mvpWXCrystObj.size();}
198 
200 {
201  VFN_DEBUG_MESSAGE("WXCrystObjBasicList::Add()",6)
202  win->AddedToList(this);
203  mvpWXCrystObj.insert(win);
204 }
205 
207 {
208  VFN_DEBUG_MESSAGE("WXCrystObjBasicList::Remove():"<<win,6)
209  mvpWXCrystObj.erase(win);
210  win->RemovedFromList(this);
211 }
212 
214 {
215  VFN_DEBUG_MESSAGE("WXCrystObjBasicList::Show(bool)",3)
216  for(set<WXCrystObjBasic*>::iterator pos=mvpWXCrystObj.begin();pos!=mvpWXCrystObj.end();pos++)
217  (*pos)->Show(show);
218  //this->CrystUpdate();
219  VFN_DEBUG_MESSAGE("WXCrystObjBasicList::Show(bool):End",3)
220  return true;
221 }
222 
223 void WXCrystObjBasicList::CrystUpdate(const bool updateUI,const bool mutexlock)
224 {
225  VFN_DEBUG_ENTRY("WXCrystObjBasicList::CrystUpdate()",5)
226  for(set<WXCrystObjBasic*>::iterator pos=mvpWXCrystObj.begin();pos!=mvpWXCrystObj.end();pos++)
227  {
228  VFN_DEBUG_MESSAGE("WXCrystObjBasicList::CrystUpdate("<<updateUI<<mutexlock<<")@"<<*pos,5)
229  (*pos)->CrystUpdate(updateUI,mutexlock);
230  }
231  VFN_DEBUG_EXIT("WXCrystObjBasicList::CrystUpdate()",5)
232 }
233 void WXCrystObjBasicList::UpdateUI(const bool mutexlock)
234 {
235  VFN_DEBUG_ENTRY("WXCrystObjBasicList::UpdateUI("<<mutexlock<<")"<<"MainThread="<<wxThread::IsMain(),5)
236  for(set<WXCrystObjBasic*>::iterator pos=mvpWXCrystObj.begin();pos!=mvpWXCrystObj.end();pos++)
237  (*pos)->UpdateUI(mutexlock);
238  VFN_DEBUG_EXIT("WXCrystObjBasicList::UpdateUI()",5)
239 }
240 void WXCrystObjBasicList::Enable(bool enable)
241 {
242  for(set<WXCrystObjBasic*>::iterator pos=mvpWXCrystObj.begin();pos!=mvpWXCrystObj.end();pos++)
243  (*pos)->Enable(enable);
244 }
245 
247 //
248 // For the automatic validation of user input
249 //
256 
258 {
259  if(0==spLastWXFieldInputNotValidated) return;
260  VFN_DEBUG_ENTRY("WXCrystValidateAllUserInput()...",6)
261  static WXField *pField;
263  spLastWXFieldInputNotValidated=0;//avoid loops
264  pField->ValidateUserInput();
265  VFN_DEBUG_EXIT("WXCrystValidateAllUserInput()...",6)
266 }
267 
269 //
270 // WXField
271 //
273 WXField::WXField(wxWindow *parent,const string& label,const int id):
274 WXCrystObjBasic(parent),mId(id)
275 {
276  VFN_DEBUG_ENTRY("WXField::WXField()",6)
277  mpSizer = new wxBoxSizer(wxHORIZONTAL);
278  mpLabel=new wxStaticText(this,-1,wxString::FromAscii(label.c_str()));
279  mpSizer->Add(mpLabel,0,wxALIGN_CENTER);
280  this->SetSizer(mpSizer);
281  //mpSizer->SetSizeHints(this);
282  //this->Layout();
283  VFN_DEBUG_EXIT("WXField::WXField()",6)
284 }
285 void WXField::SetLabel(const string& s)
286 {
287  VFN_DEBUG_MESSAGE("WXField::SetLabel()",3)
288  mpLabel->SetLabel(wxString::FromAscii(s.c_str()));
289  mpLabel->Layout();
290 }
291 bool WXField::SetForegroundColour(const wxColour& colour)
292 {
293  VFN_DEBUG_MESSAGE("WXField::SetLabel()",3)
294  mpLabel->SetForegroundColour(colour);
295  return this->wxWindow::SetForegroundColour(colour);
296 }
297 
298 void WXField::SetSize(int width, int height)
299 {}
301 //
302 // WXFieldString
303 //
305 BEGIN_EVENT_TABLE(WXFieldString,wxWindow)
306  EVT_TEXT_ENTER(ID_WXFIELD, WXFieldString::OnEnter)
307  EVT_TEXT( ID_WXFIELD, WXFieldString::OnText)
308 END_EVENT_TABLE()
309 
310 WXFieldString::WXFieldString(wxWindow *parent,string& st,
311  const int id,const int hsize, bool isEditable):
312 WXField(parent,"",id),mpString(&st),mValue(st),mIsSelfUpdating(false)
313 {
314  VFN_DEBUG_MESSAGE("WXFieldString::WXFieldName():End",6)
315 
316  if(true==isEditable)
317  mpField=new wxTextCtrl(this,ID_WXFIELD,wxString::FromAscii(mValue.c_str()),
318  wxDefaultPosition,wxSize(hsize,-1),wxTE_PROCESS_ENTER,
319  wxTextValidator(wxFILTER_ASCII));
320  else
321  mpField=new wxTextCtrl(this,ID_WXFIELD,wxString::FromAscii(mValue.c_str()),
322  wxDefaultPosition,wxSize(hsize,-1),wxTE_READONLY,
323  wxTextValidator(wxFILTER_ASCII));
324 
325  mpSizer->Add(mpField,0,wxALIGN_CENTER);
326  mpSizer->SetSizeHints(this);
327  this->Layout();
328 }
329 
330 void WXFieldString::OnEnter(wxCommandEvent & WXUNUSED(event))
331 {
332  VFN_DEBUG_MESSAGE("WXFieldString::OnEnter()",6)
334 }
335 void WXFieldString::OnText(wxCommandEvent & WXUNUSED(event))
336 {
337  if(true==mIsSelfUpdating) return;
338  VFN_DEBUG_MESSAGE("WXFieldString::OnText():",6)
339  if(spLastWXFieldInputNotValidated!=this)
340  {
342  spLastWXFieldInputNotValidated=this;
343  }
344 }
345 
346 void WXFieldString::SetValue(const string&s)
347 {
348  VFN_DEBUG_ENTRY("WXFieldString::SetValue()",3)
349  wxMutexLocker mlock(mMutex);
350  if(mValue==s)
351  {
352  VFN_DEBUG_EXIT("WXFieldString::SetValue(): string unchanged",3)
353  return;
354  }
355  mValue=s;
356  mNeedUpdateUI=true;
357  VFN_DEBUG_EXIT("WXFieldString::SetValue()",3)
358 }
359 
360 const string WXFieldString::GetValue() const
361 {
362  VFN_DEBUG_MESSAGE("WXFieldString::GetValue()"<<mValue<<":"<<mpField->GetValue(),6)
363  return mValue;
364 }
365 void WXFieldString::CrystUpdate(const bool uui,const bool lock)
366 {
367  VFN_DEBUG_ENTRY("WXFieldString::CrystUpdate()",3)
368  if(lock) mMutex.Lock();
369  if(mValue==*mpString)
370  {
371  if(lock)mMutex.Unlock();
372  return;
373  }
375  mValue=*mpString;
376  mNeedUpdateUI=true;
377  if(lock) mMutex.Unlock();
378  if(uui) if(true==wxThread::IsMain()) this->UpdateUI(lock);
379  VFN_DEBUG_EXIT("WXFieldString::CrystUpdate()",3)
380 }
381 void WXFieldString::UpdateUI(const bool lock)
382 {
383  if(lock) mMutex.Lock();
384  if(mNeedUpdateUI==false)
385  {
386  if(lock) mMutex.Unlock();
387  return;
388  }
389  VFN_DEBUG_ENTRY("WXFieldString::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),4)
390  mIsSelfUpdating=true;
391  mpField->SetValue(wxString::FromAscii(mValue.c_str()));
392  mIsSelfUpdating=false;
393  mNeedUpdateUI=false;
394  if(lock) mMutex.Unlock();
395  VFN_DEBUG_EXIT("WXFieldString::UpdateUI()",4)
396 }
398 {
399  VFN_DEBUG_MESSAGE("WXFieldString::Revert()",3)
400  wxMutexLocker mlock(mMutex);
402  mNeedUpdateUI=true;
403 }
405 {
406  VFN_DEBUG_MESSAGE("WXFieldString::ValidateUserInput()",6)
407  //:TODO: Check that the object is not busy (input should be frozen)
408  wxMutexLocker mlock(mMutex);
410  mValue=mpField->GetValue().ToAscii();
411  *mpString=mValue;
412 }
413 void WXFieldString::SetSize(int width, int height)
414 {
415  mpField->SetSize(width,height);
416  //wxTheApp->GetTopWindow()->SendSizeEvent();
417 }
418 
419 void WXFieldString::SetToolTip(const wxString& tip){mpField->SetToolTip(tip);}
420 
422 //
423 // WXFieldName
424 //
426 BEGIN_EVENT_TABLE(WXFieldName,wxWindow)
427  EVT_TEXT_ENTER(ID_WXFIELD, WXFieldName::OnEnter)
428  EVT_TEXT( ID_WXFIELD, WXFieldName::OnText)
429 END_EVENT_TABLE()
430 
431 WXFieldName::WXFieldName(wxWindow *parent,const string& label, WXCrystObj* owner,
432  const int id,const int hsize, bool isEditable):
433 WXField(parent,label,id),mpWXObj(owner),mValue(""),mIsSelfUpdating(false)
434 {
435  VFN_DEBUG_ENTRY("WXFieldName::WXFieldName()",6)
436  if(true==isEditable)
437  mpField=new wxTextCtrl(this,ID_WXFIELD,wxString::FromAscii(mValue.c_str()),
438  wxDefaultPosition,wxSize(hsize,-1),wxTE_PROCESS_ENTER,
439  wxTextValidator(wxFILTER_ASCII));
440  else
441  mpField=new wxTextCtrl(this,ID_WXFIELD,wxString::FromAscii(mValue.c_str()),
442  wxDefaultPosition,wxSize(hsize,-1),wxTE_READONLY,
443  wxTextValidator(wxFILTER_ASCII));
444 
445  mpSizer->Add(mpField,0,wxALIGN_CENTER);
446  //mpSizer->SetSizeHints(this);
447  this->Layout();
448  VFN_DEBUG_EXIT("WXFieldName::WXFieldName()",6)
449 }
450 
451 void WXFieldName::OnEnter(wxCommandEvent & WXUNUSED(event))
452 {
453  VFN_DEBUG_MESSAGE("WXFieldName::OnEnter()",6)
455 }
456 void WXFieldName::OnText(wxCommandEvent & WXUNUSED(event))
457 {
458  if(true==mIsSelfUpdating) return;
459  VFN_DEBUG_MESSAGE("WXFieldName::OnText():",6)
460  if(spLastWXFieldInputNotValidated!=this)
461  {
463  spLastWXFieldInputNotValidated=this;
464  }
465 }
466 
467 void WXFieldName::SetValue(const string&s)
468 {
469  VFN_DEBUG_ENTRY("WXFieldName::SetValue()",3)
470  wxMutexLocker mlock(mMutex);
471  if(mValue==s)
472  {
473  VFN_DEBUG_EXIT("WXFieldName::SetValue():name unchanged",3)
474  return;
475  }
476  mValue=s;
477  mNeedUpdateUI=true;
478  VFN_DEBUG_EXIT("WXFieldName::SetValue()",3)
479 }
480 
481 const string WXFieldName::GetValue() const
482 {
483  VFN_DEBUG_MESSAGE("WXFieldName::GetValue()"<<mValue<<":"<<mpField->GetValue(),6)
484  return mValue;
485 }
486 void WXFieldName::CrystUpdate(const bool updateUI,const bool lock)
487 {
488  VFN_DEBUG_MESSAGE("WXFieldName::CrystUpdate()",3)
489  // The name must be updated by the owner
490 }
491 void WXFieldName::UpdateUI(const bool lock)
492 {
493  if(lock) mMutex.Lock();
494  if(mNeedUpdateUI==false)
495  {
496  if(lock) mMutex.Unlock();
497  return;
498  }
499  VFN_DEBUG_ENTRY("WXFieldName::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),4)
500  mIsSelfUpdating=true;
501  mpField->SetValue(wxString::FromAscii(mValue.c_str()));
502  //:TODO: Some way of resizing the field which is less of a kludge...
503  int w=mpField->GetTextExtent(wxString::FromAscii(mValue.c_str())).GetWidth();
504  const int wmax=wxTheApp->GetTopWindow()->GetSize().GetWidth();
505  if(w>wmax)w=wmax;
506  if(w>mpField->GetSize().GetWidth())
507  this->GetSizer()->SetItemMinSize(mpField,w+30,-1);
508  this->GetSizer()->Fit(this);
509 
510  mIsSelfUpdating=false;
511  mNeedUpdateUI=false;
512  if(lock) mMutex.Unlock();
513  VFN_DEBUG_EXIT("WXFieldName::UpdateUI()",4)
514 }
516 {
517  VFN_DEBUG_MESSAGE("WXFieldName::Revert()",3)
518  wxMutexLocker mlock(mMutex);
519  mValue=mValueOld;
520  mNeedUpdateUI=true;
521 }
523 {
524  VFN_DEBUG_MESSAGE("WXFieldName::ValidateUserInput()",6)
525  mMutex.Lock();
527  mValue=mpField->GetValue().ToAscii();
528  mMutex.Unlock();
530 }
531 void WXFieldName::SetSize(int width, int height)
532 {//:TODO: deprecate this function ?
533  mpField->SetSize(width,height);
534 }
535 
536 void WXFieldName::SetToolTip(const wxString& tip){mpField->SetToolTip(tip);}
537 
539 //
540 // WXFieldParBase
541 //
543 BEGIN_EVENT_TABLE(WXFieldParBase,wxWindow)
544  EVT_TEXT_ENTER(ID_WXFIELD, WXFieldParBase::OnEnter)
545  EVT_TEXT( ID_WXFIELD, WXFieldParBase::OnText)
546 END_EVENT_TABLE()
547 
548 WXFieldParBase::WXFieldParBase(wxWindow *parent,const string& label,
549  const int id, const int hsize):
550 WXField(parent,label,id),mIsSelfUpdating(false),mFormat(_T("%8f"))
551 {
552  VFN_DEBUG_MESSAGE("WXFieldParBase::WXFieldName():End",6)
553 
554  mpField=new wxTextCtrl(this,ID_WXFIELD,_T(""),
555  wxDefaultPosition,wxSize(hsize,-1),wxTE_PROCESS_ENTER,
556  wxTextValidator(wxFILTER_NUMERIC));
557  mpSizer->Add(mpField,0,wxALIGN_CENTER);
558 
559  this->Layout();
560 }
561 
562 
563 void WXFieldParBase::OnEnter(wxCommandEvent & WXUNUSED(event))
564 {
565  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnEnter()",6)
567 }
568 void WXFieldParBase::OnText(wxCommandEvent & WXUNUSED(event))
569 {
570  if(true==mIsSelfUpdating) return;
571  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnText()",6)
572  if(spLastWXFieldInputNotValidated!=this)
573  {
575  spLastWXFieldInputNotValidated=this;
576  }
577 }
579 {
580  VFN_DEBUG_MESSAGE("WXFieldRefPar::ValidateUserInput()",6)
581  this->ReadNewValue();
582 }
583 
584 void WXFieldParBase::SetToolTip(const wxString& tip){mpField->SetToolTip(tip);}
585 
586 void WXFieldParBase::SetFormat(const wxString &format)
587 {
588  mFormat=format;
589 }
590 
592 //
593 // WXFieldPar<T>
594 //
596 template<class T> WXFieldPar<T>::WXFieldPar(wxWindow *parent,const string& label,
597  const int id,T *par,const int hsize):
598 WXFieldParBase(parent,label,id,hsize),mpValue(par),mValue(*par),mValueOld(*par),mHumanScale(1)
599 {
600  this->CrystUpdate(true,true);
601 }
602 
603 template<> WXFieldPar<long>::WXFieldPar(wxWindow *parent,const string& label,
604  const int id,long *par,const int hsize):
605 WXFieldParBase(parent,label,id,hsize),mpValue(par),mValue(*par),mValueOld(*par),mHumanScale(1)
606 {
607  mFormat=_T("%ld");
608  this->CrystUpdate(true,true);
609 }
610 
611 template<class T> void WXFieldPar<T>::CrystUpdate(const bool uui,const bool lock)
612 {
613  if(lock) mMutex.Lock();
614  if(mValue==*mpValue)
615  {
616  if(lock) mMutex.Unlock();
617  return;
618  }
619  VFN_DEBUG_ENTRY("WXFieldPar<T>::CrystUpdate()",6)
620  mValueOld=mValue;
621  mValue=*mpValue;
622  mNeedUpdateUI=true;
623  if(lock) mMutex.Unlock();
624  if(uui) if(true==wxThread::IsMain()) this->UpdateUI(lock);
625  VFN_DEBUG_EXIT("WXFieldPar<T>::CrystUpdate()",6)
626 }
627 
628 template<> void WXFieldPar<REAL>::UpdateUI(const bool lock)
629 {
630  if(lock)mMutex.Lock();
631  if(mNeedUpdateUI==false)
632  {
633  if(lock)mMutex.Unlock();
634  return;
635  }
636  VFN_DEBUG_ENTRY("WXFieldPar<REAL>::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),4)
637  wxString tmp;
638  if((abs(mValue*mHumanScale)<1000)&&(abs(mValue*mHumanScale)>0.01)) tmp.Printf(_T("%6.4f"),mValue*mHumanScale);
639  else tmp.Printf(mFormat,mValue*mHumanScale);
640  mIsSelfUpdating=true;
641  mpField->SetValue(tmp);
642  mIsSelfUpdating=false;
643  mNeedUpdateUI=false;
644  if(lock)mMutex.Unlock();
645  VFN_DEBUG_EXIT("WXFieldPar<REAL>::UpdateUI()",4)
646 }
647 
648 template<> void WXFieldPar<long>::UpdateUI(const bool lock)
649 {
650  if(lock)mMutex.Lock();
651  if(mNeedUpdateUI==false)
652  {
653  if(lock)mMutex.Unlock();
654  return;
655  }
656  VFN_DEBUG_ENTRY("WXFieldPar<long>::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),4)
657  wxString tmp;
658  tmp.Printf(mFormat,mValue*mHumanScale);
659  mIsSelfUpdating=true;
660  mpField->SetValue(tmp);
661  mIsSelfUpdating=false;
662  mNeedUpdateUI=false;
663  if(lock)mMutex.Unlock();
664  VFN_DEBUG_EXIT("WXFieldPar<long>::UpdateUI()",4)
665 }
666 /*
667 template<class T> void WXFieldPar<T>::UpdateUI(const bool lock)
668 {
669  if(lock)mMutex.Lock();
670  if(mNeedUpdateUI==false)
671  {
672  if(lock)mMutex.Unlock();
673  return;
674  }
675  stringstream s;
676  s <<*mpValue;
677  mIsSelfUpdating=true;
678  mpField->SetValue(s.str().c_str());;
679  mpField->SetValue(wxString::Printf("%f",mValue));
680  mIsSelfUpdating=false;
681  mNeedUpdateUI=false;
682  if(lock)mMutex.Unlock();
683 }
684 */
685 
686 template<class T> void WXFieldPar<T>::Revert()
687 {
688  VFN_DEBUG_MESSAGE("WXFieldPar<T>::Revert()",6)
689  mMutex.Lock();
690  *mpValue=mValueOld;
691  mValue=mValueOld;
692  mNeedUpdateUI=true;
693  mMutex.Unlock();
694  if(true==wxThread::IsMain()) this->UpdateUI(true);
695 }
696 
697 template<class T> void WXFieldPar<T>::SetHumanValueScale(const T s)
698 {
699  mHumanScale=s;
700 }
701 
703 {
704  VFN_DEBUG_MESSAGE("WXFieldPar<REAL>::ReadNewValue()",6)
705  wxMutexLocker mlock(mMutex);
706  mValueOld=*mpValue;
707  wxString s=mpField->GetValue();
708  double tmp;
709  s.ToDouble(&tmp);
710  *mpValue=tmp;
711  *mpValue /= mHumanScale;
712 }
714 {
715  VFN_DEBUG_MESSAGE("WXFieldPar<long>::ReadNewValue()",6)
716  wxMutexLocker mlock(mMutex);
717  mValueOld=*mpValue;
718  wxString s=mpField->GetValue();
719  s.ToLong(mpValue);
720  *mpValue /= mHumanScale;
721 }
722 
723 
724 template class WXFieldPar<REAL>;
725 template class WXFieldPar<long>;
726 
727 
729 //
730 // WXFieldChoice
731 //
733 WXFieldChoice::WXFieldChoice
734  (wxWindow *parent,const int field_id,const string &name,const int hsize):
735 WXField(parent,name,field_id)
736 {
737  mpButton=new wxButton(this,field_id,wxString::FromAscii(name.c_str()),wxDefaultPosition,wxSize(hsize,-1));
738  mpSizer->Add(mpButton,0,wxALIGN_CENTER);
739  //mpSizer->SetItemMinSize(mpButton,
740  // mpButton->GetSize().GetWidth(),
741  // mpButton->GetSize().GetHeight());
742  //mpSizer->SetSizeHints(this);
743  this->Layout();
744 }
745 
746 void WXFieldChoice::CrystUpdate(const bool uui,const bool lock)
747 {
748  //Nothing to do. This should be done by the owner
749 }
750 void WXFieldChoice::UpdateUI(const bool lock)
751 {
752  //Nothing to do. This should be done by the owner
753 }
754 
755 void WXFieldChoice::Revert()
756 {
757  //Nothing to do. This should be done by the owner
758 }
759 void WXFieldChoice::SetValue(const string&name)
760 {
761  mpButton->SetLabel(wxString::FromAscii(name.c_str()));
762 }
763 void WXFieldChoice::ValidateUserInput(){}
764 
766 //
767 // WXCrystObj
768 //
770 const long ID_WXOBJ_ENABLE=WXCRYST_ID(); //These are used in ObjCryst/RefinableObj.cpp
771 const long ID_WXOBJ_DISABLE=WXCRYST_ID();
772 BEGIN_EVENT_TABLE(WXCrystObj,wxWindow)
773  EVT_BUTTON(ID_WXOBJ_COLLAPSE,WXCrystObj::OnToggleCollapse)
774  EVT_UPDATE_UI(ID_WXOBJ_ENABLE,WXCrystObj::OnEnable)
775  EVT_UPDATE_UI(ID_WXOBJ_DISABLE,WXCrystObj::OnEnable)
776 END_EVENT_TABLE()
777 
778 WXCrystObj::WXCrystObj(wxWindow* parent,int orient,bool showName):
779 WXCrystObjBasic(parent),mIsExpanded(true)
780 {
781  VFN_DEBUG_ENTRY("WXCrystObj::WXCrystObj()",6)
782  mpTopSizer= new wxBoxSizer(orient);
783  this->SetSizer(mpTopSizer);
784 
785  mpCollapseButton=new wxButton(this,ID_WXOBJ_COLLAPSE,_T("-"),
786  wxDefaultPosition,wxSize(14,14));
787  mpTopSizer->Add(mpCollapseButton,0, wxALIGN_TOP);//wxRIGHT | wxTOP | wxALIGN_TOP,4
788  //mpCollapseButton->PushEventHandler(this);
789 
790  mpSizer=new wxBoxSizer(wxVERTICAL);
791  mpTopSizer->Add(mpSizer,0, wxALIGN_TOP);
792 
793  if(showName)
794  {
795  mpWXTitle = new WXFieldName(this,"name:",this,ID_WXOBJ_NAME,100);
796  mpSizer->Add(mpWXTitle,0,wxALIGN_LEFT);
797  }else mpWXTitle=0;
798 
799  //this->Layout();
800  VFN_DEBUG_EXIT("WXCrystObj::WXCrystObj():End",6)
801 }
802 
803 WXCrystObj::~WXCrystObj()
804 {
805  //if(0!=mpWXTitle)
806  //{
807  // delete mpWXTitle;
808  //}
809  //delete mpCollapseButton;
810  //sizers are automatically deleted
811 }
812 
813 void WXCrystObj::OnToggleCollapse(wxCommandEvent & WXUNUSED(event))
814 {
815  #if 0
816  VFN_DEBUG_MESSAGE("WXCrystObj::OnToggleCollapse()",6)
817  mIsExpanded = !mIsExpanded;
818  mList.Show(mIsExpanded);
819  if(true==mIsExpanded) mpCollapseButton->SetLabel("-");
820  else mpCollapseButton->SetLabel("+");
821  this->Layout();
822  VFN_DEBUG_MESSAGE("WXCrystObj::OnToggleCollapse():End",6)
823  #endif
824 }
825 
826 void WXCrystObj::CrystUpdate(const bool uui,const bool lock)
827 {
828  VFN_DEBUG_ENTRY("WXCrystObj::CrystUpdate("<<uui<<lock<<")",6)
829  //if(lock) mMutex.Lock();
830  mList.CrystUpdate(uui,lock);
831  //if(lock) mMutex.Unlock();
832  VFN_DEBUG_EXIT("WXCrystObj::CrystUpdate()",6)
833 }
834 void WXCrystObj::UpdateUI(const bool lock)
835 {
836  VFN_DEBUG_ENTRY("WXCrystObj::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),6)
837  if(lock) mMutex.Lock();
838  if(mpWXTitle!=0) mpWXTitle->UpdateUI(false);
839  mList.UpdateUI(false);
840  if(lock) mMutex.Unlock();
841  VFN_DEBUG_EXIT("WXCrystObj::UpdateUI()",6)
842 }
843 void WXCrystObj::OnEnable(wxUpdateUIEvent &event)
844 {
845  if(ID_WXOBJ_ENABLE==event.GetId()) this->Enable(true);
846  else this->Enable(false);
847  event.Skip();
848 }
849 bool WXCrystObj::Enable(bool enable)
850 {
851  mList.Enable(enable);
852  return this->wxWindow::Enable(enable);
853 }
854 
855 void WXCrystObj::AddChild(WXCrystObjBasic *pChild, bool doBottomLayout)
856 {
857  VFN_DEBUG_ENTRY("WXCrystObj::AddChild(..)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
858  if(mpSizer!=0)
859  {
860  mpSizer->Add(pChild);
861  }
862  if(doBottomLayout) wxTheApp->GetTopWindow()->SendSizeEvent();
863  VFN_DEBUG_EXIT("WXCrystObj::AddChild(..)"<<this->GetSize().GetWidth()<<","<<this->GetSize().GetHeight(),5);
864 }
865 
867 //
868 // WXCrystMenuBar
869 //
871 WXCRYST_ID ID_CRYST_MENU1;
872 WXCRYST_ID ID_CRYST_MENU2;
873 WXCRYST_ID ID_CRYST_MENU3;
874 WXCRYST_ID ID_CRYST_MENU4;
875 WXCRYST_ID ID_CRYST_MENU5;
876 WXCRYST_ID ID_CRYST_MENU6;
877 WXCRYST_ID ID_CRYST_MENU7;
878 WXCRYST_ID ID_CRYST_MENU8;
879 WXCRYST_ID ID_CRYST_MENU9;
880 WXCRYST_ID ID_CRYST_MENU10;
881 WXCRYST_ID ID_CRYST_MENU11;
882 WXCRYST_ID ID_CRYST_MENU12;
883 WXCRYST_ID ID_CRYST_MENU13;
884 WXCRYST_ID ID_CRYST_MENU14;
885 WXCRYST_ID ID_CRYST_MENU15;
886 WXCRYST_ID ID_CRYST_MENU16;
887 
888 
889 BEGIN_EVENT_TABLE(WXCrystMenuBar,wxWindow)
890  EVT_BUTTON(ID_CRYST_MENU1 ,WXCrystMenuBar::OnPopupMenu)
891  EVT_BUTTON(ID_CRYST_MENU2 ,WXCrystMenuBar::OnPopupMenu)
892  EVT_BUTTON(ID_CRYST_MENU3 ,WXCrystMenuBar::OnPopupMenu)
893  EVT_BUTTON(ID_CRYST_MENU4 ,WXCrystMenuBar::OnPopupMenu)
894  EVT_BUTTON(ID_CRYST_MENU5 ,WXCrystMenuBar::OnPopupMenu)
895  EVT_BUTTON(ID_CRYST_MENU6 ,WXCrystMenuBar::OnPopupMenu)
896  EVT_BUTTON(ID_CRYST_MENU7 ,WXCrystMenuBar::OnPopupMenu)
897  EVT_BUTTON(ID_CRYST_MENU8 ,WXCrystMenuBar::OnPopupMenu)
898  EVT_BUTTON(ID_CRYST_MENU9 ,WXCrystMenuBar::OnPopupMenu)
899 END_EVENT_TABLE()
900 
901 WXCrystMenuBar::WXCrystMenuBar(wxWindow *parent, WXCrystObj* owner):
902 WXCrystObjBasic(parent)
903 {
904  VFN_DEBUG_MESSAGE("WXCrystMenuBar::WXCrystMenuBar():",6)
905  mpSizer=new wxBoxSizer(wxHORIZONTAL);
906  this->SetSizer(mpSizer);
907 }
908 
909 void WXCrystMenuBar::AddMenu(const string &name,const int menuId, const string& help)
910 {
911  VFN_DEBUG_MESSAGE("WXCrystMenuBar::AddMenu()",6)
912  const long id=ID_CRYST_MENU1+mvpMenu.size();
913  mvpMenu[menuId]=make_pair(new wxMenu(wxString::FromAscii(name.c_str())),
914  new wxButton(this,id,wxString::FromAscii(name.c_str())));
915  VFN_DEBUG_MESSAGE("WXCrystMenuBar::AddMenu():2",6)
916  mvpMenu[menuId].second->Layout();
917  mpSizer->Add(mvpMenu[menuId].second,0,wxALIGN_CENTER);
918  //wxTheApp->GetTopWindow()->SendSizeEvent();
919  VFN_DEBUG_MESSAGE("WXCrystMenuBar::AddMenu():End",6)
920 }
921 
922 wxMenu& WXCrystMenuBar::GetMenu(const int menuId)
923 {
924  //:TODO: Check we found the correct menu
925  return *(mvpMenu[menuId].first);
926 }
927 
928 void WXCrystMenuBar::AddMenuItem(const int menuId, int id, const string& item, const string& help,const bool checkable)
929 {
930  VFN_DEBUG_MESSAGE("WXCrystMenuBar::AddMenuItem():",6)
931  //:TODO: Check we found the correct menu
932  this->GetMenu(menuId).Append(id,wxString::FromAscii(item.c_str()),wxString::FromAscii(help.c_str()),checkable);
933 }
934 
935 void WXCrystMenuBar::AddMenuItem(const int menuId,int id, const wxString& item,
936  wxMenu *subMenu, const wxString& helpString)
937 {
938  VFN_DEBUG_MESSAGE("WXCrystMenuBar::AddMenuItem():",6)
939  //:TODO: Check we found the correct menu
940  this->GetMenu(menuId).Append(id,item,subMenu,helpString);
941 }
942 
943 void WXCrystMenuBar::CrystUpdate(const bool updateUI,const bool mutexlock)
944 {
945 }
946 void WXCrystMenuBar::UpdateUI(const bool mutexlock)
947 {
948 }
949 
950 void WXCrystMenuBar::OnPopupMenu(wxCommandEvent & event)
951 {
952  VFN_DEBUG_MESSAGE("WXCrystMenuBar::OnPopupMenu():",6)
953  // The ID of the button is not the same as the ID of the menu,
954  // so look it up. (to have the same ID we'd need to delegate event handling,
955  // which would be a pain.
956  std::map<long,pair<wxMenu *,wxButton*> >::iterator pos;
957  const int i=event.GetId();
958  for(pos=mvpMenu.begin();pos!=mvpMenu.end();++pos) if(i==pos->second.second->GetId()) break;
959  if(pos!=mvpMenu.end())
960  this->PopupMenu(pos->second.first,pos->second.second->GetPosition());
961 }
962 void WXCrystMenuBar::SetToolTip(const wxString& tip,long menuId){mvpMenu[menuId].second->SetToolTip(tip);}
963 
964 }//namespace
WXCrystObj * mpWXObj
The WXCrystObj whose name is shown here.
Definition: wxCryst.h:399
wxString mFormat
Format to be used, default = _T("%8f")
Definition: wxCryst.h:446
void SetValue(const string &)
This actually posts an UpdateUI event, so that it is safe to call it from a non-graphic thread...
Definition: wxCryst.cpp:467
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the entry field.
Definition: wxCryst.cpp:584
A List of WXCrystObjBasic.
Definition: wxCryst.h:196
bool mIsSelfUpdating
Set to true if the Field is being updated, so that no 'EVT_TEXT' is understood as user input...
Definition: wxCryst.h:409
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual ~WXCrystObjBasic()
Destructor.
Definition: wxCryst.cpp:143
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
This gets a new value from the parameter.
Definition: wxCryst.cpp:611
wxTextCtrl * mpField
The text window.
Definition: wxCryst.h:358
string mValueOld
Last name displayed, before the value was changed by the user.
Definition: wxCryst.h:406
void SetValue(const string &)
This actually posts an UpdateUI event, so that it is safe to call it from a non-graphic thread...
Definition: wxCryst.cpp:346
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
Definition: wxCryst.cpp:257
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
Definition: wxCryst.h:189
void Remove(WXCrystObjBasic *)
remove an object from the list
Definition: wxCryst.cpp:206
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...
Definition: wxCryst.cpp:365
bool mIsSelfUpdating
Set to true if the Field is being updated, so that no 'EVT_TEXT' is understood as user input...
Definition: wxCryst.h:444
virtual void ReadNewValue()=0
Reads the new value when the Enter key is hit.
const int mId
The Id of this field.
Definition: wxCryst.h:316
WXFieldPar(wxWindow *parent, const string &label, const int field_id, T *par, const int hsize=65)
Constructor.
Definition: wxCryst.cpp:596
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the entry field.
Definition: wxCryst.cpp:536
std::set< WXCrystObjBasic * > mvpWXCrystObj
List of pointers to the objects.
Definition: wxCryst.h:231
void Add(WXCrystObjBasic *)
Add an object to the list.
Definition: wxCryst.cpp:199
unsigned int GetNb() const
Number of objects.
Definition: wxCryst.cpp:197
bool mNeedUpdateUI
Do we need to update the display ?
Definition: wxCryst.h:187
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window.
Definition: wxCryst.cpp:179
virtual void ValidateUserInput()
This function shall be called when a new value has been entered.
Definition: wxCryst.cpp:578
bool mIsSelfUpdating
Set to true if the Field is being updated, so that no 'EVT_TEXT' is understood as user input...
Definition: wxCryst.h:364
virtual void SetSize(int width, int height)
Change the size of the field (excluding the title)
Definition: wxCryst.cpp:413
void OnText(wxCommandEvent &WXUNUSED(event))
Records when text is entered (either from self-updating or user input)
Definition: wxCryst.cpp:335
std::map< wxWindowID, std::pair< wxPoint, wxSize > > gvWindowPosition
Used to remember window positions.
Definition: wxCryst.cpp:51
bool Show(bool)
Show or hide all of the windows.
Definition: wxCryst.cpp:213
void SetLabel(const string &)
Change the field's label.
Definition: wxCryst.cpp:285
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
This does nothing.
Definition: wxCryst.cpp:486
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:491
void OnEnter(wxCommandEvent &WXUNUSED(event))
When a new value is entered (must type it and then hit the 'enter' key).
Definition: wxCryst.cpp:563
A field with the name of a WXCrystObj.
Definition: wxCryst.h:371
This is the abstract base class for all fields, wether they contain a floating-point parameter...
Definition: wxCryst.h:291
void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:223
WXCrystObjBasic * mWXCrystParent
Parent, if a WXCrystObjBasic itself.
Definition: wxCryst.h:183
void OnText(wxCommandEvent &WXUNUSED(event))
Records when text is entered (either from self-updating or user input)
Definition: wxCryst.cpp:568
void RemovedFromList(WXCrystObjBasicList *list)
Definition: wxCryst.cpp:172
void AddedToList(WXCrystObjBasicList *list)
Definition: wxCryst.cpp:171
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
Definition: wxCryst.cpp:515
virtual void SetSize(int width, int height)
Change the size of the field (excluding the title)
Definition: wxCryst.cpp:298
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:127
wxTextCtrl * mpField
The field in which the value is written.
Definition: wxCryst.h:441
const string GetValue() const
Get the current name.
Definition: wxCryst.cpp:481
virtual bool SetForegroundColour(const wxColour &colour)
Change the colour of the field's title.
Definition: wxCryst.cpp:291
string mValue
Last name displayed.
Definition: wxCryst.h:401
virtual bool OnChangeName(const int id)=0
When a WXFieldName has been changed by the user, it is handled here.
wxBoxSizer * mpSizer
The horizontal sizer in which the title, button, fields, are put.
Definition: wxCryst.h:312
A field for a parameter.
Definition: wxCryst.h:416
~WXCrystObjBasicList()
Destructor.
Definition: wxCryst.cpp:189
const string GetValue() const
Get the current name.
Definition: wxCryst.cpp:360
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects)...
Definition: wxCryst.h:248
string mValue
Last name displayed.
Definition: wxCryst.h:356
virtual void SetSize(int width, int height)
Change the size of the field (excluding the title)
Definition: wxCryst.cpp:531
wxTextCtrl * mpField
The text window.
Definition: wxCryst.h:403
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the entry field.
Definition: wxCryst.cpp:419
virtual void ValidateUserInput()=0
This function shall be called when a new value has been entered.
WXCrystObjBasicList()
Constructor.
Definition: wxCryst.cpp:186
void SetFormat(const wxString &format)
Set Format.
Definition: wxCryst.cpp:586
string mValueOld
Last name displayed, before the value was changed by the user.
Definition: wxCryst.h:361
A field for a parameter.
Definition: wxCryst.h:452
Class to automatically assign a unique wxID to each window.
Definition: wxCryst.h:74
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
wxStaticText * mpLabel
The label.
Definition: wxCryst.h:314
virtual void ValidateUserInput()
This function shall be called when a new value has been entered.
Definition: wxCryst.cpp:522
virtual void ValidateUserInput()
This function shall be called when a new value has been entered.
Definition: wxCryst.cpp:404
WXField * spLastWXFieldInputNotValidated
This pointer records the last wxField in which something was enetered, so that it can be validated wh...
Definition: wxCryst.cpp:255
std::set< WXCrystObjBasicList * > mvpList
WXCrystObjBasicList which are aware of this object, and which should be told on destruction.
Definition: wxCryst.h:192
string * mpString
The WXCrystObj whose name is shown here.
Definition: wxCryst.h:354
void OnText(wxCommandEvent &WXUNUSED(event))
Records when text is entered (either from self-updating or user input)
Definition: wxCryst.cpp:456
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:381
WXField(wxWindow *parent, const string &label, const int field_id)
Constructor, specifying the label of the field.
Definition: wxCryst.cpp:273
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
Definition: wxCryst.cpp:397
virtual void AddChild(WXCrystObjBasic *pChild, bool doBottomLayout=true)
Notify that a new children has been added, also adding it to the correct sizer (which can be the top ...
Definition: wxCryst.cpp:159
A field which directly links to a string.
Definition: wxCryst.h:328
void UpdateUI(const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:233
Our own local menu bar, using buttons and Popup menus.
Definition: wxCryst.h:503