MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/gui/wxnuminput.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand                   *
00004  * Copyright (C) 2009 Sergio Galindo                                    *
00005  *                                                                      *
00006  * This program is free software: you can redistribute it and/or modify *
00007  * it under the terms of the GNU General Public License as published by *
00008  * the Free Software Foundation, either version 3 of the License, or    *
00009  * any later version.                                                   *
00010  *                                                                      *
00011  * This program is distributed in the hope that it will be useful,      *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00014  * GNU General Public License for more details.                         *
00015  *                                                                      *
00016  * You should have received a copy of the GNU General Public License    *
00017  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00018  ************************************************************************/
00019 
00020 #ifndef MECHSYS_WXNUMINPUT_H
00021 #define MECHSYS_WXNUMINPUT_H
00022 
00023 // wxWidgets
00024 #include <wx/textctrl.h>
00025 #include <wx/event.h>
00026 #include <wx/validate.h>
00027 
00028 
00030 
00031 
00032 class WxNumInput_Event : public wxNotifyEvent
00033 {
00034 public:
00035     // Constructor
00036     WxNumInput_Event(wxEventType CmdType=wxEVT_NULL, int Id=0)
00037         : wxNotifyEvent(CmdType, Id)
00038     {}
00039 
00040     // Copy constructor
00041     WxNumInput_Event(WxNumInput_Event const & Event)
00042         : wxNotifyEvent(Event)
00043     {}
00044 
00045     // Destructor
00046     virtual ~WxNumInput_Event () {}
00047 
00048     // Clone function
00049     virtual wxEvent * Clone() const { return new WxNumInput_Event(*this); }
00050 
00051     // Declare dynamic class
00052     DECLARE_DYNAMIC_CLASS(WxNumInput_Event);
00053 
00054     // Methods
00055     void   SetValue (double Val) { _value = Val;  }
00056     double GetValue ()     const { return _value; }
00057 
00058 private:
00059     // Data
00060     double _value;
00061 };
00062 
00063 typedef void (wxEvtHandler::*WxNumInput_Event_Fun)(WxNumInput_Event&);
00064 
00065 BEGIN_DECLARE_EVENT_TYPES()
00066     DECLARE_EVENT_TYPE(EVT_REALNUM_CHANGED, 801)
00067 END_DECLARE_EVENT_TYPES()
00068 
00069 // Macros for handling events
00070 #define EVT_REALNUM_CHANGED(id, fn)                                           \
00071     DECLARE_EVENT_TABLE_ENTRY                                                 \
00072     (                                                                         \
00073         EVT_REALNUM_CHANGED                                                 , \
00074         id                                                                  , \
00075         -1                                                                  , \
00076         (wxObjectEventFunction)(wxEventFunction)(WxNumInput_Event_Fun) & fn , \
00077         (wxObject*) NULL                                                      \
00078     ),
00079 
00080 DEFINE_EVENT_TYPE       (EVT_REALNUM_CHANGED)
00081 IMPLEMENT_DYNAMIC_CLASS (WxNumInput_Event, wxNotifyEvent)
00082 
00083 
00085 
00086 
00087 class WxNumInput : public wxTextCtrl
00088 {
00089 public:
00090     // Constructor
00091     WxNumInput(wxWindow * Parent, wxWindowID Id, double Val, const wxPoint & Pos=wxDefaultPosition, const wxSize & Size=wxDefaultSize, int Style=0, wxValidator const & Validator=wxDefaultValidator)
00092         : wxTextCtrl(Parent, Id, wxEmptyString, Pos, Size, Style|wxTE_PROCESS_ENTER, Validator)
00093     {
00094         wxString str;  str.Printf("%g",Val);
00095         SetValue (str);
00096     }
00097 
00098     // Events
00099     void OnChar      (wxKeyEvent     & Event);
00100     void OnSetFocus  (wxFocusEvent   & Event);
00101     void OnKillFocus (wxFocusEvent   & Event);
00102     void OnTextEnter (wxCommandEvent & Event); 
00103 
00104     // Methods
00105     double GetVal () const { double val; GetValue().ToDouble(&val); return val; }
00106     void   SetVal (double Val) { wxString str; str.Printf("%g",Val); SetValue(str); }
00107 
00108 private:
00109     // Event table
00110     DECLARE_EVENT_TABLE()
00111 
00112     // Data
00113     wxString _buffer;
00114 
00115     // Methods
00116     bool _validate_value             (double & TmpValue);
00117     void _send_realnum_changed_event (double Val);
00118 };
00119 
00120 
00122 
00123 
00124 inline void WxNumInput::OnChar(wxKeyEvent & Event)
00125 {
00126     if (!isalpha(Event.GetKeyCode())) Event.Skip(); // Input is ok, so skip to main loop
00127     else
00128     {
00129         if (Event.GetKeyCode()==69)  Event.Skip(); // "E"
00130         if (Event.GetKeyCode()==101) Event.Skip(); // "e"
00131     }
00132 }
00133 
00134 inline void WxNumInput::OnSetFocus(wxFocusEvent & Event)
00135 {
00136     _buffer = GetValue(); // save a buffered value
00137     Event.Skip();
00138 }
00139 
00140 inline void WxNumInput::OnKillFocus(wxFocusEvent & Event)
00141 {
00142     double temp;
00143     if (_validate_value(temp)) _send_realnum_changed_event(temp);
00144 }
00145 
00146 inline void WxNumInput::OnTextEnter(wxCommandEvent & Event)
00147 {
00148     double temp;
00149     if (_validate_value(temp)) _send_realnum_changed_event(temp);
00150 }
00151 
00152 inline bool WxNumInput::_validate_value(double & OutValue)
00153 {
00154     bool ok_and_changed = false;
00155     if (!GetValue().ToDouble(&OutValue)) SetValue(_buffer); // not valid, so restore buffered value
00156     else
00157     {
00158         if (GetValue()!=_buffer) // really changed ?
00159         {
00160             double buffer_temp;
00161             if (_buffer.ToDouble(&buffer_temp))
00162             {
00163                 if (buffer_temp==OutValue) SetValue(_buffer); // did not change, just the format is different, ex.: 0 != 000
00164                 else ok_and_changed=true;
00165             }
00166         }
00167     }
00168     return ok_and_changed;
00169 }
00170 
00171 inline void WxNumInput::_send_realnum_changed_event(double Val)
00172 {
00173     WxNumInput_Event event(EVT_REALNUM_CHANGED, GetId());
00174     event.SetEventObject (this);
00175     event.SetValue       (Val);
00176     GetEventHandler()->ProcessEvent(event);
00177 }
00178 
00179 BEGIN_EVENT_TABLE(WxNumInput, wxTextCtrl)
00180     EVT_CHAR       (          WxNumInput::OnChar     )
00181     EVT_SET_FOCUS  (          WxNumInput::OnSetFocus )
00182     EVT_KILL_FOCUS (          WxNumInput::OnKillFocus)
00183     EVT_TEXT_ENTER (wxID_ANY, WxNumInput::OnTextEnter)
00184 END_EVENT_TABLE()
00185 
00186 
00188 
00189 
00190 class WxNumValidator : public wxValidator
00191 {
00192 public:
00193     WxNumValidator (double * ptVal)      : wxValidator(), pValDbl(ptVal), pValInt(NULL)  {}
00194     WxNumValidator (int    * ptVal=NULL) : wxValidator(), pValDbl(NULL),  pValInt(ptVal) {}
00195     WxNumValidator (WxNumValidator const & Other) { pValDbl=Other.pValDbl; pValInt=Other.pValInt; }
00196     virtual ~WxNumValidator() {}
00197 
00198     virtual wxObject * Clone              () const { return new WxNumValidator(*this); }
00199     virtual bool       TransferFromWindow ();
00200     virtual bool       TransferToWindow   ();
00201     virtual bool       Validate           (wxWindow * parent) { return true; }
00202 
00203     WxNumValidator & operator= (WxNumValidator const & Other) { pValDbl=Other.pValDbl; pValInt=Other.pValInt; return (*this); }
00204 
00205 private:
00206     double * pValDbl;
00207     int    * pValInt;
00208     DECLARE_DYNAMIC_CLASS(WxNumValidator)
00209     DECLARE_EVENT_TABLE()
00210 };
00211 
00212 IMPLEMENT_DYNAMIC_CLASS(WxNumValidator, wxValidator)
00213 
00214 BEGIN_EVENT_TABLE(WxNumValidator, wxValidator)
00215 END_EVENT_TABLE()
00216 
00217 bool WxNumValidator::TransferFromWindow()
00218 {
00219     if (pValInt==NULL) (*pValDbl) = static_cast<WxNumInput*>(m_validatorWindow)->GetVal();
00220     else               (*pValInt) = static_cast<WxNumInput*>(m_validatorWindow)->GetVal();
00221     return true;
00222 }
00223 
00224 bool WxNumValidator::TransferToWindow()
00225 {
00226     if (pValInt==NULL) static_cast<WxNumInput*>(m_validatorWindow)->SetVal((*pValDbl));
00227     else               static_cast<WxNumInput*>(m_validatorWindow)->SetVal((*pValInt));
00228     return true;
00229 }
00230 
00231 #endif // MECHSYS_WXNUMINPUT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines