]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/spinctrl.cpp
several patches and extensions
[wxWidgets.git] / src / mac / spinctrl.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: spinbutt.cpp
3// Purpose: wxSpinCtrl
4// Author: Robert
5// Modified by: Mark Newsam (Based on GTK file)
6// RCS-ID: $Id$
7// Copyright: (c) Robert Roebling
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifdef __GNUG__
12#pragma implementation "spinctlg.h"
13#endif
14
15#include "wx/defs.h"
16
17#ifndef WX_PRECOMP
18 #include "wx/textctrl.h"
19#endif //WX_PRECOMP
20
21#if wxUSE_SPINCTRL
22
23#include "wx/spinbutt.h"
24#include "wx/spinctrl.h"
25
26
27#include "wx/spinctrl.h"
28
29// ----------------------------------------------------------------------------
30// constants
31// ----------------------------------------------------------------------------
32
33// the margin between the text control and the spin
34static const wxCoord MARGIN = 2;
35
36// ----------------------------------------------------------------------------
37// wxSpinCtrlText: text control used by spin control
38// ----------------------------------------------------------------------------
39
40class wxSpinCtrlText : public wxTextCtrl
41{
42public:
43 wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
44 : wxTextCtrl(spin , -1, value)
45 {
46 m_spin = spin;
47 }
48
49protected:
50 void OnTextChange(wxCommandEvent& event)
51 {
52 int val;
53 if ( m_spin->GetTextValue(&val) )
54 {
55 m_spin->GetSpinButton()->SetValue(val);
56 }
57
58 event.Skip();
59 }
60
61 bool ProcessEvent(wxEvent &event)
62 {
63 // Hand button down events to wxSpinCtrl. Doesn't work.
64 if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
65 return TRUE;
66
67 return wxTextCtrl::ProcessEvent( event );
68 }
69
70private:
71 wxSpinCtrl *m_spin;
72
73 DECLARE_EVENT_TABLE()
74};
75
76BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
77 EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
78END_EVENT_TABLE()
79
80// ----------------------------------------------------------------------------
81// wxSpinCtrlButton: spin button used by spin control
82// ----------------------------------------------------------------------------
83
84class wxSpinCtrlButton : public wxSpinButton
85{
86public:
87 wxSpinCtrlButton(wxSpinCtrl *spin, int style)
88 : wxSpinButton(spin )
89 {
90 m_spin = spin;
91
92 SetWindowStyle(style | wxSP_VERTICAL);
93 }
94
95protected:
96 void OnSpinButton(wxSpinEvent& eventSpin)
97 {
98#if defined(__WXMAC__) || defined(__WXMOTIF__)
99 m_spin->SetTextValue(eventSpin.GetPosition());
100
101 wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId());
102 event.SetEventObject(m_spin);
103 event.SetInt(eventSpin.GetPosition());
104
105 m_spin->GetEventHandler()->ProcessEvent(event);
106#else
107 m_spin->SetTextValue(eventSpin.GetPosition());
108 eventSpin.Skip();
109#endif
110 }
111
112private:
113 wxSpinCtrl *m_spin;
114
115 DECLARE_EVENT_TABLE()
116};
117
118BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
119 EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
120END_EVENT_TABLE()
121
122IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
123
124// ============================================================================
125// implementation
126// ============================================================================
127
128// ----------------------------------------------------------------------------
129// wxSpinCtrl creation
130// ----------------------------------------------------------------------------
131
132void wxSpinCtrl::Init()
133{
134 m_text = NULL;
135 m_btn = NULL;
136}
137
138bool wxSpinCtrl::Create(wxWindow *parent,
139 wxWindowID id,
140 const wxString& value,
141 const wxPoint& pos,
142 const wxSize& size,
143 long style,
144 int min,
145 int max,
146 int initial,
147 const wxString& name)
148{
149 if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style,
150 wxDefaultValidator, name) )
151 {
152 return FALSE;
153 }
154
155 // the string value overrides the numeric one (for backwards compatibility
156 // reasons and also because it is simpler to satisfy the string value which
157 // comes much sooner in the list of arguments and leave the initial
158 // parameter unspecified)
159 if ( !value.empty() )
160 {
161 long l;
162 if ( value.ToLong(&l) )
163 initial = l;
164 }
165
166 wxSize csize = size ;
167 m_text = new wxSpinCtrlText(this, value);
168 m_btn = new wxSpinCtrlButton(this, style);
169
170 m_btn->SetRange(min, max);
171 m_btn->SetValue(initial);
172
173 if ( size.y == -1 ) {
174 csize.y = m_text->GetSize().y ;
175 }
176 DoSetSize(pos.x , pos.y , csize.x, csize.y);
177
178 return TRUE;
179}
180
181wxSpinCtrl::~wxSpinCtrl()
182{
183 // delete the controls now, don't leave them alive even though they would
184 // still be eventually deleted by our parent - but it will be too late, the
185 // user code expects them to be gone now
186 delete m_text;
187 m_text = NULL ;
188 delete m_btn;
189 m_btn = NULL ;
190}
191
192// ----------------------------------------------------------------------------
193// geometry
194// ----------------------------------------------------------------------------
195
196wxSize wxSpinCtrl::DoGetBestSize() const
197{
198 wxSize sizeBtn = m_btn->GetBestSize(),
199 sizeText = m_text->GetBestSize();
200
201 return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
202}
203
204void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
205{
206 wxControl::DoMoveWindow(x, y, width, height);
207
208 // position the subcontrols inside the client area
209 wxSize sizeBtn = m_btn->GetSize();
210
211 wxCoord wText = width - sizeBtn.x;
212 m_text->SetSize(0, 0, wText, height);
213 m_btn->SetSize(0 + wText + MARGIN, 0, -1, -1);
214}
215
216// ----------------------------------------------------------------------------
217// operations forwarded to the subcontrols
218// ----------------------------------------------------------------------------
219
220bool wxSpinCtrl::Enable(bool enable)
221{
222 if ( !wxControl::Enable(enable) )
223 return FALSE;
224 return TRUE;
225}
226
227bool wxSpinCtrl::Show(bool show)
228{
229 if ( !wxControl::Show(show) )
230 return FALSE;
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(); Why???? TODO.
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
322void wxSpinCtrl::SetSelection(long from, long to)
323{
324 // if from and to are both -1, it means (in wxWindows) that all text should
325 // be selected
326 if ( (from == -1) && (to == -1) )
327 {
328 from = 0;
329 }
330 m_text->SetSelection(from, to);
331}
332
333#endif // wxUSE_SPINCTRL