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