1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "slider.h" 
  20 #include "wx/slider.h" 
  21 #include "wx/mac/uma.h" 
  23 #if !USE_SHARED_LIBRARY 
  24 IMPLEMENT_DYNAMIC_CLASS(wxSlider
, wxControl
) 
  26 BEGIN_EVENT_TABLE(wxSlider
, wxControl
) 
  30  // The dimensions of the different styles of sliders (From Aqua document) 
  31 #define wxSLIDER_DIMENSIONACROSS 15 
  32 #define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 24 
  33 #define wxSLIDER_DIMENSIONACROSS_ARROW 18 
  35 // Distance between slider and text 
  36 #define wxSLIDER_BORDERTEXT 5 
  38 /* NB!  The default orientation for a slider is horizontal however if the user specifies 
  39  * some slider styles but dosen't specify the orientation we have to assume he wants a 
  40  * horizontal one.  Therefore in this file when testing for the sliders orientation 
  41  * vertical is tested for if this is not set then we use the horizontal one 
  42  * eg.  if(GetWindowStyle() & wxSL_VERTICAL) {}  else { horizontal case }> 
  55 extern ControlActionUPP wxMacLiveScrollbarActionUPP 
; 
  57 bool wxSlider::Create(wxWindow 
*parent
, wxWindowID id
, 
  58                       int value
, int minValue
, int maxValue
, 
  60                       const wxSize
& size
, long style
, 
  61                       const wxValidator
& validator
, 
  64     m_macIsUserPane 
= false ; 
  66     if ( !wxControl::Create(parent
, id
, pos
, size
, style
, validator
, name
) ) 
  69     m_macMinimumStatic 
= NULL 
; 
  70     m_macMaximumStatic 
= NULL 
; 
  71     m_macValueStatic 
= NULL 
; 
  77     m_rangeMax 
= maxValue
; 
  78     m_rangeMin 
= minValue
; 
  80     m_pageSize 
= (int)((maxValue
-minValue
)/10); 
  82     Rect bounds 
= wxMacGetBoundsForControl( this , pos 
, size 
) ; 
  85     // NB: (RN) Ticks here are sometimes off in the GUI if there 
  86     // is not as many ticks as there are values 
  88     UInt16 tickMarks 
= 0 ; 
  89     if ( style 
& wxSL_AUTOTICKS 
) 
  90         tickMarks 
= (maxValue 
- minValue
) + 1; //+1 for the 0 value 
  92     while (tickMarks 
> 20) 
  93             tickMarks 
/= 5; //keep the number of tickmarks from becoming unwieldly 
  95     m_peer 
= new wxMacControl() ; 
  96     verify_noerr ( CreateSliderControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()) , &bounds 
, 
  97     value 
, minValue 
, maxValue 
, kControlSliderPointsDownOrRight 
, tickMarks 
, true /* liveTracking */ , 
  98         wxMacLiveScrollbarActionUPP 
, m_peer
->GetControlRefAddr() ) ); 
 101     if(style 
& wxSL_VERTICAL
) { 
 102         SetSizeHints(10, -1, 10, -1);  // Forces SetSize to use the proper width 
 105         SetSizeHints(-1, 10, -1, 10);  // Forces SetSize to use the proper height 
 107     // NB!  SetSizeHints is overloaded by wxSlider and will substitute 10 with the 
 108     // proper dimensions, it also means other people cannot bugger the slider with 
 111     if(style 
& wxSL_LABELS
) 
 113         m_macMinimumStatic 
= new wxStaticText( parent
, wxID_ANY
, wxEmptyString 
); 
 114         m_macMaximumStatic 
= new wxStaticText( parent
, wxID_ANY
, wxEmptyString 
); 
 115         m_macValueStatic 
= new wxStaticText( parent
, wxID_ANY
, wxEmptyString 
); 
 116         SetRange(minValue
, maxValue
); 
 120     MacPostControlCreate(pos
,size
) ; 
 125 wxSlider::~wxSlider() 
 127     delete m_macMinimumStatic 
; 
 128     delete m_macMaximumStatic 
; 
 129     delete m_macValueStatic 
; 
 132 int wxSlider::GetValue() const 
 134     return m_peer
->GetValue() ; 
 137 void wxSlider::SetValue(int value
) 
 139     wxString valuestring 
; 
 140     valuestring
.Printf( wxT("%d") , value 
) ; 
 141     if ( m_macValueStatic 
) 
 142         m_macValueStatic
->SetLabel( valuestring 
) ; 
 143     m_peer
->SetValue( value 
) ; 
 146 void wxSlider::SetRange(int minValue
, int maxValue
) 
 150     m_rangeMin 
= minValue
; 
 151     m_rangeMax 
= maxValue
; 
 153     m_peer
->SetMinimum( m_rangeMin
); 
 154     m_peer
->SetMaximum( m_rangeMax
); 
 156     if(m_macMinimumStatic
) { 
 157         value
.Printf(wxT("%d"), m_rangeMin
); 
 158         m_macMinimumStatic
->SetLabel(value
); 
 160     if(m_macMaximumStatic
) { 
 161         value
.Printf(wxT("%d"), m_rangeMax
); 
 162         m_macMaximumStatic
->SetLabel(value
); 
 164     SetValue(m_rangeMin
); 
 167 // For trackbars only 
 168 void wxSlider::SetTickFreq(int n
, int pos
) 
 174 void wxSlider::SetPageSize(int pageSize
) 
 177     m_pageSize 
= pageSize
; 
 180 int wxSlider::GetPageSize() const 
 185 void wxSlider::ClearSel() 
 190 void wxSlider::ClearTicks() 
 195 void wxSlider::SetLineSize(int lineSize
) 
 197     m_lineSize 
= lineSize
; 
 201 int wxSlider::GetLineSize() const 
 207 int wxSlider::GetSelEnd() const 
 213 int wxSlider::GetSelStart() const 
 219 void wxSlider::SetSelection(int minPos
, int maxPos
) 
 224 void wxSlider::SetThumbLength(int len
) 
 229 int wxSlider::GetThumbLength() const 
 235 void wxSlider::SetTick(int tickPos
) 
 240 void wxSlider::Command (wxCommandEvent 
& event
) 
 242     SetValue (event
.GetInt()); 
 243     ProcessCommand (event
); 
 246 void wxSlider::MacHandleControlClick( WXWidget control 
, wxInt16 controlpart
, bool mouseStillDown 
) 
 248     SInt16 value 
= m_peer
->GetValue() ; 
 252     wxEventType scrollEvent 
= wxEVT_NULL 
; 
 254     scrollEvent 
= wxEVT_SCROLL_THUMBTRACK
; 
 256     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 257     event
.SetPosition(value
); 
 258     event
.SetEventObject( this ); 
 259     GetEventHandler()->ProcessEvent(event
); 
 261     wxCommandEvent 
cevent( wxEVT_COMMAND_SLIDER_UPDATED
, m_windowId 
); 
 262     cevent
.SetInt( value 
); 
 263     cevent
.SetEventObject( this ); 
 265     GetEventHandler()->ProcessEvent( cevent 
); 
 268 wxInt32 
wxSlider::MacControlHit( WXEVENTHANDLERREF handler 
, WXEVENTREF mevent 
) 
 270     SInt16 value 
= m_peer
->GetValue() ; 
 274     wxEventType scrollEvent 
= wxEVT_NULL 
; 
 276     scrollEvent 
= wxEVT_SCROLL_THUMBRELEASE
; 
 278     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 279     event
.SetPosition(value
); 
 280     event
.SetEventObject( this ); 
 281     GetEventHandler()->ProcessEvent(event
); 
 283     wxCommandEvent 
cevent( wxEVT_COMMAND_SLIDER_UPDATED
, m_windowId 
); 
 284     cevent
.SetInt( value 
); 
 285     cevent
.SetEventObject( this ); 
 287     GetEventHandler()->ProcessEvent( cevent 
); 
 292 /* This is overloaded in wxSlider so that the proper width/height will always be used 
 293 * for the slider different values would cause redrawing and mouse detection problems */ 
 294 void wxSlider::SetSizeHints( int minW
, int minH
, 
 295                             int maxW 
, int maxH 
, 
 296                             int incW 
, int incH 
) 
 298     wxSize size 
= GetBestSize(); 
 300     if(GetWindowStyle() & wxSL_VERTICAL
) { 
 301         wxWindow::SetSizeHints(size
.x
, minH
, size
.x
, maxH
, incW
, incH
); 
 304         wxWindow::SetSizeHints(minW
, size
.y
, maxW
, size
.y
, incW
, incH
); 
 308 wxSize 
wxSlider::DoGetBestSize() const 
 311     int textwidth
, textheight
; 
 313     if(GetWindowStyle() & wxSL_LABELS
) 
 318         // Get maximum text label width and height 
 319         text
.Printf(wxT("%d"), m_rangeMin
); 
 320         GetTextExtent(text
, &textwidth
, &textheight
); 
 321         text
.Printf(wxT("%d"), m_rangeMax
); 
 322         GetTextExtent(text
, &wd
, &ht
); 
 323         if(ht 
> textheight
) { 
 326         if (wd 
> textwidth
) { 
 331     if(GetWindowStyle() & wxSL_VERTICAL
) 
 333         if(GetWindowStyle() & wxSL_AUTOTICKS
) { 
 334             size
.x 
= wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS
; 
 337             size
.x 
= wxSLIDER_DIMENSIONACROSS_ARROW
; 
 339         if(GetWindowStyle() & wxSL_LABELS
) { 
 340             size
.x 
+= textwidth 
+ wxSLIDER_BORDERTEXT
; 
 346         if(GetWindowStyle() & wxSL_AUTOTICKS
) { 
 347             size
.y 
= wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS
; 
 350             size
.y 
= wxSLIDER_DIMENSIONACROSS_ARROW
; 
 352         if(GetWindowStyle() & wxSL_LABELS
) { 
 353             size
.y 
+= textheight 
+ wxSLIDER_BORDERTEXT
; 
 360 void wxSlider::DoSetSize(int x
, int y
, int w
, int h
, int sizeFlags
) 
 362     int  xborder
, yborder
; 
 363     int  minValWidth
, maxValWidth
, textwidth
, textheight
; 
 366     xborder 
= yborder 
= 0; 
 368     if (GetWindowStyle() & wxSL_LABELS
) 
 370         //Labels have this control's parent as their parent 
 371         //so if this control is not at 0,0 relative to the parent 
 372         //the labels need to know the position of this control 
 373         //relative to its parent in order to size properly, so 
 374         //move the control first so we can use GetPosition() 
 375         wxControl::DoSetSize( x
, y 
, w 
, h 
,sizeFlags 
) ; 
 380         // Get maximum text label width and height 
 381         text
.Printf(wxT("%d"), m_rangeMin
); 
 382         GetTextExtent(text
, &minValWidth
, &textheight
); 
 383         text
.Printf(wxT("%d"), m_rangeMax
); 
 384         GetTextExtent(text
, &maxValWidth
, &ht
); 
 385         if(ht 
> textheight
) { 
 388         textwidth 
= (minValWidth 
> maxValWidth 
? minValWidth 
: maxValWidth
); 
 390         xborder 
= textwidth 
+ wxSLIDER_BORDERTEXT
; 
 391         yborder 
= textheight 
+ wxSLIDER_BORDERTEXT
; 
 393         // Get slider breadth 
 394         if(GetWindowStyle() & wxSL_AUTOTICKS
) { 
 395             sliderBreadth 
= wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS
; 
 398             sliderBreadth 
= wxSLIDER_DIMENSIONACROSS_ARROW
; 
 401         if(GetWindowStyle() & wxSL_VERTICAL
) 
 405             if ( m_macMinimumStatic 
) 
 406                 m_macMinimumStatic
->Move(GetPosition().x 
+ sliderBreadth 
+ wxSLIDER_BORDERTEXT
, 
 407                 GetPosition().y 
+ h 
- yborder
); 
 408             if ( m_macMaximumStatic 
) 
 409                 m_macMaximumStatic
->Move(GetPosition().x 
+ sliderBreadth 
+ wxSLIDER_BORDERTEXT
, GetPosition().y 
+ 0); 
 410             if ( m_macValueStatic 
) 
 411                 m_macValueStatic
->Move(GetPosition().x
, GetPosition().y 
+ h 
); 
 416             if ( m_macMinimumStatic 
) 
 417                 m_macMinimumStatic
->Move(GetPosition().x 
+ 0, GetPosition().y 
+ sliderBreadth 
+ wxSLIDER_BORDERTEXT
); 
 418             if ( m_macMaximumStatic 
) 
 419                 m_macMaximumStatic
->Move(GetPosition().x 
+ w 
- (maxValWidth
/2), 
 420                 GetPosition().y 
+ sliderBreadth 
+ wxSLIDER_BORDERTEXT
); 
 421             if ( m_macValueStatic 
) 
 422                 m_macValueStatic
->Move(GetPosition().x 
+ w
, GetPosition().y 
+ 0); 
 425     //If the control has labels, we still need to call this again because 
 426     //the labels alter the control's w and h values. 
 427     wxControl::DoSetSize( x
, y 
, w 
, h 
,sizeFlags 
) ; 
 431 void wxSlider::DoMoveWindow(int x
, int y
, int width
, int height
) 
 433     wxControl::DoMoveWindow(x
,y
,width
,height
) ; 
 436 #endif // wxUSE_SLIDER