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