]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/spinctrl.cpp
Test commit
[wxWidgets.git] / src / mac / classic / spinctrl.cpp
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 #include "wx/defs.h"
12
13 #ifndef WX_PRECOMP
14 #include "wx/textctrl.h"
15 #endif //WX_PRECOMP
16
17 #if wxUSE_SPINCTRL
18
19 #include "wx/spinbutt.h"
20 #include "wx/spinctrl.h"
21
22
23 #include "wx/spinctrl.h"
24
25 // ----------------------------------------------------------------------------
26 // constants
27 // ----------------------------------------------------------------------------
28
29 // the margin between the text control and the spin
30 static const wxCoord MARGIN = 2;
31
32 // ----------------------------------------------------------------------------
33 // wxSpinCtrlText: text control used by spin control
34 // ----------------------------------------------------------------------------
35
36 class wxSpinCtrlText : public wxTextCtrl
37 {
38 public:
39 wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
40 : wxTextCtrl(spin , -1, value)
41 {
42 m_spin = spin;
43 }
44
45 protected:
46 void OnTextChange(wxCommandEvent& event)
47 {
48 int val;
49 if ( m_spin->GetTextValue(&val) )
50 {
51 m_spin->GetSpinButton()->SetValue(val);
52 }
53
54 event.Skip();
55 }
56
57 bool ProcessEvent(wxEvent &event)
58 {
59 // Hand button down events to wxSpinCtrl. Doesn't work.
60 if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
61 return TRUE;
62
63 return wxTextCtrl::ProcessEvent( event );
64 }
65
66 private:
67 wxSpinCtrl *m_spin;
68
69 DECLARE_EVENT_TABLE()
70 };
71
72 BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
73 EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
74 END_EVENT_TABLE()
75
76 // ----------------------------------------------------------------------------
77 // wxSpinCtrlButton: spin button used by spin control
78 // ----------------------------------------------------------------------------
79
80 class wxSpinCtrlButton : public wxSpinButton
81 {
82 public:
83 wxSpinCtrlButton(wxSpinCtrl *spin, int style)
84 : wxSpinButton(spin )
85 {
86 m_spin = spin;
87
88 SetWindowStyle(style | wxSP_VERTICAL);
89 }
90
91 protected:
92 void OnSpinButton(wxSpinEvent& eventSpin)
93 {
94 #if defined(__WXMAC__) || defined(__WXMOTIF__)
95 m_spin->SetTextValue(eventSpin.GetPosition());
96
97 wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId());
98 event.SetEventObject(m_spin);
99 event.SetInt(eventSpin.GetPosition());
100
101 m_spin->GetEventHandler()->ProcessEvent(event);
102 #else
103 m_spin->SetTextValue(eventSpin.GetPosition());
104 eventSpin.Skip();
105 #endif
106 }
107
108 private:
109 wxSpinCtrl *m_spin;
110
111 DECLARE_EVENT_TABLE()
112 };
113
114 BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
115 EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
116 END_EVENT_TABLE()
117
118 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
119
120 // ============================================================================
121 // implementation
122 // ============================================================================
123
124 // ----------------------------------------------------------------------------
125 // wxSpinCtrl creation
126 // ----------------------------------------------------------------------------
127
128 void wxSpinCtrl::Init()
129 {
130 m_text = NULL;
131 m_btn = NULL;
132 }
133
134 bool wxSpinCtrl::Create(wxWindow *parent,
135 wxWindowID id,
136 const wxString& value,
137 const wxPoint& pos,
138 const wxSize& size,
139 long style,
140 int min,
141 int max,
142 int initial,
143 const wxString& name)
144 {
145 if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style,
146 wxDefaultValidator, name) )
147 {
148 return FALSE;
149 }
150
151 // the string value overrides the numeric one (for backwards compatibility
152 // reasons and also because it is simpler to satisfy the string value which
153 // comes much sooner in the list of arguments and leave the initial
154 // parameter unspecified)
155 if ( !value.empty() )
156 {
157 long l;
158 if ( value.ToLong(&l) )
159 initial = l;
160 }
161
162 wxSize csize = size ;
163 m_text = new wxSpinCtrlText(this, value);
164 m_btn = new wxSpinCtrlButton(this, style);
165
166 m_btn->SetRange(min, max);
167 m_btn->SetValue(initial);
168
169 if ( size.y == -1 ) {
170 csize.y = m_text->GetSize().y ;
171 }
172 DoSetSize(pos.x , pos.y , csize.x, csize.y);
173
174 return TRUE;
175 }
176
177 wxSpinCtrl::~wxSpinCtrl()
178 {
179 // delete the controls now, don't leave them alive even though they would
180 // still be eventually deleted by our parent - but it will be too late, the
181 // user code expects them to be gone now
182 delete m_text;
183 m_text = NULL ;
184 delete m_btn;
185 m_btn = NULL ;
186 }
187
188 // ----------------------------------------------------------------------------
189 // geometry
190 // ----------------------------------------------------------------------------
191
192 wxSize wxSpinCtrl::DoGetBestSize() const
193 {
194 wxSize sizeBtn = m_btn->GetBestSize(),
195 sizeText = m_text->GetBestSize();
196
197 return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
198 }
199
200 void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
201 {
202 wxControl::DoMoveWindow(x, y, width, height);
203
204 // position the subcontrols inside the client area
205 wxSize sizeBtn = m_btn->GetSize();
206
207 wxCoord wText = width - sizeBtn.x;
208 m_text->SetSize(0, 0, wText, height);
209 m_btn->SetSize(0 + wText + MARGIN, 0, -1, -1);
210 }
211
212 // ----------------------------------------------------------------------------
213 // operations forwarded to the subcontrols
214 // ----------------------------------------------------------------------------
215
216 bool wxSpinCtrl::Enable(bool enable)
217 {
218 if ( !wxControl::Enable(enable) )
219 return FALSE;
220 return TRUE;
221 }
222
223 bool wxSpinCtrl::Show(bool show)
224 {
225 if ( !wxControl::Show(show) )
226 return FALSE;
227 return TRUE;
228 }
229
230 // ----------------------------------------------------------------------------
231 // value and range access
232 // ----------------------------------------------------------------------------
233
234 bool wxSpinCtrl::GetTextValue(int *val) const
235 {
236 long l;
237 if ( !m_text->GetValue().ToLong(&l) )
238 {
239 // not a number at all
240 return FALSE;
241 }
242
243 if ( l < GetMin() || l > GetMax() )
244 {
245 // out of range
246 return FALSE;
247 }
248
249 *val = l;
250
251 return TRUE;
252 }
253
254 int wxSpinCtrl::GetValue() const
255 {
256 return m_btn ? m_btn->GetValue() : 0;
257 }
258
259 int wxSpinCtrl::GetMin() const
260 {
261 return m_btn ? m_btn->GetMin() : 0;
262 }
263
264 int wxSpinCtrl::GetMax() const
265 {
266 return m_btn ? m_btn->GetMax() : 0;
267 }
268
269 // ----------------------------------------------------------------------------
270 // changing value and range
271 // ----------------------------------------------------------------------------
272
273 void wxSpinCtrl::SetTextValue(int val)
274 {
275 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
276
277 m_text->SetValue(wxString::Format(_T("%d"), val));
278
279 // select all text
280 m_text->SetSelection(0, -1);
281
282 // and give focus to the control!
283 // m_text->SetFocus(); Why???? TODO.
284 }
285
286 void wxSpinCtrl::SetValue(int val)
287 {
288 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
289
290 SetTextValue(val);
291
292 m_btn->SetValue(val);
293 }
294
295 void wxSpinCtrl::SetValue(const wxString& text)
296 {
297 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
298
299 long val;
300 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
301 {
302 SetValue((int)val);
303 }
304 else // not a number at all or out of range
305 {
306 m_text->SetValue(text);
307 m_text->SetSelection(0, -1);
308 }
309 }
310
311 void wxSpinCtrl::SetRange(int min, int max)
312 {
313 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
314
315 m_btn->SetRange(min, max);
316 }
317
318 void wxSpinCtrl::SetSelection(long from, long to)
319 {
320 // if from and to are both -1, it means (in wxWidgets) that all text should
321 // be selected
322 if ( (from == -1) && (to == -1) )
323 {
324 from = 0;
325 }
326 m_text->SetSelection(from, to);
327 }
328
329 #endif // wxUSE_SPINCTRL