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