]> git.saurik.com Git - wxWidgets.git/blame - src/generic/spinctlg.cpp
removed assert which could be provoked by correct code
[wxWidgets.git] / src / generic / spinctlg.cpp
CommitLineData
21709999
JS
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$
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
9453cf2b 31#if !(defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__)) || defined(__WXMAC__) || \
3379ed37 32 defined(__WXUNIVERSAL__)
21709999
JS
33
34#ifndef WX_PRECOMP
35 #include "wx/textctrl.h"
36#endif //WX_PRECOMP
37
38#include "wx/spinbutt.h"
39#include "wx/spinctrl.h"
40
41// ----------------------------------------------------------------------------
42// constants
43// ----------------------------------------------------------------------------
44
45// the margin between the text control and the spin
46static const wxCoord MARGIN = 2;
47
48// ----------------------------------------------------------------------------
49// wxSpinCtrlText: text control used by spin control
50// ----------------------------------------------------------------------------
51
52class wxSpinCtrlText : public wxTextCtrl
53{
54public:
55 wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
56 : wxTextCtrl(spin->GetParent(), -1, value)
57 {
58 m_spin = spin;
59 }
60
61protected:
62 void OnTextChange(wxCommandEvent& event)
63 {
64 int val;
65 if ( m_spin->GetTextValue(&val) )
66 {
67 m_spin->GetSpinButton()->SetValue(val);
68 }
69
70 event.Skip();
71 }
23d416bf
RR
72
73 bool ProcessEvent(wxEvent &event)
74 {
75 // Hand button down events to wxSpinCtrl. Doesn't work.
76 if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
77 return TRUE;
78
79 return wxTextCtrl::ProcessEvent( event );
80 }
21709999
JS
81
82private:
83 wxSpinCtrl *m_spin;
84
85 DECLARE_EVENT_TABLE()
86};
87
88BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
89 EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
90END_EVENT_TABLE()
91
92// ----------------------------------------------------------------------------
93// wxSpinCtrlButton: spin button used by spin control
94// ----------------------------------------------------------------------------
95
96class wxSpinCtrlButton : public wxSpinButton
97{
98public:
99 wxSpinCtrlButton(wxSpinCtrl *spin, int style)
100 : wxSpinButton(spin->GetParent())
101 {
102 m_spin = spin;
103
104 SetWindowStyle(style);
105 }
106
107protected:
108 void OnSpinButton(wxSpinEvent& event)
109 {
110 m_spin->SetTextValue(event.GetPosition());
111
112 event.Skip();
113 }
114
115private:
116 wxSpinCtrl *m_spin;
117
118 DECLARE_EVENT_TABLE()
119};
120
121BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
122 EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
123END_EVENT_TABLE()
124
125IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
126
127// ============================================================================
128// implementation
129// ============================================================================
130
131// ----------------------------------------------------------------------------
132// wxSpinCtrl creation
133// ----------------------------------------------------------------------------
134
135void wxSpinCtrl::Init()
136{
137 m_text = NULL;
138 m_btn = NULL;
139}
140
141bool wxSpinCtrl::Create(wxWindow *parent,
142 wxWindowID id,
143 const wxString& value,
144 const wxPoint& pos,
145 const wxSize& size,
146 long style,
147 int min,
148 int max,
149 int initial,
150 const wxString& name)
151{
152 if ( !wxControl::Create(parent, id, pos, size, style,
153 wxDefaultValidator, name) )
154 {
155 return FALSE;
156 }
157
158 SetBackgroundColour(*wxRED);
21709999
JS
159 m_text = new wxSpinCtrlText(this, value);
160 m_btn = new wxSpinCtrlButton(this, style);
161
162 m_btn->SetRange(min, max);
163 m_btn->SetValue(initial);
9453cf2b 164#ifdef __WXMAC__
954fc50b
SC
165 wxSize csize = size ;
166 if ( size.y == -1 ) {
167 csize.y = m_text->GetSize().y ;
168 }
169 DoSetSize(pos.x, pos.y, csize.x, csize.y);
170#else
171 DoSetSize(pos.x, pos.y, size.x, size.y);
9453cf2b 172#endif
21709999
JS
173 // have to disable this window to avoid interfering it with message
174 // processing to the text and the button... but pretend it is enabled to
175 // make IsEnabled() return TRUE
176 wxControl::Enable(FALSE); // don't use non virtual Disable() here!
177 m_isEnabled = TRUE;
178
179 // we don't even need to show this window itself - and not doing it avoids
180 // that it overwrites the text control
181 wxControl::Show(FALSE);
954fc50b 182#ifndef __WXMAC__
21709999 183 m_isShown = TRUE;
954fc50b 184#endif
21709999
JS
185 return TRUE;
186}
187
188wxSpinCtrl::~wxSpinCtrl()
189{
190 // delete the controls now, don't leave them alive even though they woudl
191 // still be eventually deleted by our parent - but it will be too late, the
192 // user code expects them to be gone now
193 delete m_text;
194 delete m_btn;
195}
196
197// ----------------------------------------------------------------------------
198// geometry
199// ----------------------------------------------------------------------------
200
201wxSize wxSpinCtrl::DoGetBestClientSize() const
202{
203 wxSize sizeBtn = m_btn->GetBestSize(),
204 sizeText = m_text->GetBestSize();
205
206 return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
207}
208
209void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
210{
211 wxControl::DoMoveWindow(x, y, width, height);
212
213 // position the subcontrols inside the client area
3379ed37 214 wxSize sizeBtn = m_btn->GetSize();
21709999
JS
215
216 wxCoord wText = width - sizeBtn.x;
217 m_text->SetSize(x, y, wText, height);
218 m_btn->SetSize(x + wText + MARGIN, y, -1, height);
219}
220
221// ----------------------------------------------------------------------------
222// operations forwarded to the subcontrols
223// ----------------------------------------------------------------------------
224
225bool wxSpinCtrl::Enable(bool enable)
226{
227 if ( !wxControl::Enable(enable) )
228 return FALSE;
229
230 m_btn->Enable(enable);
231 m_text->Enable(enable);
232
233 return TRUE;
234}
235
236bool wxSpinCtrl::Show(bool show)
237{
238 if ( !wxControl::Show(show) )
239 return FALSE;
240
3379ed37
VZ
241 // under GTK Show() is called the first time before we are fully
242 // constructed
243 if ( m_btn )
244 {
245 m_btn->Show(show);
246 m_text->Show(show);
247 }
21709999
JS
248
249 return TRUE;
250}
251
252// ----------------------------------------------------------------------------
253// value and range access
254// ----------------------------------------------------------------------------
255
256bool wxSpinCtrl::GetTextValue(int *val) const
257{
258 long l;
259 if ( !m_text->GetValue().ToLong(&l) )
260 {
261 // not a number at all
262 return FALSE;
263 }
264
265 if ( l < GetMin() || l > GetMax() )
266 {
267 // out of range
268 return FALSE;
269 }
270
271 *val = l;
272
273 return TRUE;
274}
275
276int wxSpinCtrl::GetValue() const
277{
278 return m_btn ? m_btn->GetValue() : 0;
279}
280
281int wxSpinCtrl::GetMin() const
282{
283 return m_btn ? m_btn->GetMin() : 0;
284}
285
286int wxSpinCtrl::GetMax() const
287{
288 return m_btn ? m_btn->GetMax() : 0;
289}
290
291// ----------------------------------------------------------------------------
292// changing value and range
293// ----------------------------------------------------------------------------
294
295void wxSpinCtrl::SetTextValue(int val)
296{
297 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
298
299 m_text->SetValue(wxString::Format(_T("%d"), val));
300
301 // select all text
302 m_text->SetSelection(0, -1);
303
304 // and give focus to the control!
305 m_text->SetFocus();
306}
307
308void wxSpinCtrl::SetValue(int val)
309{
310 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
311
312 SetTextValue(val);
313
314 m_btn->SetValue(val);
315}
316
317void wxSpinCtrl::SetValue(const wxString& text)
318{
319 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
320
321 long val;
322 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
323 {
324 SetValue((int)val);
325 }
326 else // not a number at all or out of range
327 {
328 m_text->SetValue(text);
329 m_text->SetSelection(0, -1);
330 }
331}
332
333void wxSpinCtrl::SetRange(int min, int max)
334{
335 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
336
337 m_btn->SetRange(min, max);
338}
339
3379ed37 340#endif // !wxPort-with-native-spinctrl