home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / spinctlg.cpp < prev    next >
C/C++ Source or Header  |  2002-09-01  |  10KB  |  378 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        src/generic/spinctlg.cpp
  3. // Purpose:     implements wxSpinCtrl as a composite control
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     29.01.01
  7. // RCS-ID:      $Id: spinctlg.cpp,v 1.19 2002/08/31 22:52:24 VZ Exp $
  8. // Copyright:   (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  9. // License:     wxWindows license
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "spinctlg.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28.     #pragma hdrstop
  29. #endif
  30.  
  31. #if !(defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__)) || \
  32.     defined(__WXMAC__) || defined(__WXUNIVERSAL__)
  33.  
  34. #ifndef WX_PRECOMP
  35.     #include "wx/textctrl.h"
  36. #endif //WX_PRECOMP
  37.  
  38. #if wxUSE_SPINCTRL
  39.  
  40. #include "wx/spinbutt.h"
  41. #include "wx/spinctrl.h"
  42.  
  43. // ----------------------------------------------------------------------------
  44. // constants
  45. // ----------------------------------------------------------------------------
  46.  
  47. // the margin between the text control and the spin
  48. static const wxCoord MARGIN = 2;
  49.  
  50. // ----------------------------------------------------------------------------
  51. // wxSpinCtrlText: text control used by spin control
  52. // ----------------------------------------------------------------------------
  53.  
  54. class wxSpinCtrlText : public wxTextCtrl
  55. {
  56. public:
  57.     wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
  58.         : wxTextCtrl(spin->GetParent(), -1, value)
  59.     {
  60.         m_spin = spin;
  61.     }
  62.  
  63. protected:
  64.     void OnTextChange(wxCommandEvent& event)
  65.     {
  66.         int val;
  67.         if ( m_spin->GetTextValue(&val) )
  68.         {
  69.             m_spin->GetSpinButton()->SetValue(val);
  70.         }
  71.  
  72.         event.Skip();
  73.     }
  74.  
  75.     bool ProcessEvent(wxEvent &event)
  76.     {
  77.         // Hand button down events to wxSpinCtrl. Doesn't work.
  78.         if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
  79.             return TRUE;
  80.  
  81.         return wxTextCtrl::ProcessEvent( event );
  82.     }
  83.  
  84. private:
  85.     wxSpinCtrl *m_spin;
  86.  
  87.     DECLARE_EVENT_TABLE()
  88. };
  89.  
  90. BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
  91.     EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
  92. END_EVENT_TABLE()
  93.  
  94. // ----------------------------------------------------------------------------
  95. // wxSpinCtrlButton: spin button used by spin control
  96. // ----------------------------------------------------------------------------
  97.  
  98. class wxSpinCtrlButton : public wxSpinButton
  99. {
  100. public:
  101.     wxSpinCtrlButton(wxSpinCtrl *spin, int style)
  102.         : wxSpinButton(spin->GetParent())
  103.     {
  104.         m_spin = spin;
  105.  
  106.         SetWindowStyle(style | wxSP_VERTICAL);
  107.     }
  108.  
  109. protected:
  110.     void OnSpinButton(wxSpinEvent& eventSpin)
  111.     {
  112. #if defined(__WXMAC__) || defined(__WXMOTIF__)
  113.       m_spin->SetTextValue(eventSpin.GetPosition());
  114.  
  115.       wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId());
  116.       event.SetEventObject(m_spin);
  117.       event.SetInt(eventSpin.GetPosition());
  118.  
  119.       m_spin->GetEventHandler()->ProcessEvent(event);
  120. #else
  121.         m_spin->SetTextValue(eventSpin.GetPosition());
  122.         eventSpin.Skip();
  123. #endif
  124.     }
  125.  
  126. private:
  127.     wxSpinCtrl *m_spin;
  128.  
  129.     DECLARE_EVENT_TABLE()
  130. };
  131.  
  132. BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
  133.     EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
  134. END_EVENT_TABLE()
  135.  
  136. IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
  137.  
  138. // ============================================================================
  139. // implementation
  140. // ============================================================================
  141.  
  142. // ----------------------------------------------------------------------------
  143. // wxSpinCtrl creation
  144. // ----------------------------------------------------------------------------
  145.  
  146. void wxSpinCtrl::Init()
  147. {
  148.     m_text = NULL;
  149.     m_btn = NULL;
  150. }
  151.  
  152. bool wxSpinCtrl::Create(wxWindow *parent,
  153.                         wxWindowID id,
  154.                         const wxString& value,
  155.                         const wxPoint& pos,
  156.                         const wxSize& size,
  157.                         long style,
  158.                         int min,
  159.                         int max,
  160.                         int initial,
  161.                         const wxString& name)
  162. {
  163.     if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style,
  164.                             wxDefaultValidator, name) )
  165.     {
  166.         return FALSE;
  167.     }
  168.  
  169.     // the string value overrides the numeric one (for backwards compatibility
  170.     // reasons and also because it is simpler to satisfy the string value which
  171.     // comes much sooner in the list of arguments and leave the initial
  172.     // parameter unspecified)
  173.     if ( !value.empty() )
  174.     {
  175.         long l;
  176.         if ( value.ToLong(&l) )
  177.             initial = l;
  178.     }
  179.  
  180.     SetBackgroundColour(*wxRED);
  181.     m_text = new wxSpinCtrlText(this, value);
  182.     m_btn = new wxSpinCtrlButton(this, style);
  183.  
  184.     m_btn->SetRange(min, max);
  185.     m_btn->SetValue(initial);
  186. #ifdef __WXMAC__
  187.     wxSize csize = size ;
  188.     if ( size.y == -1 ) {
  189.       csize.y = m_text->GetSize().y ;
  190.     }
  191.     DoSetSize(pos.x, pos.y, csize.x, csize.y);
  192. #else
  193.     wxSize best = GetBestSize();
  194.     if ( size.x != -1 ) best.x = size.x;
  195.     if ( size.y != -1 ) best.y = size.y;
  196.     DoSetSize(pos.x, pos.y, best.x, best.y);
  197. #endif
  198.     // have to disable this window to avoid interfering it with message
  199.     // processing to the text and the button... but pretend it is enabled to
  200.     // make IsEnabled() return TRUE
  201.     wxControl::Enable(FALSE); // don't use non virtual Disable() here!
  202.     m_isEnabled = TRUE;
  203.  
  204.     // we don't even need to show this window itself - and not doing it avoids
  205.     // that it overwrites the text control
  206.     wxControl::Show(FALSE);
  207. #ifndef __WXMAC__
  208.     m_isShown = TRUE;
  209. #endif
  210.     return TRUE;
  211. }
  212.  
  213. wxSpinCtrl::~wxSpinCtrl()
  214. {
  215.     // delete the controls now, don't leave them alive even though they woudl
  216.     // still be eventually deleted by our parent - but it will be too late, the
  217.     // user code expects them to be gone now
  218.     delete m_text;
  219.     delete m_btn;
  220. }
  221.  
  222. // ----------------------------------------------------------------------------
  223. // geometry
  224. // ----------------------------------------------------------------------------
  225.  
  226. wxSize wxSpinCtrl::DoGetBestSize() const
  227. {
  228.     wxSize sizeBtn = m_btn->GetBestSize(),
  229.            sizeText = m_text->GetBestSize();
  230.  
  231.     return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
  232. }
  233.  
  234. void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
  235. {
  236.     wxControl::DoMoveWindow(x, y, width, height);
  237.  
  238.     // position the subcontrols inside the client area
  239.     wxSize sizeBtn = m_btn->GetSize();
  240.  
  241.     wxCoord wText = width - sizeBtn.x;
  242.     m_text->SetSize(x, y, wText, height);
  243. #ifdef __WXMAC__
  244.     m_btn->SetSize(x + wText + MARGIN, y, -1, -1);
  245. #else
  246.     m_btn->SetSize(x + wText + MARGIN, y, -1, height);
  247. #endif
  248. }
  249.  
  250. // ----------------------------------------------------------------------------
  251. // operations forwarded to the subcontrols
  252. // ----------------------------------------------------------------------------
  253.  
  254. bool wxSpinCtrl::Enable(bool enable)
  255. {
  256.     if ( !wxControl::Enable(enable) )
  257.         return FALSE;
  258.  
  259.     m_btn->Enable(enable);
  260.     m_text->Enable(enable);
  261.  
  262.     return TRUE;
  263. }
  264.  
  265. bool wxSpinCtrl::Show(bool show)
  266. {
  267.     if ( !wxControl::Show(show) )
  268.         return FALSE;
  269.  
  270.     // under GTK Show() is called the first time before we are fully
  271.     // constructed
  272.     if ( m_btn )
  273.     {
  274.         m_btn->Show(show);
  275.         m_text->Show(show);
  276.     }
  277.  
  278.     return TRUE;
  279. }
  280.  
  281. // ----------------------------------------------------------------------------
  282. // value and range access
  283. // ----------------------------------------------------------------------------
  284.  
  285. bool wxSpinCtrl::GetTextValue(int *val) const
  286. {
  287.     long l;
  288.     if ( !m_text->GetValue().ToLong(&l) )
  289.     {
  290.         // not a number at all
  291.         return FALSE;
  292.     }
  293.  
  294.     if ( l < GetMin() || l > GetMax() )
  295.     {
  296.         // out of range
  297.         return FALSE;
  298.     }
  299.  
  300.     *val = l;
  301.  
  302.     return TRUE;
  303. }
  304.  
  305. int wxSpinCtrl::GetValue() const
  306. {
  307.     return m_btn ? m_btn->GetValue() : 0;
  308. }
  309.  
  310. int wxSpinCtrl::GetMin() const
  311. {
  312.     return m_btn ? m_btn->GetMin() : 0;
  313. }
  314.  
  315. int wxSpinCtrl::GetMax() const
  316. {
  317.     return m_btn ? m_btn->GetMax() : 0;
  318. }
  319.  
  320. // ----------------------------------------------------------------------------
  321. // changing value and range
  322. // ----------------------------------------------------------------------------
  323.  
  324. void wxSpinCtrl::SetTextValue(int val)
  325. {
  326.     wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
  327.  
  328.     m_text->SetValue(wxString::Format(_T("%d"), val));
  329.  
  330.     // select all text
  331.     m_text->SetSelection(0, -1);
  332.  
  333.     // and give focus to the control!
  334.     // m_text->SetFocus();    Why???? TODO.
  335. }
  336.  
  337. void wxSpinCtrl::SetValue(int val)
  338. {
  339.     wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
  340.  
  341.     SetTextValue(val);
  342.  
  343.     m_btn->SetValue(val);
  344. }
  345.  
  346. void wxSpinCtrl::SetValue(const wxString& text)
  347. {
  348.     wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
  349.  
  350.     long val;
  351.     if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
  352.     {
  353.         SetValue((int)val);
  354.     }
  355.     else // not a number at all or out of range
  356.     {
  357.         m_text->SetValue(text);
  358.         m_text->SetSelection(0, -1);
  359.     }
  360. }
  361.  
  362. void wxSpinCtrl::SetRange(int min, int max)
  363. {
  364.     wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
  365.  
  366.     m_btn->SetRange(min, max);
  367. }
  368.  
  369. void wxSpinCtrl::SetSelection(long from, long to)
  370. {
  371.     wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetSelection") );
  372.  
  373.     m_text->SetSelection(from, to);
  374. }
  375.  
  376. #endif // wxUSE_SPINCTRL
  377. #endif // !wxPort-with-native-spinctrl
  378.