]> git.saurik.com Git - wxWidgets.git/blame - src/generic/spinctlg.cpp
1. added --enable-gtk2 option, check for GTK+ 2.0 disabled by default
[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
31#if !wxUSE_SPINBTN
32 #error "This file can only be compiled if wxSpinButton is available"
33#endif // !wxUSE_SPINBTN
34
35#ifndef WX_PRECOMP
36 #include "wx/textctrl.h"
37#endif //WX_PRECOMP
38
39#include "wx/spinbutt.h"
40#include "wx/spinctrl.h"
41
42// ----------------------------------------------------------------------------
43// constants
44// ----------------------------------------------------------------------------
45
46// the margin between the text control and the spin
47static const wxCoord MARGIN = 2;
48
49// ----------------------------------------------------------------------------
50// wxSpinCtrlText: text control used by spin control
51// ----------------------------------------------------------------------------
52
53class wxSpinCtrlText : public wxTextCtrl
54{
55public:
56 wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
57 : wxTextCtrl(spin->GetParent(), -1, value)
58 {
59 m_spin = spin;
60 }
61
62protected:
63 void OnTextChange(wxCommandEvent& event)
64 {
65 int val;
66 if ( m_spin->GetTextValue(&val) )
67 {
68 m_spin->GetSpinButton()->SetValue(val);
69 }
70
71 event.Skip();
72 }
73
74private:
75 wxSpinCtrl *m_spin;
76
77 DECLARE_EVENT_TABLE()
78};
79
80BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
81 EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
82END_EVENT_TABLE()
83
84// ----------------------------------------------------------------------------
85// wxSpinCtrlButton: spin button used by spin control
86// ----------------------------------------------------------------------------
87
88class wxSpinCtrlButton : public wxSpinButton
89{
90public:
91 wxSpinCtrlButton(wxSpinCtrl *spin, int style)
92 : wxSpinButton(spin->GetParent())
93 {
94 m_spin = spin;
95
96 SetWindowStyle(style);
97 }
98
99protected:
100 void OnSpinButton(wxSpinEvent& event)
101 {
102 m_spin->SetTextValue(event.GetPosition());
103
104 event.Skip();
105 }
106
107private:
108 wxSpinCtrl *m_spin;
109
110 DECLARE_EVENT_TABLE()
111};
112
113BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
114 EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
115END_EVENT_TABLE()
116
117IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
118
119// ============================================================================
120// implementation
121// ============================================================================
122
123// ----------------------------------------------------------------------------
124// wxSpinCtrl creation
125// ----------------------------------------------------------------------------
126
127void wxSpinCtrl::Init()
128{
129 m_text = NULL;
130 m_btn = NULL;
131}
132
133bool wxSpinCtrl::Create(wxWindow *parent,
134 wxWindowID id,
135 const wxString& value,
136 const wxPoint& pos,
137 const wxSize& size,
138 long style,
139 int min,
140 int max,
141 int initial,
142 const wxString& name)
143{
144 if ( !wxControl::Create(parent, id, pos, size, style,
145 wxDefaultValidator, name) )
146 {
147 return FALSE;
148 }
149
150 SetBackgroundColour(*wxRED);
151
152 m_text = new wxSpinCtrlText(this, value);
153 m_btn = new wxSpinCtrlButton(this, style);
154
155 m_btn->SetRange(min, max);
156 m_btn->SetValue(initial);
157
158 DoSetSize(pos.x, pos.y, size.x, size.y);
159
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
200 wxSize sizeBtn = m_btn->GetSize(),
201 sizeText = m_text->GetSize();
202
203 wxCoord wText = width - sizeBtn.x;
204 m_text->SetSize(x, y, wText, height);
205 m_btn->SetSize(x + wText + MARGIN, y, -1, height);
206}
207
208// ----------------------------------------------------------------------------
209// operations forwarded to the subcontrols
210// ----------------------------------------------------------------------------
211
212bool wxSpinCtrl::Enable(bool enable)
213{
214 if ( !wxControl::Enable(enable) )
215 return FALSE;
216
217 m_btn->Enable(enable);
218 m_text->Enable(enable);
219
220 return TRUE;
221}
222
223bool wxSpinCtrl::Show(bool show)
224{
225 if ( !wxControl::Show(show) )
226 return FALSE;
227
228 m_btn->Show(show);
229 m_text->Show(show);
230
231 return TRUE;
232}
233
234// ----------------------------------------------------------------------------
235// value and range access
236// ----------------------------------------------------------------------------
237
238bool wxSpinCtrl::GetTextValue(int *val) const
239{
240 long l;
241 if ( !m_text->GetValue().ToLong(&l) )
242 {
243 // not a number at all
244 return FALSE;
245 }
246
247 if ( l < GetMin() || l > GetMax() )
248 {
249 // out of range
250 return FALSE;
251 }
252
253 *val = l;
254
255 return TRUE;
256}
257
258int wxSpinCtrl::GetValue() const
259{
260 return m_btn ? m_btn->GetValue() : 0;
261}
262
263int wxSpinCtrl::GetMin() const
264{
265 return m_btn ? m_btn->GetMin() : 0;
266}
267
268int wxSpinCtrl::GetMax() const
269{
270 return m_btn ? m_btn->GetMax() : 0;
271}
272
273// ----------------------------------------------------------------------------
274// changing value and range
275// ----------------------------------------------------------------------------
276
277void wxSpinCtrl::SetTextValue(int val)
278{
279 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
280
281 m_text->SetValue(wxString::Format(_T("%d"), val));
282
283 // select all text
284 m_text->SetSelection(0, -1);
285
286 // and give focus to the control!
287 m_text->SetFocus();
288}
289
290void wxSpinCtrl::SetValue(int val)
291{
292 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
293
294 SetTextValue(val);
295
296 m_btn->SetValue(val);
297}
298
299void wxSpinCtrl::SetValue(const wxString& text)
300{
301 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
302
303 long val;
304 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
305 {
306 SetValue((int)val);
307 }
308 else // not a number at all or out of range
309 {
310 m_text->SetValue(text);
311 m_text->SetSelection(0, -1);
312 }
313}
314
315void wxSpinCtrl::SetRange(int min, int max)
316{
317 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
318
319 m_btn->SetRange(min, max);
320}
321