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