]> git.saurik.com Git - wxWidgets.git/blame - src/generic/spinctlg.cpp
rename fobr95.{cpp,h} files to foobar.{cpp,h}
[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>
65571936 9// License: wxWindows licence
21709999
JS
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
21709999
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
571d14b2
RD
27// There are port-specific versions for MSW, GTK, OS/2 and Mac, so exclude the
28// contents of this file in those cases
29#if !(defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__) || \
30 defined(__WXMAC__)) || defined(__WXUNIVERSAL__)
21709999
JS
31
32#ifndef WX_PRECOMP
33 #include "wx/textctrl.h"
34#endif //WX_PRECOMP
35
c67d6888
JS
36#if wxUSE_SPINCTRL
37
21709999
JS
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)
3fb79396 56 : wxTextCtrl(spin->GetParent(), wxID_ANY, value)
21709999
JS
57 {
58 m_spin = spin;
ca65c044 59
e459a794 60 // remove the default minsize, the spinctrl will have one instead
422d0ff0 61 SetSizeHints(wxDefaultCoord,wxDefaultCoord);
21709999
JS
62 }
63
64protected:
65 void OnTextChange(wxCommandEvent& event)
66 {
67 int val;
68 if ( m_spin->GetTextValue(&val) )
69 {
70 m_spin->GetSpinButton()->SetValue(val);
71 }
72
73 event.Skip();
74 }
71e03035 75
23d416bf
RR
76 bool ProcessEvent(wxEvent &event)
77 {
78 // Hand button down events to wxSpinCtrl. Doesn't work.
79 if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
3fb79396 80 return true;
71e03035 81
23d416bf
RR
82 return wxTextCtrl::ProcessEvent( event );
83 }
21709999
JS
84
85private:
86 wxSpinCtrl *m_spin;
87
88 DECLARE_EVENT_TABLE()
89};
90
91BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
3fb79396 92 EVT_TEXT(wxID_ANY, wxSpinCtrlText::OnTextChange)
21709999
JS
93END_EVENT_TABLE()
94
95// ----------------------------------------------------------------------------
96// wxSpinCtrlButton: spin button used by spin control
97// ----------------------------------------------------------------------------
98
99class wxSpinCtrlButton : public wxSpinButton
100{
101public:
102 wxSpinCtrlButton(wxSpinCtrl *spin, int style)
103 : wxSpinButton(spin->GetParent())
104 {
105 m_spin = spin;
106
71e03035 107 SetWindowStyle(style | wxSP_VERTICAL);
e459a794
RD
108
109 // remove the default minsize, the spinctrl will have one instead
422d0ff0 110 SetSizeHints(wxDefaultCoord,wxDefaultCoord);
21709999
JS
111 }
112
113protected:
63efc55f 114 void OnSpinButton(wxSpinEvent& eventSpin)
21709999 115 {
c1eb1102 116 m_spin->SetTextValue(eventSpin.GetPosition());
63efc55f 117
c1eb1102
VZ
118 wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId());
119 event.SetEventObject(m_spin);
120 event.SetInt(eventSpin.GetPosition());
121
122 m_spin->GetEventHandler()->ProcessEvent(event);
21709999 123
5d0000b5 124 eventSpin.Skip();
21709999
JS
125 }
126
127private:
128 wxSpinCtrl *m_spin;
129
130 DECLARE_EVENT_TABLE()
131};
132
133BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
3fb79396 134 EVT_SPIN(wxID_ANY, wxSpinCtrlButton::OnSpinButton)
21709999
JS
135END_EVENT_TABLE()
136
137IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
739555e3 138
21709999
JS
139// ============================================================================
140// implementation
141// ============================================================================
142
143// ----------------------------------------------------------------------------
144// wxSpinCtrl creation
145// ----------------------------------------------------------------------------
146
147void wxSpinCtrl::Init()
148{
149 m_text = NULL;
150 m_btn = NULL;
151}
152
153bool wxSpinCtrl::Create(wxWindow *parent,
154 wxWindowID id,
155 const wxString& value,
9cb6c9a0 156 const wxPoint& pos,
21709999
JS
157 const wxSize& size,
158 long style,
159 int min,
160 int max,
161 int initial,
162 const wxString& name)
163{
094ca819 164 if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style,
21709999
JS
165 wxDefaultValidator, name) )
166 {
3fb79396 167 return false;
21709999
JS
168 }
169
71e03035
VZ
170 // the string value overrides the numeric one (for backwards compatibility
171 // reasons and also because it is simpler to satisfy the string value which
172 // comes much sooner in the list of arguments and leave the initial
173 // parameter unspecified)
174 if ( !value.empty() )
175 {
176 long l;
177 if ( value.ToLong(&l) )
178 initial = l;
179 }
180
21709999
JS
181 m_text = new wxSpinCtrlText(this, value);
182 m_btn = new wxSpinCtrlButton(this, style);
ca65c044 183
21709999
JS
184 m_btn->SetRange(min, max);
185 m_btn->SetValue(initial);
170acdc9 186 SetInitialSize(size);
9cb6c9a0 187 Move(pos);
ca65c044 188
21709999
JS
189 // have to disable this window to avoid interfering it with message
190 // processing to the text and the button... but pretend it is enabled to
3fb79396
WS
191 // make IsEnabled() return true
192 wxControl::Enable(false); // don't use non virtual Disable() here!
193 m_isEnabled = true;
21709999
JS
194
195 // we don't even need to show this window itself - and not doing it avoids
196 // that it overwrites the text control
3fb79396
WS
197 wxControl::Show(false);
198 m_isShown = true;
199 return true;
21709999
JS
200}
201
202wxSpinCtrl::~wxSpinCtrl()
203{
e459a794 204 // delete the controls now, don't leave them alive even though they would
21709999
JS
205 // still be eventually deleted by our parent - but it will be too late, the
206 // user code expects them to be gone now
207 delete m_text;
e459a794 208 m_text = NULL ;
21709999 209 delete m_btn;
e459a794 210 m_btn = NULL ;
21709999
JS
211}
212
213// ----------------------------------------------------------------------------
214// geometry
215// ----------------------------------------------------------------------------
216
dba00620 217wxSize wxSpinCtrl::DoGetBestSize() const
21709999
JS
218{
219 wxSize sizeBtn = m_btn->GetBestSize(),
220 sizeText = m_text->GetBestSize();
221
222 return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
223}
224
225void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
226{
227 wxControl::DoMoveWindow(x, y, width, height);
228
229 // position the subcontrols inside the client area
3379ed37 230 wxSize sizeBtn = m_btn->GetSize();
21709999
JS
231
232 wxCoord wText = width - sizeBtn.x;
e466fe5f 233 m_text->SetSize(x, y, wText, height);
422d0ff0 234 m_btn->SetSize(x + wText + MARGIN, y, wxDefaultCoord, height);
21709999
JS
235}
236
237// ----------------------------------------------------------------------------
238// operations forwarded to the subcontrols
239// ----------------------------------------------------------------------------
240
241bool wxSpinCtrl::Enable(bool enable)
242{
243 if ( !wxControl::Enable(enable) )
3fb79396 244 return false;
21709999
JS
245
246 m_btn->Enable(enable);
247 m_text->Enable(enable);
248
3fb79396 249 return true;
21709999
JS
250}
251
252bool wxSpinCtrl::Show(bool show)
253{
254 if ( !wxControl::Show(show) )
3fb79396 255 return false;
21709999 256
3379ed37
VZ
257 // under GTK Show() is called the first time before we are fully
258 // constructed
259 if ( m_btn )
260 {
261 m_btn->Show(show);
262 m_text->Show(show);
263 }
21709999 264
3fb79396 265 return true;
21709999
JS
266}
267
03d4194d
VZ
268bool wxSpinCtrl::Reparent(wxWindow *newParent)
269{
270 if ( m_btn )
271 {
272 m_btn->Reparent(newParent);
273 m_text->Reparent(newParent);
274 }
275
276 return true;
277}
278
21709999
JS
279// ----------------------------------------------------------------------------
280// value and range access
281// ----------------------------------------------------------------------------
282
283bool wxSpinCtrl::GetTextValue(int *val) const
284{
285 long l;
286 if ( !m_text->GetValue().ToLong(&l) )
287 {
288 // not a number at all
3fb79396 289 return false;
21709999
JS
290 }
291
292 if ( l < GetMin() || l > GetMax() )
293 {
294 // out of range
3fb79396 295 return false;
21709999
JS
296 }
297
298 *val = l;
299
3fb79396 300 return true;
21709999
JS
301}
302
303int wxSpinCtrl::GetValue() const
304{
305 return m_btn ? m_btn->GetValue() : 0;
306}
307
308int wxSpinCtrl::GetMin() const
309{
310 return m_btn ? m_btn->GetMin() : 0;
311}
312
313int wxSpinCtrl::GetMax() const
314{
315 return m_btn ? m_btn->GetMax() : 0;
316}
317
318// ----------------------------------------------------------------------------
319// changing value and range
320// ----------------------------------------------------------------------------
321
322void wxSpinCtrl::SetTextValue(int val)
323{
324 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
325
326 m_text->SetValue(wxString::Format(_T("%d"), val));
327
328 // select all text
329 m_text->SetSelection(0, -1);
330
331 // and give focus to the control!
d45906e0 332 // m_text->SetFocus(); Why???? TODO.
21709999
JS
333}
334
335void wxSpinCtrl::SetValue(int val)
336{
337 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
338
339 SetTextValue(val);
340
341 m_btn->SetValue(val);
342}
343
344void wxSpinCtrl::SetValue(const wxString& text)
345{
346 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
347
348 long val;
349 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
350 {
351 SetValue((int)val);
352 }
353 else // not a number at all or out of range
354 {
355 m_text->SetValue(text);
356 m_text->SetSelection(0, -1);
357 }
358}
359
360void wxSpinCtrl::SetRange(int min, int max)
361{
362 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
363
364 m_btn->SetRange(min, max);
365}
366
739555e3
VZ
367void wxSpinCtrl::SetSelection(long from, long to)
368{
369 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetSelection") );
370
371 m_text->SetSelection(from, to);
372}
373
c67d6888 374#endif // wxUSE_SPINCTRL
3379ed37 375#endif // !wxPort-with-native-spinctrl