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