]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/spinctrl.cpp
Refresh is necessary in earlier systems, no penalty when doing in 10.3+
[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
327788ac 28// the margin between the text control and the spin
3109d198 29static const wxCoord MARGIN = 8;
a842a96e 30
327788ac
SC
31// ----------------------------------------------------------------------------
32// wxSpinCtrlText: text control used by spin control
33// ----------------------------------------------------------------------------
a842a96e 34
327788ac
SC
35class wxSpinCtrlText : public wxTextCtrl
36{
37public:
38 wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
3109d198 39 : wxTextCtrl(spin , -1, value, wxDefaultPosition, wxSize(40, 22))
327788ac
SC
40 {
41 m_spin = spin;
571d14b2
RD
42
43 // remove the default minsize, the spinctrl will have one instead
44 SetSizeHints(-1,-1);
327788ac
SC
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;
327788ac 89 SetWindowStyle(style | wxSP_VERTICAL);
571d14b2
RD
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.
3109d198 95 //SetWindowVariant(wxWINDOW_VARIANT_SMALL);
571d14b2
RD
96
97 // remove the default minsize, the spinctrl will have one instead
98 SetSizeHints(-1,-1);
327788ac 99 }
a5bc50ee 100
327788ac
SC
101protected:
102 void OnSpinButton(wxSpinEvent& eventSpin)
103 {
327788ac 104 m_spin->SetTextValue(eventSpin.GetPosition());
a5bc50ee 105
327788ac
SC
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);
327788ac
SC
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{
3109d198
KO
150 m_macIsUserPane = true;
151 if ( !wxControl::Create(parent, id, pos, size, style,
327788ac
SC
152 wxDefaultValidator, name) )
153 {
154 return FALSE;
155 }
156
157 // the string value overrides the numeric one (for backwards compatibility
158 // reasons and also because it is simpler to satisfy the string value which
159 // comes much sooner in the list of arguments and leave the initial
160 // parameter unspecified)
161 if ( !value.empty() )
162 {
163 long l;
164 if ( value.ToLong(&l) )
165 initial = l;
166 }
167
168 wxSize csize = size ;
169 m_text = new wxSpinCtrlText(this, value);
170 m_btn = new wxSpinCtrlButton(this, style);
3109d198 171
327788ac
SC
172 m_btn->SetRange(min, max);
173 m_btn->SetValue(initial);
174
3109d198
KO
175 if ( size.x == -1 ){
176 csize.x = m_text->GetSize().x + MARGIN + m_btn->GetSize().x ;
177 }
178
327788ac 179 if ( size.y == -1 ) {
3109d198 180 csize.y = m_text->GetSize().y + 4; //allow for text border highlights
327788ac 181 }
3109d198
KO
182
183 //SetSize(csize);
184
185 MacPostControlCreate(pos, csize);
186 SetInitialBestSize(csize);
327788ac
SC
187
188 return TRUE;
189}
190
191wxSpinCtrl::~wxSpinCtrl()
192{
193 // delete the controls now, don't leave them alive even though they would
194 // still be eventually deleted by our parent - but it will be too late, the
195 // user code expects them to be gone now
196 delete m_text;
197 m_text = NULL ;
198 delete m_btn;
199 m_btn = NULL ;
200}
201
202// ----------------------------------------------------------------------------
203// geometry
204// ----------------------------------------------------------------------------
205
206wxSize wxSpinCtrl::DoGetBestSize() const
207{
51e14ebe
JS
208 if (!m_btn || !m_text)
209 return GetSize();
210
327788ac
SC
211 wxSize sizeBtn = m_btn->GetBestSize(),
212 sizeText = m_text->GetBestSize();
213
3109d198
KO
214 int height;
215 if (sizeText.y > sizeBtn.y)
216 height = sizeText.y;
217 else
218 height = sizeBtn.y;
219
220 return wxSize(sizeBtn.x + sizeText.x + MARGIN, height + MARGIN);
327788ac
SC
221}
222
223void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
224{
327788ac
SC
225 // position the subcontrols inside the client area
226 wxSize sizeBtn = m_btn->GetSize();
3109d198
KO
227
228 wxControl::DoMoveWindow(x, y, width, height);
327788ac 229
3109d198
KO
230 wxCoord wText = width - sizeBtn.x - MARGIN;
231
232 //growing or shrinking a control like this doesn't really make sense
233 //so just leave the controls the same size and add whitespace
234 m_text->SetSize(2, 2, wText, 22);
571d14b2 235 m_btn->SetSize(0 + wText + MARGIN, 0, -1, height);
327788ac
SC
236}
237
238// ----------------------------------------------------------------------------
239// operations forwarded to the subcontrols
240// ----------------------------------------------------------------------------
241
242bool wxSpinCtrl::Enable(bool enable)
243{
244 if ( !wxControl::Enable(enable) )
245 return FALSE;
246 return TRUE;
247}
248
249bool wxSpinCtrl::Show(bool show)
250{
251 if ( !wxControl::Show(show) )
252 return FALSE;
253 return TRUE;
254}
255
256// ----------------------------------------------------------------------------
257// value and range access
258// ----------------------------------------------------------------------------
259
260bool wxSpinCtrl::GetTextValue(int *val) const
261{
262 long l;
263 if ( !m_text->GetValue().ToLong(&l) )
264 {
265 // not a number at all
266 return FALSE;
267 }
268
269 if ( l < GetMin() || l > GetMax() )
270 {
271 // out of range
272 return FALSE;
273 }
274
275 *val = l;
276
277 return TRUE;
278}
279
280int wxSpinCtrl::GetValue() const
281{
282 return m_btn ? m_btn->GetValue() : 0;
283}
284
285int wxSpinCtrl::GetMin() const
286{
287 return m_btn ? m_btn->GetMin() : 0;
288}
289
290int wxSpinCtrl::GetMax() const
291{
292 return m_btn ? m_btn->GetMax() : 0;
293}
294
295// ----------------------------------------------------------------------------
296// changing value and range
297// ----------------------------------------------------------------------------
298
299void wxSpinCtrl::SetTextValue(int val)
300{
301 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
302
303 m_text->SetValue(wxString::Format(_T("%d"), val));
304
305 // select all text
306 m_text->SetSelection(0, -1);
307
308 // and give focus to the control!
309 // m_text->SetFocus(); Why???? TODO.
310}
311
312void wxSpinCtrl::SetValue(int val)
313{
314 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
315
316 SetTextValue(val);
317
318 m_btn->SetValue(val);
319}
320
321void wxSpinCtrl::SetValue(const wxString& text)
322{
323 wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
324
325 long val;
326 if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
327 {
328 SetValue((int)val);
329 }
330 else // not a number at all or out of range
331 {
332 m_text->SetValue(text);
333 m_text->SetSelection(0, -1);
334 }
335}
336
337void wxSpinCtrl::SetRange(int min, int max)
338{
339 wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
9453cf2b 340
327788ac
SC
341 m_btn->SetRange(min, max);
342}
a5bc50ee 343
a811affe
GD
344void wxSpinCtrl::SetSelection(long from, long to)
345{
77ffb593 346 // if from and to are both -1, it means (in wxWidgets) that all text should
a811affe
GD
347 // be selected
348 if ( (from == -1) && (to == -1) )
349 {
350 from = 0;
351 }
352 m_text->SetSelection(from, to);
353}
354
327788ac 355#endif // wxUSE_SPINCTRL