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