]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/slider.cpp
fixed selection when using keyboard after JS' change broke it
[wxWidgets.git] / src / mac / classic / slider.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/classic/slider.cpp
3 // Purpose: wxSlider
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_SLIDER
19
20 #include "wx/slider.h"
21 #include "wx/mac/uma.h"
22
23 IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
24
25 BEGIN_EVENT_TABLE(wxSlider, wxControl)
26 END_EVENT_TABLE()
27
28 // The dimensions of the different styles of sliders (From Aqua document)
29 #define wxSLIDER_DIMENSIONACROSS 15
30 #define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 24
31 #define wxSLIDER_DIMENSIONACROSS_ARROW 18
32
33 // Distance between slider and text
34 #define wxSLIDER_BORDERTEXT 5
35
36 /* NB! The default orientation for a slider is horizontal however if the user specifies
37 * some slider styles but dosen't specify the orientation we have to assume he wants a
38 * horizontal one. Therefore in this file when testing for the sliders orientation
39 * vertical is tested for if this is not set then we use the horizontal one
40 * eg. if(GetWindowStyle() & wxSL_VERTICAL) {} else { horizontal case }>
41 */
42
43 // Slider
44 wxSlider::wxSlider()
45 {
46 m_pageSize = 1;
47 m_lineSize = 1;
48 m_rangeMax = 0;
49 m_rangeMin = 0;
50 m_tickFreq = 0;
51 }
52
53 extern ControlActionUPP wxMacLiveScrollbarActionUPP ;
54
55 bool wxSlider::Create(wxWindow *parent, wxWindowID id,
56 int value, int minValue, int maxValue,
57 const wxPoint& pos,
58 const wxSize& size, long style,
59 const wxValidator& validator,
60 const wxString& name)
61 {
62 if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
63 return false;
64
65 Rect bounds ;
66 Str255 title ;
67 SInt16 procID;
68
69 m_macMinimumStatic = NULL ;
70 m_macMaximumStatic = NULL ;
71 m_macValueStatic = NULL ;
72
73
74 m_lineSize = 1;
75 m_tickFreq = 0;
76
77 m_rangeMax = maxValue;
78 m_rangeMin = minValue;
79
80 m_pageSize = (int)((maxValue-minValue)/10);
81
82 MacPreControlCreate( parent, id, wxEmptyString, pos, size, style,
83 validator, name, &bounds, title );
84
85 procID = kControlSliderProc + kControlSliderLiveFeedback;
86 if(style & wxSL_AUTOTICKS) {
87 procID += kControlSliderHasTickMarks;
88 }
89
90
91 m_macControl = (WXWidget) ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, title, false,
92 value, minValue, maxValue, procID, (long) this);
93
94 wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
95
96 ::SetControlAction( (ControlHandle) m_macControl , wxMacLiveScrollbarActionUPP ) ;
97
98 if(style & wxSL_LABELS)
99 {
100 m_macMinimumStatic = new wxStaticText( this, wxID_ANY, wxEmptyString );
101 m_macMaximumStatic = new wxStaticText( this, wxID_ANY, wxEmptyString );
102 m_macValueStatic = new wxStaticText( this, wxID_ANY, wxEmptyString );
103 SetRange(minValue, maxValue);
104 SetValue(value);
105 }
106
107 else {
108 m_macMinimumStatic = NULL ;
109 m_macMaximumStatic = NULL ;
110 m_macValueStatic = NULL ;
111 }
112
113 if(style & wxSL_VERTICAL) {
114 SetSizeHints(10, -1, 10, -1); // Forces SetSize to use the proper width
115 }
116 else {
117 SetSizeHints(-1, 10, -1, 10); // Forces SetSize to use the proper height
118 }
119 // NB! SetSizeHints is overloaded by wxSlider and will substitute 10 with the
120 // proper dimensions, it also means other people cannot bugger the slider with
121 // other values
122
123 MacPostControlCreate() ;
124
125 return true;
126 }
127
128 wxSlider::~wxSlider()
129 {
130 }
131
132 int wxSlider::GetValue() const
133 {
134 return GetControl32BitValue( (ControlHandle) m_macControl) ;
135 }
136
137 void wxSlider::SetValue(int value)
138 {
139 wxString valuestring ;
140 valuestring.Printf( wxT("%d") , value ) ;
141 if ( m_macValueStatic )
142 m_macValueStatic->SetLabel( valuestring ) ;
143 SetControl32BitValue( (ControlHandle) m_macControl , value ) ;
144 }
145
146 void wxSlider::SetRange(int minValue, int maxValue)
147 {
148 wxString value;
149
150 m_rangeMin = minValue;
151 m_rangeMax = maxValue;
152
153 SetControl32BitMinimum( (ControlHandle) m_macControl, m_rangeMin);
154 SetControl32BitMaximum( (ControlHandle) m_macControl, m_rangeMax);
155
156 if(m_macMinimumStatic) {
157 value.Printf(wxT("%d"), m_rangeMin);
158 m_macMinimumStatic->SetLabel(value);
159 }
160 if(m_macMaximumStatic) {
161 value.Printf(wxT("%d"), m_rangeMax);
162 m_macMaximumStatic->SetLabel(value);
163 }
164 SetValue(m_rangeMin);
165 }
166
167 // For trackbars only
168 void wxSlider::SetTickFreq(int n, int pos)
169 {
170 // TODO
171 m_tickFreq = n;
172 }
173
174 void wxSlider::SetPageSize(int pageSize)
175 {
176 // TODO
177 m_pageSize = pageSize;
178 }
179
180 int wxSlider::GetPageSize() const
181 {
182 return m_pageSize;
183 }
184
185 void wxSlider::ClearSel()
186 {
187 // TODO
188 }
189
190 void wxSlider::ClearTicks()
191 {
192 // TODO
193 }
194
195 void wxSlider::SetLineSize(int lineSize)
196 {
197 m_lineSize = lineSize;
198 // TODO
199 }
200
201 int wxSlider::GetLineSize() const
202 {
203 // TODO
204 return 0;
205 }
206
207 int wxSlider::GetSelEnd() const
208 {
209 // TODO
210 return 0;
211 }
212
213 int wxSlider::GetSelStart() const
214 {
215 // TODO
216 return 0;
217 }
218
219 void wxSlider::SetSelection(int minPos, int maxPos)
220 {
221 // TODO
222 }
223
224 void wxSlider::SetThumbLength(int len)
225 {
226 // TODO
227 }
228
229 int wxSlider::GetThumbLength() const
230 {
231 // TODO
232 return 0;
233 }
234
235 void wxSlider::SetTick(int tickPos)
236 {
237 // TODO
238 }
239
240 void wxSlider::Command (wxCommandEvent & event)
241 {
242 SetValue (event.GetInt());
243 ProcessCommand (event);
244 }
245
246 void wxSlider::MacHandleControlClick( WXWidget control , wxInt16 controlpart, bool mouseStillDown )
247 {
248 SInt16 value = ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
249
250 SetValue( value ) ;
251
252 wxEventType scrollEvent = wxEVT_NULL ;
253
254 if ( mouseStillDown )
255 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
256 else
257 scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
258
259 wxScrollEvent event(scrollEvent, m_windowId);
260 event.SetPosition(value);
261 event.SetEventObject( this );
262 GetEventHandler()->ProcessEvent(event);
263
264 wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, m_windowId );
265 cevent.SetInt( value );
266 cevent.SetEventObject( this );
267
268 GetEventHandler()->ProcessEvent( cevent );
269 }
270
271 /* This is overloaded in wxSlider so that the proper width/height will always be used
272 * for the slider different values would cause redrawing and mouse detection problems */
273 void wxSlider::DoSetSizeHints( int minW, int minH,
274 int maxW , int maxH ,
275 int incW , int incH )
276 {
277 wxSize size = GetBestSize();
278
279 if(GetWindowStyle() & wxSL_VERTICAL) {
280 wxWindow::DoSetSizeHints(size.x, minH, size.x, maxH, incW, incH);
281 }
282 else {
283 wxWindow::DoSetSizeHints(minW, size.y, maxW, size.y, incW, incH);
284 }
285 }
286
287 wxSize wxSlider::DoGetBestSize() const
288 {
289 wxSize size;
290 int textwidth, textheight;
291
292 if(GetWindowStyle() & wxSL_LABELS)
293 {
294 wxString text;
295 int ht, wd;
296
297 // Get maximum text label width and height
298 text.Printf(wxT("%d"), m_rangeMin);
299 GetTextExtent(text, &textwidth, &textheight);
300 text.Printf(wxT("%d"), m_rangeMax);
301 GetTextExtent(text, &wd, &ht);
302 if(ht > textheight) {
303 textheight = ht;
304 }
305 if (wd > textwidth) {
306 textwidth = wd;
307 }
308 }
309
310 if(GetWindowStyle() & wxSL_VERTICAL)
311 {
312 if(GetWindowStyle() & wxSL_AUTOTICKS) {
313 size.x = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
314 }
315 else {
316 size.x = wxSLIDER_DIMENSIONACROSS_ARROW;
317 }
318 if(GetWindowStyle() & wxSL_LABELS) {
319 size.x += textwidth + wxSLIDER_BORDERTEXT;
320 }
321 size.y = 150;
322 }
323 else
324 {
325 if(GetWindowStyle() & wxSL_AUTOTICKS) {
326 size.y = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
327 }
328 else {
329 size.y = wxSLIDER_DIMENSIONACROSS_ARROW;
330 }
331 if(GetWindowStyle() & wxSL_LABELS) {
332 size.y += textheight + wxSLIDER_BORDERTEXT;
333 }
334 size.x = 150;
335 }
336 return size;
337 }
338
339 void wxSlider::DoSetSize(int x, int y, int width, int height, int sizeFlags)
340 {
341 wxControl::DoSetSize( x, y , width , height ,sizeFlags ) ;
342 }
343
344 void wxSlider::MacUpdateDimensions()
345 {
346 // actually in the current systems this should never be possible, but later reparenting
347 // may become a reality
348
349 if ( (ControlHandle) m_macControl == NULL )
350 return ;
351
352 if ( GetParent() == NULL )
353 return ;
354
355 WindowRef rootwindow = (WindowRef) MacGetRootWindow() ;
356 if ( rootwindow == NULL )
357 return ;
358
359 int xborder, yborder;
360 int minValWidth, maxValWidth, textwidth, textheight;
361 int sliderBreadth;
362
363 xborder = yborder = 0;
364
365 if (GetWindowStyle() & wxSL_LABELS)
366 {
367 wxString text;
368 int ht;
369
370 // Get maximum text label width and height
371 text.Printf(wxT("%d"), m_rangeMin);
372 GetTextExtent(text, &minValWidth, &textheight);
373 text.Printf(wxT("%d"), m_rangeMax);
374 GetTextExtent(text, &maxValWidth, &ht);
375 if(ht > textheight) {
376 textheight = ht;
377 }
378 textwidth = (minValWidth > maxValWidth ? minValWidth : maxValWidth);
379
380 xborder = textwidth + wxSLIDER_BORDERTEXT;
381 yborder = textheight + wxSLIDER_BORDERTEXT;
382
383 // Get slider breadth
384 if(GetWindowStyle() & wxSL_AUTOTICKS) {
385 sliderBreadth = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
386 }
387 else {
388 sliderBreadth = wxSLIDER_DIMENSIONACROSS_ARROW;
389 }
390
391 if(GetWindowStyle() & wxSL_VERTICAL)
392 {
393 m_macMinimumStatic->Move(sliderBreadth + wxSLIDER_BORDERTEXT,
394 m_height - yborder - textheight);
395 m_macMaximumStatic->Move(sliderBreadth + wxSLIDER_BORDERTEXT, 0);
396 m_macValueStatic->Move(0, m_height - textheight);
397 }
398 else
399 {
400 m_macMinimumStatic->Move(0, sliderBreadth + wxSLIDER_BORDERTEXT);
401 m_macMaximumStatic->Move(m_width - xborder - maxValWidth / 2,
402 sliderBreadth + wxSLIDER_BORDERTEXT);
403 m_macValueStatic->Move(m_width - textwidth, 0);
404 }
405 }
406
407 Rect oldBounds ;
408 GetControlBounds( (ControlHandle) m_macControl , &oldBounds ) ;
409
410 int new_x = m_x + MacGetLeftBorderSize() + m_macHorizontalBorder ;
411 int new_y = m_y + MacGetTopBorderSize() + m_macVerticalBorder ;
412 int new_width = m_width - MacGetLeftBorderSize() - MacGetRightBorderSize() - 2 * m_macHorizontalBorder - xborder ;
413 int new_height = m_height - MacGetTopBorderSize() - MacGetBottomBorderSize() - 2 * m_macVerticalBorder - yborder ;
414
415 GetParent()->MacWindowToRootWindow( & new_x , & new_y ) ;
416 bool doMove = new_x != oldBounds.left || new_y != oldBounds.top ;
417 bool doResize = ( oldBounds.right - oldBounds.left ) != new_width || (oldBounds.bottom - oldBounds.top ) != new_height ;
418 if ( doMove || doResize )
419 {
420 InvalWindowRect( rootwindow, &oldBounds ) ;
421 if ( doMove )
422 {
423 UMAMoveControl( (ControlHandle) m_macControl , new_x , new_y ) ;
424 }
425 if ( doResize )
426 {
427 UMASizeControl( (ControlHandle) m_macControl , new_width , new_height ) ;
428 }
429 }
430 }
431
432 void wxSlider::DoMoveWindow(int x, int y, int width, int height)
433 {
434 wxControl::DoMoveWindow(x,y,width,height) ;
435 }
436
437 #endif // wxUSE_SLIDER