]> git.saurik.com Git - wxWidgets.git/blame - src/msw/slider95.cpp
DeleteFunction argument should be non-const since it
[wxWidgets.git] / src / msw / slider95.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
7d0d80bd
WS
2// Name: msw/slider.cpp
3// Purpose: wxSlider, using the Win95 (and later) trackbar control
2bda0e17
KB
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6181cef5
VZ
8// Copyright: (c) Julian Smart 1998
9// Vadim Zeitlin 2004
65571936 10// Licence: wxWindows licence
2bda0e17
KB
11/////////////////////////////////////////////////////////////////////////////
12
6181cef5
VZ
13// ============================================================================
14// declarations
15// ============================================================================
16
6181cef5
VZ
17// ----------------------------------------------------------------------------
18// headers
19// ----------------------------------------------------------------------------
20
2bda0e17
KB
21// For compilers that support precompilation, includes "wx.h".
22#include "wx/wxprec.h"
23
24#ifdef __BORLANDC__
6181cef5 25 #pragma hdrstop
2bda0e17
KB
26#endif
27
1e6feb95
VZ
28#if wxUSE_SLIDER
29
2bda0e17 30#ifndef WX_PRECOMP
6181cef5 31 #include "wx/brush.h"
2bda0e17
KB
32#endif
33
6181cef5
VZ
34#include "wx/slider.h"
35#include "wx/msw/subwin.h"
2bda0e17 36
6181cef5 37#if !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
c42404a5 38 #include <commctrl.h>
2bda0e17
KB
39#endif
40
6181cef5
VZ
41// ----------------------------------------------------------------------------
42// constants
43// ----------------------------------------------------------------------------
44
7d0d80bd 45// indices of labels in wxSlider::m_labels
6181cef5
VZ
46enum
47{
48 SliderLabel_Min,
49 SliderLabel_Max,
50 SliderLabel_Value,
51 SliderLabel_Last
52};
53
54// the gap between the slider and the labels, in pixels
55static const int HGAP = 5;
56
57// ----------------------------------------------------------------------------
58// XTI
59// ----------------------------------------------------------------------------
60
f0a126fe 61#if wxUSE_EXTENDED_RTTI
bc9fb572
JS
62WX_DEFINE_FLAGS( wxSliderStyle )
63
3ff066a4 64wxBEGIN_FLAGS( wxSliderStyle )
bc9fb572
JS
65 // new style border flags, we put them first to
66 // use them for streaming out
3ff066a4
SC
67 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
68 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
69 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
70 wxFLAGS_MEMBER(wxBORDER_RAISED)
71 wxFLAGS_MEMBER(wxBORDER_STATIC)
72 wxFLAGS_MEMBER(wxBORDER_NONE)
57f4f925 73
bc9fb572 74 // old style border flags
3ff066a4
SC
75 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
76 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
77 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
78 wxFLAGS_MEMBER(wxRAISED_BORDER)
79 wxFLAGS_MEMBER(wxSTATIC_BORDER)
cb0afb26 80 wxFLAGS_MEMBER(wxBORDER)
bc9fb572
JS
81
82 // standard window styles
3ff066a4
SC
83 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
84 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
85 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
86 wxFLAGS_MEMBER(wxWANTS_CHARS)
cb0afb26 87 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
3ff066a4
SC
88 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
89 wxFLAGS_MEMBER(wxVSCROLL)
90 wxFLAGS_MEMBER(wxHSCROLL)
91
92 wxFLAGS_MEMBER(wxSL_HORIZONTAL)
93 wxFLAGS_MEMBER(wxSL_VERTICAL)
94 wxFLAGS_MEMBER(wxSL_AUTOTICKS)
95 wxFLAGS_MEMBER(wxSL_LABELS)
96 wxFLAGS_MEMBER(wxSL_LEFT)
97 wxFLAGS_MEMBER(wxSL_TOP)
98 wxFLAGS_MEMBER(wxSL_RIGHT)
99 wxFLAGS_MEMBER(wxSL_BOTTOM)
100 wxFLAGS_MEMBER(wxSL_BOTH)
101 wxFLAGS_MEMBER(wxSL_SELRANGE)
6bee5ffb 102 wxFLAGS_MEMBER(wxSL_INVERSE)
3ff066a4
SC
103
104wxEND_FLAGS( wxSliderStyle )
bc9fb572 105
7d0d80bd 106IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/scrolbar.h")
f0a126fe 107
7d0d80bd 108wxBEGIN_PROPERTIES_TABLE(wxSlider)
cbc85508 109 wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_CHANGED , wxScrollEvent )
3ff066a4 110 wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SLIDER_UPDATED , wxCommandEvent )
c5ca409b 111
3ff066a4 112 wxPROPERTY( Value , int , SetValue, GetValue , 0, 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
822e690b
WS
113 wxPROPERTY( Minimum , int , SetMin, GetMin, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
114 wxPROPERTY( Maximum , int , SetMax, GetMax, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
115 wxPROPERTY( PageSize , int , SetPageSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
116 wxPROPERTY( LineSize , int , SetLineSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
117 wxPROPERTY( ThumbLength , int , SetThumbLength, GetThumbLength, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
af498247 118 wxPROPERTY_FLAGS( WindowStyle , wxSliderStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
3ff066a4 119wxEND_PROPERTIES_TABLE()
f0a126fe 120
7d0d80bd 121wxBEGIN_HANDLERS_TABLE(wxSlider)
3ff066a4 122wxEND_HANDLERS_TABLE()
f0a126fe 123
7d0d80bd 124wxCONSTRUCTOR_8( wxSlider , wxWindow* , Parent , wxWindowID , Id , int , Value , int , Minimum , int , Maximum , wxPoint , Position , wxSize , Size , long , WindowStyle )
f0a126fe 125#else
7d0d80bd 126IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
f0a126fe 127#endif
2bda0e17 128
6181cef5 129// ============================================================================
7d0d80bd 130// wxSlider implementation
6181cef5
VZ
131// ============================================================================
132
133// ----------------------------------------------------------------------------
134// construction
135// ----------------------------------------------------------------------------
136
7d0d80bd 137void wxSlider::Init()
2bda0e17 138{
6181cef5
VZ
139 m_labels = NULL;
140
5f605ccf
VZ
141 m_pageSize = 1;
142 m_lineSize = 1;
143 m_rangeMax = 0;
144 m_rangeMin = 0;
145 m_tickFreq = 0;
3c96417a
VZ
146
147 m_isDragging = false;
2bda0e17
KB
148}
149
6181cef5 150bool
7d0d80bd
WS
151wxSlider::Create(wxWindow *parent,
152 wxWindowID id,
153 int value,
154 int minValue,
155 int maxValue,
156 const wxPoint& pos,
157 const wxSize& size,
158 long style,
159 const wxValidator& validator,
160 const wxString& name)
2bda0e17 161{
10f80f9b
VZ
162 // our styles are redundant: wxSL_LEFT/RIGHT imply wxSL_VERTICAL and
163 // wxSL_TOP/BOTTOM imply wxSL_HORIZONTAL, but for backwards compatibility
164 // reasons we can't really change it, instead try to infer the orientation
165 // from the flags given to us here
166 switch ( style & (wxSL_LEFT | wxSL_RIGHT | wxSL_TOP | wxSL_BOTTOM) )
167 {
168 case wxSL_LEFT:
169 case wxSL_RIGHT:
170 style |= wxSL_VERTICAL;
171 break;
172
173 case wxSL_TOP:
174 case wxSL_BOTTOM:
175 style |= wxSL_HORIZONTAL;
176 break;
177
178 case 0:
179 // no specific direction, do we have at least the orientation?
180 if ( !(style & (wxSL_HORIZONTAL | wxSL_VERTICAL)) )
181 {
182 // no, choose default
183 style |= wxSL_BOTTOM | wxSL_HORIZONTAL;
184 }
185 };
186
d1103787 187 wxASSERT_MSG( !(style & wxSL_VERTICAL) || !(style & wxSL_HORIZONTAL),
10f80f9b
VZ
188 _T("incompatible slider direction and orientation") );
189
190
6181cef5
VZ
191 // initialize everything
192 if ( !CreateControl(parent, id, pos, size, style, validator, name) )
822e690b 193 return false;
2bda0e17 194
6181cef5
VZ
195 // ensure that we have correct values for GetLabelsSize()
196 m_rangeMin = minValue;
197 m_rangeMax = maxValue;
5f605ccf 198
6181cef5
VZ
199 // create the labels first, so that our DoGetBestSize() could take them
200 // into account
201 //
202 // note that we could simply create 3 wxStaticTexts here but it could
203 // result in some observable side effects at wx level (e.g. the parent of
204 // wxSlider would have 3 more children than expected) and so we prefer not
205 // to do it like this
5f605ccf
VZ
206 if ( m_windowStyle & wxSL_LABELS )
207 {
6181cef5
VZ
208 m_labels = new wxSubwindows(SliderLabel_Last);
209
210 HWND hwndParent = GetHwndOf(parent);
211 for ( size_t n = 0; n < SliderLabel_Last; n++ )
212 {
213 (*m_labels)[n] = ::CreateWindow
214 (
215 wxT("STATIC"),
216 NULL,
217 WS_CHILD | WS_VISIBLE | SS_CENTER,
218 0, 0, 0, 0,
219 hwndParent,
220 (HMENU)NewControlId(),
221 wxGetInstance(),
222 NULL
223 );
224 }
225
226 m_labels->SetFont(GetFont());
5f605ccf
VZ
227 }
228
6181cef5
VZ
229 // now create the main control too
230 if ( !MSWCreateControl(TRACKBAR_CLASS, wxEmptyString, pos, size) )
231 return false;
5f605ccf 232
6181cef5
VZ
233 // and initialize everything
234 SetRange(minValue, maxValue);
235 SetValue(value);
236 SetPageSize((maxValue - minValue)/10);
822e690b 237
8a8dcc34
VZ
238 // we need to position the labels correctly if we have them and if
239 // SetSize() hadn't been called before (when best size was determined by
240 // MSWCreateControl()) as in this case they haven't been put in place yet
241 if ( m_labels && size.x != wxDefaultCoord && size.y != wxDefaultCoord )
242 {
243 SetSize(size);
244 }
245
6181cef5
VZ
246 return true;
247}
2bda0e17 248
7d0d80bd 249WXDWORD wxSlider::MSWGetStyle(long style, WXDWORD *exstyle) const
6181cef5
VZ
250{
251 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
b0766406 252
10f80f9b 253 // TBS_HORZ, TBS_RIGHT and TBS_BOTTOM are 0 but do include them for clarity
6181cef5
VZ
254 msStyle |= style & wxSL_VERTICAL ? TBS_VERT : TBS_HORZ;
255
10f80f9b 256 if ( style & wxSL_BOTH )
cbc6af74
VZ
257 {
258 // this fully specifies the style combined with TBS_VERT/HORZ above
5f605ccf 259 msStyle |= TBS_BOTH;
cbc6af74
VZ
260 }
261 else // choose one direction
262 {
263 if ( style & wxSL_LEFT )
264 msStyle |= TBS_LEFT;
265 else if ( style & wxSL_RIGHT )
266 msStyle |= TBS_RIGHT;
267 else if ( style & wxSL_TOP )
268 msStyle |= TBS_TOP;
269 else if ( style & wxSL_BOTTOM )
270 msStyle |= TBS_BOTTOM;
271 }
10f80f9b
VZ
272
273 if ( style & wxSL_AUTOTICKS )
274 msStyle |= TBS_AUTOTICKS;
275 else
5f605ccf 276 msStyle |= TBS_NOTICKS;
2bda0e17 277
6181cef5 278 if ( style & wxSL_SELRANGE )
5f605ccf 279 msStyle |= TBS_ENABLESELRANGE;
2bda0e17 280
6181cef5
VZ
281 return msStyle;
282}
7a5a5718 283
7d0d80bd 284wxSlider::~wxSlider()
6181cef5
VZ
285{
286 delete m_labels;
2bda0e17
KB
287}
288
6181cef5
VZ
289// ----------------------------------------------------------------------------
290// event handling
291// ----------------------------------------------------------------------------
292
7d0d80bd
WS
293bool wxSlider::MSWOnScroll(int WXUNUSED(orientation),
294 WXWORD wParam,
295 WXWORD WXUNUSED(pos),
296 WXHWND control)
2bda0e17 297{
1e6feb95 298 wxEventType scrollEvent;
2bda0e17
KB
299 switch ( wParam )
300 {
a23fd0e1 301 case SB_TOP:
a23fd0e1
VZ
302 scrollEvent = wxEVT_SCROLL_TOP;
303 break;
304
305 case SB_BOTTOM:
a23fd0e1
VZ
306 scrollEvent = wxEVT_SCROLL_BOTTOM;
307 break;
308
309 case SB_LINEUP:
a23fd0e1
VZ
310 scrollEvent = wxEVT_SCROLL_LINEUP;
311 break;
312
313 case SB_LINEDOWN:
a23fd0e1
VZ
314 scrollEvent = wxEVT_SCROLL_LINEDOWN;
315 break;
316
317 case SB_PAGEUP:
a23fd0e1
VZ
318 scrollEvent = wxEVT_SCROLL_PAGEUP;
319 break;
320
321 case SB_PAGEDOWN:
a23fd0e1
VZ
322 scrollEvent = wxEVT_SCROLL_PAGEDOWN;
323 break;
324
325 case SB_THUMBTRACK:
a23fd0e1 326 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
3c96417a 327 m_isDragging = true;
a23fd0e1
VZ
328 break;
329
e8b669d3 330 case SB_THUMBPOSITION:
3c96417a
VZ
331 if ( m_isDragging )
332 {
333 scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
334 m_isDragging = false;
335 }
336 else
337 {
338 // this seems to only happen when the mouse wheel is used: in
339 // this case, as it might be unexpected to get THUMBRELEASE
340 // without preceding THUMBTRACKs, we don't generate it at all
341 // but generate CHANGED event because the control itself does
342 // not send us SB_ENDSCROLL for whatever reason when mouse
343 // wheel is used
344 scrollEvent = wxEVT_SCROLL_CHANGED;
345 }
e8b669d3
VZ
346 break;
347
348 case SB_ENDSCROLL:
cbc85508 349 scrollEvent = wxEVT_SCROLL_CHANGED;
e8b669d3
VZ
350 break;
351
a23fd0e1 352 default:
1e6feb95 353 // unknown scroll event?
822e690b 354 return false;
2bda0e17
KB
355 }
356
01526d4f 357 int newPos = ValueInvertOrNot((int) ::SendMessage((HWND) control, TBM_GETPOS, 0, 0));
a23fd0e1 358 if ( (newPos < GetMin()) || (newPos > GetMax()) )
2bda0e17 359 {
a23fd0e1 360 // out of range - but we did process it
822e690b 361 return true;
a23fd0e1 362 }
2bda0e17 363
a23fd0e1 364 SetValue(newPos);
2bda0e17 365
a23fd0e1
VZ
366 wxScrollEvent event(scrollEvent, m_windowId);
367 event.SetPosition(newPos);
368 event.SetEventObject( this );
369 GetEventHandler()->ProcessEvent(event);
f3a65071 370
a23fd0e1 371 wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, GetId() );
f6bcfd97 372 cevent.SetInt( newPos );
a23fd0e1 373 cevent.SetEventObject( this );
f3a65071 374
a23fd0e1 375 return GetEventHandler()->ProcessEvent( cevent );
2bda0e17
KB
376}
377
7d0d80bd 378void wxSlider::Command (wxCommandEvent & event)
2bda0e17 379{
6181cef5
VZ
380 SetValue (event.GetInt());
381 ProcessCommand (event);
2bda0e17
KB
382}
383
6181cef5
VZ
384// ----------------------------------------------------------------------------
385// geometry stuff
386// ----------------------------------------------------------------------------
2bda0e17 387
7d0d80bd 388wxRect wxSlider::GetBoundingBox() const
2bda0e17 389{
6181cef5
VZ
390 // take care not to call our own functions which would call us recursively
391 int x, y, w, h;
392 wxSliderBase::DoGetPosition(&x, &y);
393 wxSliderBase::DoGetSize(&w, &h);
5f605ccf 394
6181cef5
VZ
395 wxRect rect(x, y, w, h);
396 if ( m_labels )
b5c45059
RD
397 {
398 wxRect lrect = m_labels->GetBoundingBox();
399 GetParent()->ScreenToClient(&lrect.x, &lrect.y);
400 rect.Union(lrect);
401 }
6181cef5
VZ
402
403 return rect;
5f605ccf
VZ
404}
405
7d0d80bd 406void wxSlider::DoGetSize(int *width, int *height) const
2bda0e17 407{
6181cef5 408 wxRect rect = GetBoundingBox();
5f605ccf 409
6819fb9b 410 if ( width )
6181cef5 411 *width = rect.width;
6819fb9b 412 if ( height )
6181cef5 413 *height = rect.height;
2bda0e17
KB
414}
415
7d0d80bd 416void wxSlider::DoGetPosition(int *x, int *y) const
2bda0e17 417{
6181cef5 418 wxRect rect = GetBoundingBox();
5f605ccf 419
6181cef5
VZ
420 if ( x )
421 *x = rect.x;
422 if ( y )
423 *y = rect.y;
424}
5f605ccf 425
7d0d80bd 426int wxSlider::GetLabelsSize(int *width) const
6181cef5
VZ
427{
428 int cy;
5f605ccf 429
6181cef5
VZ
430 if ( width )
431 {
432 // find the max label width
433 int wLabelMin, wLabelMax;
434 GetTextExtent(Format(m_rangeMin), &wLabelMin, &cy);
435 GetTextExtent(Format(m_rangeMax), &wLabelMax, &cy);
5f605ccf 436
6181cef5
VZ
437 *width = wxMax(wLabelMin, wLabelMax);
438 }
439 else
5f605ccf 440 {
6181cef5 441 cy = GetCharHeight();
5f605ccf
VZ
442 }
443
6181cef5 444 return EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2bda0e17
KB
445}
446
7d0d80bd 447void wxSlider::DoMoveWindow(int x, int y, int width, int height)
2bda0e17 448{
6181cef5
VZ
449 // all complications below are because we need to position the labels,
450 // without them everything is easy
451 if ( !m_labels )
452 {
453 wxSliderBase::DoMoveWindow(x, y, width, height);
454 return;
455 }
2bda0e17 456
8a8dcc34
VZ
457 // be careful to position the slider itself after moving the labels as
458 // otherwise our GetBoundingBox(), which is called from WM_SIZE handler,
459 // would return a wrong result and wrong size would be cached internally
6181cef5
VZ
460 if ( HasFlag(wxSL_VERTICAL) )
461 {
462 int wLabel;
463 int hLabel = GetLabelsSize(&wLabel);
81d66cf3 464
6181cef5 465 int xLabel = HasFlag(wxSL_LEFT) ? x + width - wLabel : x;
2bda0e17 466
6181cef5
VZ
467 // position all labels: min at the top, value in the middle and max at
468 // the bottom
7d86a2d4 469 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
8e44f3ca 470 xLabel, y, wLabel, hLabel);
2bda0e17 471
7d86a2d4 472 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
8e44f3ca 473 xLabel, y + (height - hLabel)/2, wLabel, hLabel);
2bda0e17 474
7d86a2d4
VZ
475 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
476 xLabel, y + height - hLabel, wLabel, hLabel);
8a8dcc34
VZ
477
478 // position the slider itself along the left/right edge
7d86a2d4
VZ
479 wxSliderBase::DoMoveWindow(HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP,
480 y + hLabel/2,
481 width - wLabel - HGAP,
482 height - hLabel);
a23fd0e1 483 }
6181cef5 484 else // horizontal
2bda0e17 485 {
6181cef5
VZ
486 int wLabel;
487 int hLabel = GetLabelsSize(&wLabel);
488
489 int yLabel = HasFlag(wxSL_TOP) ? y + height - hLabel : y;
490
6181cef5
VZ
491 // position all labels: min on the left, value in the middle and max to
492 // the right
7d86a2d4
VZ
493 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
494 x, yLabel, wLabel, hLabel);
6181cef5 495
7d86a2d4
VZ
496 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
497 x + (width - wLabel)/2, yLabel, wLabel, hLabel);
6181cef5 498
7d86a2d4
VZ
499 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
500 x + width - wLabel, yLabel, wLabel, hLabel);
8a8dcc34
VZ
501
502 // position the slider itself along the top/bottom edge
7d86a2d4
VZ
503 wxSliderBase::DoMoveWindow(x,
504 HasFlag(wxSL_TOP) ? y : y + hLabel,
505 width,
506 height - hLabel);
8e44f3ca 507 }
2bda0e17
KB
508}
509
7d0d80bd 510wxSize wxSlider::DoGetBestSize() const
7bdfb981 511{
6181cef5
VZ
512 // these values are arbitrary
513 static const int length = 100;
cbc6af74
VZ
514 static const int thumb = 24;
515 static const int ticks = 8;
57f4f925 516
cbc6af74 517 int *width;
6181cef5
VZ
518 wxSize size;
519 if ( HasFlag(wxSL_VERTICAL) )
7bdfb981 520 {
cbc6af74 521 size.x = thumb;
6181cef5 522 size.y = length;
cbc6af74 523 width = &size.x;
57f4f925 524
6181cef5 525 if ( m_labels )
7bdfb981 526 {
6181cef5
VZ
527 int wLabel;
528 int hLabel = GetLabelsSize(&wLabel);
7bdfb981 529
6181cef5
VZ
530 // account for the labels
531 size.x += HGAP + wLabel;
532
533 // labels are indented relative to the slider itself
534 size.y += hLabel;
7bdfb981
RD
535 }
536 }
6181cef5 537 else // horizontal
7bdfb981 538 {
6181cef5 539 size.x = length;
cbc6af74
VZ
540 size.y = thumb;
541 width = &size.y;
7bdfb981 542
6181cef5 543 if ( m_labels )
7bdfb981 544 {
6181cef5
VZ
545 // labels add extra height
546 size.y += GetLabelsSize();
7bdfb981
RD
547 }
548 }
6181cef5 549
cbc6af74
VZ
550 // need extra space to show ticks
551 if ( HasFlag(wxSL_TICKS) )
552 {
553 *width += ticks;
554
555 // and maybe twice as much if we show them on both sides
556 if ( HasFlag(wxSL_BOTH) )
557 *width += ticks;
558 }
559
6181cef5 560 return size;
7bdfb981
RD
561}
562
6181cef5
VZ
563// ----------------------------------------------------------------------------
564// slider-specific methods
565// ----------------------------------------------------------------------------
566
7d0d80bd 567int wxSlider::GetValue() const
6181cef5 568{
01526d4f 569 return ValueInvertOrNot(::SendMessage(GetHwnd(), TBM_GETPOS, 0, 0));
6181cef5
VZ
570}
571
7d0d80bd 572void wxSlider::SetValue(int value)
6181cef5 573{
01526d4f 574 ::SendMessage(GetHwnd(), TBM_SETPOS, (WPARAM)TRUE, (LPARAM)ValueInvertOrNot(value));
6181cef5
VZ
575
576 if ( m_labels )
577 {
578 ::SetWindowText((*m_labels)[SliderLabel_Value], Format(value));
579 }
580}
7bdfb981 581
7d0d80bd 582void wxSlider::SetRange(int minValue, int maxValue)
2bda0e17 583{
5f605ccf
VZ
584 m_rangeMin = minValue;
585 m_rangeMax = maxValue;
586
b552060a
WS
587 ::SendMessage(GetHwnd(), TBM_SETRANGEMIN, TRUE, m_rangeMin);
588 ::SendMessage(GetHwnd(), TBM_SETRANGEMAX, TRUE, m_rangeMax);
5f605ccf 589
6181cef5 590 if ( m_labels )
5f605ccf 591 {
01526d4f
WS
592 ::SetWindowText((*m_labels)[SliderLabel_Min], Format(ValueInvertOrNot(m_rangeMin)));
593 ::SetWindowText((*m_labels)[SliderLabel_Max], Format(ValueInvertOrNot(m_rangeMax)));
5f605ccf 594 }
2bda0e17
KB
595}
596
7d0d80bd 597void wxSlider::SetTickFreq(int n, int pos)
2bda0e17 598{
6181cef5
VZ
599 m_tickFreq = n;
600 ::SendMessage( GetHwnd(), TBM_SETTICFREQ, (WPARAM) n, (LPARAM) pos );
2bda0e17
KB
601}
602
7d0d80bd 603void wxSlider::SetPageSize(int pageSize)
2bda0e17 604{
6181cef5
VZ
605 ::SendMessage( GetHwnd(), TBM_SETPAGESIZE, (WPARAM) 0, (LPARAM) pageSize );
606 m_pageSize = pageSize;
2bda0e17
KB
607}
608
7d0d80bd 609int wxSlider::GetPageSize() const
2bda0e17 610{
6181cef5 611 return m_pageSize;
2bda0e17
KB
612}
613
7d0d80bd 614void wxSlider::ClearSel()
2bda0e17 615{
6181cef5 616 ::SendMessage(GetHwnd(), TBM_CLEARSEL, (WPARAM) TRUE, (LPARAM) 0);
2bda0e17
KB
617}
618
7d0d80bd 619void wxSlider::ClearTicks()
2bda0e17 620{
6181cef5 621 ::SendMessage(GetHwnd(), TBM_CLEARTICS, (WPARAM) TRUE, (LPARAM) 0);
2bda0e17
KB
622}
623
7d0d80bd 624void wxSlider::SetLineSize(int lineSize)
2bda0e17 625{
5f605ccf 626 m_lineSize = lineSize;
6181cef5 627 ::SendMessage(GetHwnd(), TBM_SETLINESIZE, (WPARAM) 0, (LPARAM) lineSize);
2bda0e17
KB
628}
629
7d0d80bd 630int wxSlider::GetLineSize() const
2bda0e17 631{
6181cef5 632 return (int)::SendMessage(GetHwnd(), TBM_GETLINESIZE, 0, 0);
2bda0e17
KB
633}
634
7d0d80bd 635int wxSlider::GetSelEnd() const
2bda0e17 636{
0a936028 637 return (int)::SendMessage(GetHwnd(), TBM_GETSELEND, 0, 0);
2bda0e17
KB
638}
639
7d0d80bd 640int wxSlider::GetSelStart() const
2bda0e17 641{
6181cef5 642 return (int)::SendMessage(GetHwnd(), TBM_GETSELSTART, 0, 0);
2bda0e17
KB
643}
644
7d0d80bd 645void wxSlider::SetSelection(int minPos, int maxPos)
2bda0e17 646{
5f605ccf 647 ::SendMessage(GetHwnd(), TBM_SETSEL,
6181cef5
VZ
648 (WPARAM) TRUE /* redraw */,
649 (LPARAM) MAKELONG( minPos, maxPos) );
2bda0e17
KB
650}
651
7d0d80bd 652void wxSlider::SetThumbLength(int len)
2bda0e17 653{
6181cef5 654 ::SendMessage(GetHwnd(), TBM_SETTHUMBLENGTH, (WPARAM) len, (LPARAM) 0);
2bda0e17
KB
655}
656
7d0d80bd 657int wxSlider::GetThumbLength() const
2bda0e17 658{
6bee5ffb 659 return (int)::SendMessage( GetHwnd(), TBM_GETTHUMBLENGTH, 0, 0);
2bda0e17
KB
660}
661
7d0d80bd 662void wxSlider::SetTick(int tickPos)
2bda0e17 663{
6bee5ffb 664 ::SendMessage( GetHwnd(), TBM_SETTIC, (WPARAM) 0, (LPARAM) tickPos );
2bda0e17
KB
665}
666
6181cef5
VZ
667// ----------------------------------------------------------------------------
668// composite control methods
669// ----------------------------------------------------------------------------
670
7d0d80bd 671WXHWND wxSlider::GetStaticMin() const
2bda0e17 672{
6181cef5 673 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Min] : NULL;
2bda0e17
KB
674}
675
7d0d80bd 676WXHWND wxSlider::GetStaticMax() const
2bda0e17 677{
6181cef5 678 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Max] : NULL;
2bda0e17
KB
679}
680
7d0d80bd 681WXHWND wxSlider::GetEditValue() const
2bda0e17 682{
6181cef5
VZ
683 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Value] : NULL;
684}
2bda0e17 685
7d0d80bd 686WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(wxSlider, wxSliderBase, m_labels)
8a8dcc34 687
1e6feb95 688#endif // wxUSE_SLIDER