]> git.saurik.com Git - wxWidgets.git/blame - src/generic/spinctlg.cpp
applied patch 439186 (mingw and VC5 fixes)
[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
3379ed37
VZ
31#if !(defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__)) || \
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);
150
151 m_text = new wxSpinCtrlText(this, value);
152 m_btn = new wxSpinCtrlButton(this, style);
153
154 m_btn->SetRange(min, max);
155 m_btn->SetValue(initial);
156
157 DoSetSize(pos.x, pos.y, size.x, size.y);
158
159 // have to disable this window to avoid interfering it with message
160 // processing to the text and the button... but pretend it is enabled to
161 // make IsEnabled() return TRUE
162 wxControl::Enable(FALSE); // don't use non virtual Disable() here!
163 m_isEnabled = TRUE;
164
165 // we don't even need to show this window itself - and not doing it avoids
166 // that it overwrites the text control
167 wxControl::Show(FALSE);
168 m_isShown = TRUE;
169
170 return TRUE;
171}
172
173wxSpinCtrl::~wxSpinCtrl()
174{
175 // delete the controls now, don't leave them alive even though they woudl
176 // still be eventually deleted by our parent - but it will be too late, the
177 // user code expects them to be gone now
178 delete m_text;
179 delete m_btn;
180}
181
182// ----------------------------------------------------------------------------
183// geometry
184// ----------------------------------------------------------------------------
185
186wxSize wxSpinCtrl::DoGetBestClientSize() const
187{
188 wxSize sizeBtn = m_btn->GetBestSize(),
189 sizeText = m_text->GetBestSize();
190
191 return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
192}
193
194void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
195{
196 wxControl::DoMoveWindow(x, y, width, height);
197
198 // position the subcontrols inside the client area
3379ed37 199 wxSize sizeBtn = m_btn->GetSize();
21709999
JS
200
201 wxCoord wText = width - sizeBtn.x;
202 m_text->SetSize(x, y, wText, height);
203 m_btn->SetSize(x + wText + MARGIN, y, -1, height);
204}
205
206// ----------------------------------------------------------------------------
207// operations forwarded to the subcontrols
208// ----------------------------------------------------------------------------
209
210bool wxSpinCtrl::Enable(bool enable)
211{
212 if ( !wxControl::Enable(enable) )
213 return FALSE;
214
215 m_btn->Enable(enable);
216 m_text->Enable(enable);
217
218 return TRUE;
219}
220
221bool wxSpinCtrl::Show(bool show)
222{
223 if ( !wxControl::Show(show) )
224 return FALSE;
225
3379ed37
VZ
226 // under GTK Show() is called the first time before we are fully
227 // constructed
228 if ( m_btn )
229 {
230 m_btn->Show(show);
231 m_text->Show(show);
232 }
21709999
JS
233
234 return TRUE;
235}
236
237// ----------------------------------------------------------------------------
238// value and range access
239// ----------------------------------------------------------------------------
240
241bool wxSpinCtrl::GetTextValue(int *val) const
242{
243 long l;
244 if ( !m_text->GetValue().ToLong(&l) )
245 {
246 // not a number at all
247 return FALSE;
248 }
249
250 if ( l < GetMin() || l > GetMax() )
251 {
252 // out of range
253 return FALSE;
254 }
255
256 *val = l;
257
258 return TRUE;
259}
260
261int wxSpinCtrl::GetValue() const
262{
263 return m_btn ? m_btn->GetValue() : 0;
264}
265
266int wxSpinCtrl::GetMin() const
267{
268 return m_btn ? m_btn->GetMin() : 0;
269}
270
271int wxSpinCtrl::GetMax() const
272{
273 return m_btn ? m_btn->GetMax() : 0;
274}
275
276// ----------------------------------------------------------------------------
277// changing value and range
278// ----------------------------------------------------------------------------
279
280void wxSpinCtrl::SetTextValue(int val)
281{
282 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
283
284 m_text->SetValue(wxString::Format(_T("%d"), val));
285
286 // select all text
287 m_text->SetSelection(0, -1);
288
289 // and give focus to the control!
290 m_text->SetFocus();
291}
292
293void wxSpinCtrl::SetValue(int val)
294{
295 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
296
297 SetTextValue(val);
298
299 m_btn->SetValue(val);
300}
301
302void wxSpinCtrl::SetValue(const wxString& text)
303{
304 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
305
306 long val;
307 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
308 {
309 SetValue((int)val);
310 }
311 else // not a number at all or out of range
312 {
313 m_text->SetValue(text);
314 m_text->SetSelection(0, -1);
315 }
316}
317
318void wxSpinCtrl::SetRange(int min, int max)
319{
320 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
321
322 m_btn->SetRange(min, max);
323}
324
3379ed37 325#endif // !wxPort-with-native-spinctrl