1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:           wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "slider.h" 
  14 #include "wx/slider.h" 
  25 //----------------------------------------------------------------------------- 
  27 //----------------------------------------------------------------------------- 
  29 extern void wxapp_install_idle_handler(); 
  32 //----------------------------------------------------------------------------- 
  34 //----------------------------------------------------------------------------- 
  36 extern bool   g_blockEventsOnDrag
; 
  38 static const float sensitivity 
= 0.02; 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  44 static void gtk_slider_callback( GtkAdjustment 
*adjust
, wxSlider 
*win 
) 
  46     if (g_isIdle
) wxapp_install_idle_handler(); 
  48     if (!win
->m_hasVMT
) return; 
  49     if (g_blockEventsOnDrag
) return; 
  51     float diff 
= adjust
->value 
- win
->m_oldPos
; 
  52     if (fabs(diff
) < sensitivity
) return; 
  54     win
->m_oldPos 
= adjust
->value
; 
  56     GtkRange 
*range 
= GTK_RANGE( win
->m_widget 
); 
  58     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
  59     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLL_LINEUP
; 
  60     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLL_LINEDOWN
; 
  61     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLL_PAGEUP
; 
  62     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLL_PAGEDOWN
; 
  64     double dvalue 
= adjust
->value
; 
  65     int value 
= (int)(dvalue 
>= 0 ? dvalue 
- 0.5 : dvalue 
+ 0.5); 
  67     int orient 
= wxHORIZONTAL
; 
  68     if ( (win
->GetWindowStyleFlag() & wxSB_VERTICAL
) == wxSB_VERTICAL
) 
  71     wxScrollEvent 
event( command
, win
->GetId(), value
, orient 
); 
  72     event
.SetEventObject( win 
); 
  73     win
->GetEventHandler()->ProcessEvent( event 
); 
  75     wxCommandEvent 
cevent( wxEVT_COMMAND_SLIDER_UPDATED
, win
->GetId() ); 
  76     cevent
.SetEventObject( win 
); 
  77     cevent
.SetInt( value 
); 
  78     win
->GetEventHandler()->ProcessEvent( cevent 
); 
  81 //----------------------------------------------------------------------------- 
  83 //----------------------------------------------------------------------------- 
  85 IMPLEMENT_DYNAMIC_CLASS(wxSlider
,wxControl
) 
  87 bool wxSlider::Create(wxWindow 
*parent
, wxWindowID id
, 
  88         int value
, int minValue
, int maxValue
, 
  89         const wxPoint
& pos
, const wxSize
& size
, 
  90         long style
, const wxValidator
& validator
, const wxString
& name 
) 
  92     m_acceptsFocus 
= TRUE
; 
  95     if (!PreCreation( parent
, pos
, size 
) || 
  96         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
  98         wxFAIL_MSG( wxT("wxSlider creation failed") ); 
 104     if (style 
& wxSL_VERTICAL
) 
 105         m_widget 
= gtk_vscale_new( (GtkAdjustment 
*) NULL 
); 
 107         m_widget 
= gtk_hscale_new( (GtkAdjustment 
*) NULL 
); 
 109     if (style 
& wxSL_LABELS
) 
 111         gtk_scale_set_draw_value( GTK_SCALE( m_widget 
), TRUE 
); 
 112         gtk_scale_set_digits( GTK_SCALE( m_widget 
), 0 ); 
 114         /* labels need more space and too small window will 
 115            cause junk to appear on the dialog */ 
 116         if (style 
& wxSL_VERTICAL
) 
 136         gtk_scale_set_draw_value( GTK_SCALE( m_widget 
), FALSE 
); 
 138     m_adjust 
= gtk_range_get_adjustment( GTK_RANGE(m_widget
) ); 
 140     gtk_signal_connect( GTK_OBJECT(m_adjust
), 
 142                         (GtkSignalFunc
) gtk_slider_callback
, 
 145     SetRange( minValue
, maxValue 
); 
 148     m_parent
->DoAddChild( this ); 
 152     SetBackgroundColour( parent
->GetBackgroundColour() ); 
 159 int wxSlider::GetValue() const 
 161     // we want to round to the nearest integer, i.e. 0.9 is rounded to 1 and 
 162     // -0.9 is rounded to -1 
 163     double val 
= m_adjust
->value
; 
 164     return (int)(val 
>= 0 ? val 
- 0.5 : val 
+ 0.5); 
 167 void wxSlider::SetValue( int value 
) 
 169     float fpos 
= (float)value
; 
 171     if (fabs(fpos
-m_adjust
->value
) < 0.2) return; 
 173     m_adjust
->value 
= fpos
; 
 175     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "value_changed" ); 
 178 void wxSlider::SetRange( int minValue
, int maxValue 
) 
 180     float fmin 
= (float)minValue
; 
 181     float fmax 
= (float)maxValue
; 
 183     if ((fabs(fmin
-m_adjust
->lower
) < 0.2) && 
 184         (fabs(fmax
-m_adjust
->upper
) < 0.2)) 
 189     m_adjust
->lower 
= fmin
; 
 190     m_adjust
->upper 
= fmax
; 
 191     m_adjust
->step_increment 
= 1.0; 
 192     m_adjust
->page_increment 
= ceil((fmax
-fmin
) / 10.0); 
 194     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "changed" ); 
 197 int wxSlider::GetMin() const 
 199     return (int)ceil(m_adjust
->lower
); 
 202 int wxSlider::GetMax() const 
 204     return (int)ceil(m_adjust
->upper
); 
 207 void wxSlider::SetPageSize( int pageSize 
) 
 209     float fpage 
= (float)pageSize
; 
 211     if (fabs(fpage
-m_adjust
->page_increment
) < 0.2) return; 
 213     m_adjust
->page_increment 
= fpage
; 
 215     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "changed" ); 
 218 int wxSlider::GetPageSize() const 
 220     return (int)ceil(m_adjust
->page_increment
); 
 223 void wxSlider::SetThumbLength( int len 
) 
 225     float flen 
= (float)len
; 
 227     if (fabs(flen
-m_adjust
->page_size
) < 0.2) return; 
 229     m_adjust
->page_size 
= flen
; 
 231     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "changed" ); 
 234 int wxSlider::GetThumbLength() const 
 236     return (int)ceil(m_adjust
->page_size
); 
 239 void wxSlider::SetLineSize( int WXUNUSED(lineSize
) ) 
 243 int wxSlider::GetLineSize() const 
 248 void wxSlider::SetTick( int WXUNUSED(tickPos
) ) 
 252 void wxSlider::SetTickFreq( int WXUNUSED(n
), int WXUNUSED(pos
) ) 
 256 int wxSlider::GetTickFreq() const 
 261 void wxSlider::ClearTicks() 
 265 void wxSlider::SetSelection( int WXUNUSED(minPos
), int WXUNUSED(maxPos
) ) 
 269 int wxSlider::GetSelEnd() const 
 274 int wxSlider::GetSelStart() const 
 279 void wxSlider::ClearSel() 
 283 bool wxSlider::IsOwnGtkWindow( GdkWindow 
*window 
) 
 285     GtkRange 
*range 
= GTK_RANGE(m_widget
); 
 286     return ( (window 
== GTK_WIDGET(range
)->window
) || 
 287              (window 
== range
->trough
) || 
 288              (window 
== range
->slider
) || 
 289              (window 
== range
->step_forw
) || 
 290              (window 
== range
->step_back
) ); 
 293 void wxSlider::ApplyWidgetStyle() 
 296     gtk_widget_set_style( m_widget
, m_widgetStyle 
);